@skrr-ai/cli 0.1.109 → 0.1.111
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/bin/run.js +15 -1
- package/dist/base-command.d.ts +44 -1
- package/dist/base-command.js +194 -33
- package/dist/commands/actions/list.js +2 -1
- package/dist/commands/agenda/trigger/create.js +1 -1
- package/dist/commands/agenda/trigger/list.js +2 -1
- package/dist/commands/agent-groups/list.js +2 -1
- package/dist/commands/agents/actions/list.js +2 -1
- package/dist/commands/agents/always-on/status.js +5 -0
- package/dist/commands/agents/chat.js +4 -1
- package/dist/commands/agents/duplicate.js +4 -0
- package/dist/commands/agents/eval/list.js +2 -1
- package/dist/commands/agents/files/list.js +2 -1
- package/dist/commands/agents/folders/list.js +2 -1
- package/dist/commands/agents/goals/list.js +2 -1
- package/dist/commands/agents/intuitions/list.js +8 -5
- package/dist/commands/agents/list.d.ts +12 -0
- package/dist/commands/agents/list.js +45 -8
- package/dist/commands/agents/releases/known-issues/list.js +2 -1
- package/dist/commands/agents/releases/list.js +5 -1
- package/dist/commands/agents/releases/trusted-publishers/list.js +2 -1
- package/dist/commands/agents/roles/list.js +2 -1
- package/dist/commands/agents/skills/list.js +2 -1
- package/dist/commands/agents/todos/list.js +2 -1
- package/dist/commands/agents/triggers/create.js +1 -1
- package/dist/commands/agents/triggers/list.js +2 -1
- package/dist/commands/agents/triggers/update.js +1 -1
- package/dist/commands/agents/update.d.ts +11 -0
- package/dist/commands/agents/update.js +58 -2
- package/dist/commands/api-keys/list.js +2 -1
- package/dist/commands/apps/channel.d.ts +20 -0
- package/dist/commands/apps/channel.js +64 -0
- package/dist/commands/apps/check-draft.d.ts +12 -0
- package/dist/commands/apps/check-draft.js +41 -0
- package/dist/commands/apps/check.d.ts +42 -0
- package/dist/commands/apps/check.js +91 -0
- package/dist/commands/apps/create.d.ts +15 -0
- package/dist/commands/apps/create.js +59 -0
- package/dist/commands/apps/data/put.d.ts +18 -0
- package/dist/commands/apps/data/put.js +72 -0
- package/dist/commands/apps/data/query.d.ts +20 -0
- package/dist/commands/apps/data/query.js +88 -0
- package/dist/commands/apps/disclosure.d.ts +16 -0
- package/dist/commands/apps/disclosure.js +71 -0
- package/dist/commands/apps/file/cat.d.ts +15 -0
- package/dist/commands/apps/file/cat.js +50 -0
- package/dist/commands/apps/file/ls.d.ts +13 -0
- package/dist/commands/apps/file/ls.js +47 -0
- package/dist/commands/apps/file/mv.d.ts +15 -0
- package/dist/commands/apps/file/mv.js +49 -0
- package/dist/commands/apps/file/rm.d.ts +15 -0
- package/dist/commands/apps/file/rm.js +53 -0
- package/dist/commands/apps/file/write.d.ts +17 -0
- package/dist/commands/apps/file/write.js +81 -0
- package/dist/commands/apps/install.d.ts +19 -0
- package/dist/commands/apps/install.js +136 -0
- package/dist/commands/apps/installations/list.d.ts +11 -0
- package/dist/commands/apps/installations/list.js +49 -0
- package/dist/commands/apps/installations/show.d.ts +12 -0
- package/dist/commands/apps/installations/show.js +61 -0
- package/dist/commands/apps/layout/set.d.ts +11 -0
- package/dist/commands/apps/layout/set.js +125 -0
- package/dist/commands/apps/layout/show.d.ts +9 -0
- package/dist/commands/apps/layout/show.js +33 -0
- package/dist/commands/apps/list.d.ts +10 -0
- package/dist/commands/apps/list.js +45 -0
- package/dist/commands/apps/logs.d.ts +13 -0
- package/dist/commands/apps/logs.js +55 -0
- package/dist/commands/apps/preview.d.ts +12 -0
- package/dist/commands/apps/preview.js +39 -0
- package/dist/commands/apps/publish/propose.d.ts +14 -0
- package/dist/commands/apps/publish/propose.js +45 -0
- package/dist/commands/apps/pull.d.ts +14 -0
- package/dist/commands/apps/pull.js +56 -0
- package/dist/commands/apps/push.d.ts +15 -0
- package/dist/commands/apps/push.js +75 -0
- package/dist/commands/apps/reconsent.d.ts +13 -0
- package/dist/commands/apps/reconsent.js +67 -0
- package/dist/commands/apps/report.d.ts +20 -0
- package/dist/commands/apps/report.js +63 -0
- package/dist/commands/apps/resume.d.ts +12 -0
- package/dist/commands/apps/resume.js +36 -0
- package/dist/commands/apps/settings/set.d.ts +13 -0
- package/dist/commands/apps/settings/set.js +54 -0
- package/dist/commands/apps/settings/show.d.ts +11 -0
- package/dist/commands/apps/settings/show.js +31 -0
- package/dist/commands/apps/show.d.ts +12 -0
- package/dist/commands/apps/show.js +49 -0
- package/dist/commands/apps/suspend.d.ts +12 -0
- package/dist/commands/apps/suspend.js +35 -0
- package/dist/commands/apps/uninstall.d.ts +13 -0
- package/dist/commands/apps/uninstall.js +43 -0
- package/dist/commands/apps/upgrade.d.ts +14 -0
- package/dist/commands/apps/upgrade.js +49 -0
- package/dist/commands/apps/version/create.d.ts +14 -0
- package/dist/commands/apps/version/create.js +53 -0
- package/dist/commands/apps/version/show.d.ts +12 -0
- package/dist/commands/apps/version/show.js +39 -0
- package/dist/commands/apps/versions.d.ts +12 -0
- package/dist/commands/apps/versions.js +40 -0
- package/dist/commands/apps/webhooks/list.d.ts +12 -0
- package/dist/commands/apps/webhooks/list.js +47 -0
- package/dist/commands/characters/list.js +2 -1
- package/dist/commands/chats/files/list.js +2 -1
- package/dist/commands/chats/folders/list.js +2 -1
- package/dist/commands/chats/list.js +2 -1
- package/dist/commands/chats/spaces/list.js +2 -1
- package/dist/commands/chats/widgets/list.js +2 -1
- package/dist/commands/code/jobs/list.js +4 -1
- package/dist/commands/commerce/incidents/list.js +2 -1
- package/dist/commands/commitments/accounting.js +3 -0
- package/dist/commands/commitments/action-proposals.d.ts +8 -0
- package/dist/commands/commitments/action-proposals.js +17 -2
- package/dist/commands/commitments/cost.d.ts +11 -0
- package/dist/commands/commitments/cost.js +25 -0
- package/dist/commands/commitments/create.js +6 -1
- package/dist/commands/commitments/endpoints/list.js +2 -1
- package/dist/commands/commitments/links/list.js +2 -1
- package/dist/commands/commitments/list.js +2 -1
- package/dist/commands/commitments/liveness.d.ts +30 -0
- package/dist/commands/commitments/liveness.js +22 -5
- package/dist/commands/commitments/pack/list.js +2 -1
- package/dist/commands/commitments/preflight.js +6 -2
- package/dist/commands/commitments/update.js +10 -1
- package/dist/commands/compass/list.js +2 -1
- package/dist/commands/context.js +7 -1
- package/dist/commands/convos/list.js +3 -2
- package/dist/commands/daemon/install.js +17 -1
- package/dist/commands/daemon/login.js +14 -0
- package/dist/commands/dm/list.js +2 -1
- package/dist/commands/dm/work.d.ts +19 -0
- package/dist/commands/dm/work.js +54 -0
- package/dist/commands/feeds/list.js +2 -1
- package/dist/commands/followups/list.js +2 -1
- package/dist/commands/followups/plans/cancel.d.ts +13 -0
- package/dist/commands/followups/plans/cancel.js +26 -0
- package/dist/commands/followups/plans/create.d.ts +11 -0
- package/dist/commands/followups/plans/create.js +35 -0
- package/dist/commands/followups/plans/list.d.ts +13 -0
- package/dist/commands/followups/plans/list.js +50 -0
- package/dist/commands/followups/plans/observability.d.ts +11 -0
- package/dist/commands/followups/plans/observability.js +46 -0
- package/dist/commands/followups/plans/revise.d.ts +13 -0
- package/dist/commands/followups/plans/revise.js +35 -0
- package/dist/commands/followups/plans/show.d.ts +11 -0
- package/dist/commands/followups/plans/show.js +32 -0
- package/dist/commands/goals/key-results/list.js +2 -1
- package/dist/commands/goals/labels/list.js +3 -2
- package/dist/commands/goals/list.js +3 -2
- package/dist/commands/grants/list.js +2 -1
- package/dist/commands/harnesses/grants/list.js +2 -1
- package/dist/commands/harnesses/leases/list.js +2 -1
- package/dist/commands/harnesses/list.js +10 -1
- package/dist/commands/harnesses/prune.d.ts +26 -0
- package/dist/commands/harnesses/prune.js +172 -0
- package/dist/commands/ingress/list.js +2 -1
- package/dist/commands/initiatives/list.js +2 -1
- package/dist/commands/instruction-blocks/list.js +2 -1
- package/dist/commands/instructions/list.js +2 -1
- package/dist/commands/integrations/connections/list.js +2 -1
- package/dist/commands/integrations/tools/list.js +2 -1
- package/dist/commands/labels/list.js +3 -2
- package/dist/commands/learning/adapters.d.ts +16 -0
- package/dist/commands/learning/adapters.js +44 -0
- package/dist/commands/login.js +11 -0
- package/dist/commands/machines/dedicated/list.js +2 -1
- package/dist/commands/machines/hosted/list.js +2 -1
- package/dist/commands/machines/list.js +2 -1
- package/dist/commands/machines/show.js +5 -2
- package/dist/commands/measures/list.js +2 -1
- package/dist/commands/memory/list.js +2 -1
- package/dist/commands/memory/proposals/list.js +2 -1
- package/dist/commands/memory/stores/list.js +2 -1
- package/dist/commands/memory/topics/list.js +2 -1
- package/dist/commands/memory/versions/list.js +2 -1
- package/dist/commands/messages/list.js +2 -1
- package/dist/commands/northstars/intents/list.js +2 -1
- package/dist/commands/northstars/list.js +2 -1
- package/dist/commands/northstars/recommendations/list.js +2 -1
- package/dist/commands/outbox/list.js +2 -1
- package/dist/commands/profiles/list.js +2 -1
- package/dist/commands/projects/docs/list.js +8 -1
- package/dist/commands/projects/updates/list.js +2 -1
- package/dist/commands/proposals/list.js +2 -1
- package/dist/commands/requests/comments/list.js +2 -1
- package/dist/commands/requests/list.js +2 -1
- package/dist/commands/shares/list.js +2 -1
- package/dist/commands/shortcuts/list.js +2 -1
- package/dist/commands/signals/monitors/list.js +2 -1
- package/dist/commands/signals/schemas/list.js +2 -1
- package/dist/commands/signals/sources/list.js +2 -1
- package/dist/commands/space-directory-views/list.js +2 -1
- package/dist/commands/spaces/actions/list.js +4 -3
- package/dist/commands/spaces/briefs/list.js +2 -1
- package/dist/commands/spaces/cycles/list.js +2 -1
- package/dist/commands/spaces/files/folders/list.js +2 -1
- package/dist/commands/spaces/files/list.js +3 -2
- package/dist/commands/spaces/heartbeats/list.js +3 -2
- package/dist/commands/spaces/labels/list.js +3 -2
- package/dist/commands/spaces/list.d.ts +3 -18
- package/dist/commands/spaces/list.js +28 -35
- package/dist/commands/spaces/live/cards/list.js +2 -1
- package/dist/commands/spaces/members/list.d.ts +1 -0
- package/dist/commands/spaces/members/list.js +4 -1
- package/dist/commands/spaces/show.js +2 -2
- package/dist/commands/spaces/skills/list.js +6 -2
- package/dist/commands/spaces/states/list.js +2 -1
- package/dist/commands/spaces/views/list.js +2 -1
- package/dist/commands/spaces/widgets/list.js +3 -2
- package/dist/commands/spaces/workflow-templates/list.js +2 -1
- package/dist/commands/spaces/workflows/fixtures/list.js +2 -1
- package/dist/commands/spaces/workflows/list.js +3 -2
- package/dist/commands/spaces/workflows/proposals/list.js +2 -1
- package/dist/commands/spaces/workflows/start.js +3 -1
- package/dist/commands/spaces/workflows/triggers/list.js +2 -1
- package/dist/commands/spaces/workflows/validate.js +12 -2
- package/dist/commands/store/acquisitions/list.js +2 -1
- package/dist/commands/store/admissions/list.js +17 -1
- package/dist/commands/store/advisories/list.js +2 -1
- package/dist/commands/store/follows/list.js +2 -1
- package/dist/commands/store/publishers/domains/list.js +2 -1
- package/dist/commands/store/reports/list.js +2 -1
- package/dist/commands/subscriptions/list.js +2 -1
- package/dist/commands/tasks/actionability.js +7 -30
- package/dist/commands/tasks/activity.js +14 -8
- package/dist/commands/tasks/approvals/list.js +2 -1
- package/dist/commands/tasks/assign.d.ts +1 -0
- package/dist/commands/tasks/assign.js +43 -7
- package/dist/commands/tasks/attachments/list.js +2 -1
- package/dist/commands/tasks/chat/send.js +34 -0
- package/dist/commands/tasks/comments/add.js +6 -1
- package/dist/commands/tasks/comments/list.js +2 -1
- package/dist/commands/tasks/complete.js +26 -2
- package/dist/commands/tasks/continue.d.ts +18 -0
- package/dist/commands/tasks/continue.js +54 -0
- package/dist/commands/tasks/create-tree.d.ts +5 -0
- package/dist/commands/tasks/create-tree.js +399 -219
- package/dist/commands/tasks/create.d.ts +1 -0
- package/dist/commands/tasks/create.js +63 -11
- package/dist/commands/tasks/deliverable/add.js +10 -3
- package/dist/commands/tasks/deliverable/list.js +2 -1
- package/dist/commands/tasks/events/list.js +2 -1
- package/dist/commands/tasks/execution-state.d.ts +12 -0
- package/dist/commands/tasks/execution-state.js +28 -0
- package/dist/commands/tasks/expectations/assess.js +40 -5
- package/dist/commands/tasks/guide.d.ts +10 -0
- package/dist/commands/tasks/guide.js +20 -0
- package/dist/commands/tasks/labels/list.js +2 -1
- package/dist/commands/tasks/list.d.ts +19 -0
- package/dist/commands/tasks/list.js +103 -6
- package/dist/commands/tasks/move.js +10 -2
- package/dist/commands/tasks/preflight.d.ts +14 -0
- package/dist/commands/tasks/preflight.js +77 -0
- package/dist/commands/tasks/rearm-recurrence.js +22 -3
- package/dist/commands/tasks/resource/list.js +2 -1
- package/dist/commands/tasks/result/submit.js +10 -1
- package/dist/commands/tasks/review.js +6 -1
- package/dist/commands/tasks/revisions.d.ts +2 -0
- package/dist/commands/tasks/revisions.js +8 -1
- package/dist/commands/tasks/show.d.ts +8 -0
- package/dist/commands/tasks/show.js +81 -43
- package/dist/commands/tasks/start.d.ts +1 -0
- package/dist/commands/tasks/start.js +35 -0
- package/dist/commands/tasks/templates/list.js +2 -1
- package/dist/commands/tasks/timeline.d.ts +5 -0
- package/dist/commands/tasks/timeline.js +9 -1
- package/dist/commands/tasks/unschedule.js +5 -1
- package/dist/commands/tasks/update.d.ts +1 -0
- package/dist/commands/tasks/update.js +36 -3
- package/dist/commands/tasks/updates/add.js +6 -1
- package/dist/commands/tasks/updates/list.js +2 -1
- package/dist/commands/tasks/upsert.d.ts +1 -0
- package/dist/commands/tasks/upsert.js +8 -1
- package/dist/commands/token/list.js +2 -1
- package/dist/commands/tokens/list.js +2 -1
- package/dist/commands/tones/list.js +4 -2
- package/dist/commands/triggers/audit.js +12 -3
- package/dist/commands/triggers/create.js +1 -1
- package/dist/commands/triggers/fire-detail.d.ts +7 -0
- package/dist/commands/triggers/fire-detail.js +30 -12
- package/dist/commands/triggers/fire.js +13 -3
- package/dist/commands/triggers/list.js +2 -1
- package/dist/commands/triggers/parse-intent.js +1 -1
- package/dist/commands/triggers/update.js +1 -1
- package/dist/commands/views/list.js +2 -1
- package/dist/commands/webhooks/list.js +2 -1
- package/dist/commands/whoami.js +1 -1
- package/dist/commands/widgets/list.js +2 -1
- package/dist/commands/widgets/save-as-app.d.ts +13 -0
- package/dist/commands/widgets/save-as-app.js +65 -0
- package/dist/commands/work-views/list.js +2 -1
- package/dist/commands/worklog/list.js +2 -1
- package/dist/commands/workspaces/grants.js +1 -4
- package/dist/commands/workspaces/list.js +3 -2
- package/dist/commands/workspaces/members.d.ts +1 -0
- package/dist/commands/workspaces/members.js +10 -7
- package/dist/generated/managed-instruction-guides.json +2 -2
- package/dist/help.js +7 -0
- package/dist/lib/agent-proactive-baseline.d.ts +9 -0
- package/dist/lib/agent-proactive-baseline.js +44 -0
- package/dist/lib/agentic-stream.d.ts +4 -1
- package/dist/lib/agentic-stream.js +29 -4
- package/dist/lib/appData.d.ts +75 -0
- package/dist/lib/appData.js +274 -0
- package/dist/lib/appInstallations.d.ts +117 -0
- package/dist/lib/appInstallations.js +960 -0
- package/dist/lib/appSettings.d.ts +3 -0
- package/dist/lib/appSettings.js +71 -0
- package/dist/lib/appWebhooks.d.ts +7 -0
- package/dist/lib/appWebhooks.js +59 -0
- package/dist/lib/apps-command.d.ts +44 -0
- package/dist/lib/apps-command.js +164 -0
- package/dist/lib/apps.d.ts +45 -0
- package/dist/lib/apps.js +148 -0
- package/dist/lib/appsCheck.d.ts +12 -0
- package/dist/lib/appsCheck.js +173 -0
- package/dist/lib/appsFs.d.ts +58 -0
- package/dist/lib/appsFs.js +384 -0
- package/dist/lib/auth-failure.d.ts +20 -0
- package/dist/lib/auth-failure.js +40 -3
- package/dist/lib/cli-installers.d.ts +9 -2
- package/dist/lib/command-miss.js +107 -0
- package/dist/lib/commitment-loop-status.js +25 -3
- package/dist/lib/commitment-product.js +5 -2
- package/dist/lib/commitments.d.ts +45 -3
- package/dist/lib/commitments.js +139 -41
- package/dist/lib/compasses.d.ts +4 -0
- package/dist/lib/compasses.js +11 -0
- package/dist/lib/daemon-machine-identity-copy.d.ts +14 -0
- package/dist/lib/daemon-machine-identity-copy.js +27 -0
- package/dist/lib/daemon-machine-identity.d.ts +27 -0
- package/dist/lib/daemon-machine-identity.js +61 -0
- package/dist/lib/daemon-setup.js +7 -7
- package/dist/lib/daemonHandoff.d.ts +19 -1
- package/dist/lib/daemonHandoff.js +62 -2
- package/dist/lib/dedicated-ssh.d.ts +2 -0
- package/dist/lib/dedicated-ssh.js +98 -28
- package/dist/lib/harnesses.d.ts +71 -0
- package/dist/lib/harnesses.js +70 -0
- package/dist/lib/json-output.d.ts +33 -0
- package/dist/lib/json-output.js +37 -0
- package/dist/lib/list-output.d.ts +9 -4
- package/dist/lib/list-output.js +38 -9
- package/dist/lib/lookbackPlans.d.ts +13 -0
- package/dist/lib/lookbackPlans.js +68 -0
- package/dist/lib/machines.d.ts +27 -6
- package/dist/lib/machines.js +25 -14
- package/dist/lib/member-output.d.ts +20 -0
- package/dist/lib/member-output.js +57 -0
- package/dist/lib/preflight-copy.d.ts +7 -0
- package/dist/lib/preflight-copy.js +31 -0
- package/dist/lib/profile-machine-identity-guard.js +11 -1
- package/dist/lib/roles.d.ts +2 -2
- package/dist/lib/task-admission.d.ts +9 -0
- package/dist/lib/task-admission.js +35 -0
- package/dist/lib/task-batch.d.ts +4 -0
- package/dist/lib/task-batch.js +2 -0
- package/dist/lib/task-economics.d.ts +10 -0
- package/dist/lib/task-economics.js +24 -2
- package/dist/lib/task-operations.d.ts +25 -0
- package/dist/lib/task-operations.js +123 -0
- package/dist/lib/task-preflight.d.ts +35 -0
- package/dist/lib/task-preflight.js +121 -0
- package/dist/lib/task-resource-references.d.ts +23 -0
- package/dist/lib/task-resource-references.js +119 -0
- package/dist/lib/task-spec-verification.d.ts +42 -0
- package/dist/lib/task-spec-verification.js +101 -0
- package/dist/lib/task-work.d.ts +11 -0
- package/dist/lib/task-work.js +41 -0
- package/dist/lib/task-write-attribution.d.ts +26 -0
- package/dist/lib/task-write-attribution.js +47 -0
- package/dist/lib/tasks.d.ts +13 -0
- package/dist/lib/tasks.js +61 -8
- package/dist/lib/triggers.d.ts +18 -0
- package/dist/lib/triggers.js +97 -5
- package/dist/lib/usage-discovery.d.ts +4 -0
- package/dist/lib/usage-discovery.js +14 -4
- package/dist/lib/widgetApps.d.ts +10 -0
- package/dist/lib/widgetApps.js +47 -0
- package/dist/lib/widgetStaticScan.js +25 -1
- package/dist/lib/workflow-run-view.d.ts +4 -0
- package/dist/lib/workflow-run-view.js +5 -0
- package/dist/lib/workspaces.d.ts +33 -9
- package/dist/lib/workspaces.js +19 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +14 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.d.ts +49 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +26 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.d.ts +118 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.js +614 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +5 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.d.ts +60 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.js +130 -6
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.js +15 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refreshClassification.d.ts +5 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refreshClassification.js +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionRevocation.d.ts +177 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionRevocation.js +484 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/telemetryRedaction.d.ts +11 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/telemetryRedaction.js +46 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.d.ts +232 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.js +372 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/types.d.ts +17 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/types.js +12 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +14 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +45 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.d.ts +49 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +24 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.d.ts +118 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.js +608 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.d.ts +60 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.js +128 -6
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.js +15 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refreshClassification.d.ts +5 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refreshClassification.js +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionRevocation.d.ts +177 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionRevocation.js +472 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/telemetryRedaction.d.ts +11 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/telemetryRedaction.js +44 -6
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.d.ts +232 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.js +360 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/types.d.ts +17 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/types.js +12 -1
- package/dist/node_modules/@skrr-ai/auth-core/package.json +31 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +25255 -18711
- package/docs/v1/operations.md +52 -0
- package/docs/v1/space-search.md +19 -0
- package/oclif.manifest.json +4843 -513
- package/package.json +32 -2
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a session was signed out, and what the person should do next (OSK-16941).
|
|
3
|
+
*
|
|
4
|
+
* ## Why this file exists
|
|
5
|
+
*
|
|
6
|
+
* The server always knew why it refused a session: `requireJwtAuth` answers
|
|
7
|
+
* `401 SESSION_REVOKED` with a `reason` for an inactive account, an account-wide
|
|
8
|
+
* revocation, a password change and a per-session sign-out. Nothing passed it
|
|
9
|
+
* on. The CLI dropped the field, the web client folded every unrecognised code
|
|
10
|
+
* into "your saved credentials are no longer valid", and a refresh refused for a
|
|
11
|
+
* revoked session answered with no code at all. A person signed out with no
|
|
12
|
+
* explanation reasonably concludes their account was stolen.
|
|
13
|
+
*
|
|
14
|
+
* So the vocabulary lives here, once, beside the one function that turns a
|
|
15
|
+
* reason into words: the API writes these codes, the web login page, the desktop
|
|
16
|
+
* banner, the desktop main process (OS notification and tray) and the CLI all
|
|
17
|
+
* render them through `describeSessionRevocation`.
|
|
18
|
+
*
|
|
19
|
+
* ## Why auth-core, behind its own subpath
|
|
20
|
+
*
|
|
21
|
+
* It was declared in `@skrr-ai/data-provider`, which the Electron main process
|
|
22
|
+
* does not (and should not) depend on — so main kept printing the server's raw
|
|
23
|
+
* message in the OS notification and the tray. auth-core is already the
|
|
24
|
+
* package that LATCHES the reason (`refresh.ts` writes `revocationReason` into
|
|
25
|
+
* `needs-reauth.json`), and every desktop, daemon and CLI process already
|
|
26
|
+
* depends on it. This module imports nothing, so the
|
|
27
|
+
* `@skrr-ai/auth-core/session-revocation` subpath is safe in a browser, React
|
|
28
|
+
* Native and Node alike, the same way `first-party-harness` is.
|
|
29
|
+
* `@skrr-ai/data-provider` re-exports it unchanged: there is still exactly one
|
|
30
|
+
* declaration of the vocabulary and one copy of its words.
|
|
31
|
+
*
|
|
32
|
+
* ## Three closed lists
|
|
33
|
+
*
|
|
34
|
+
* - `SESSION_REVOCATION_REASONS` — what a refused CLIENT is told. Wire values;
|
|
35
|
+
* the 401 body's `reason` field. The account-state members keep the spelling
|
|
36
|
+
* `requireJwtAuth` already sent (`banned`, `pending_deletion`, ...), so a
|
|
37
|
+
* client that already switched on them keeps working.
|
|
38
|
+
* - `SESSION_REVOCATION_CAUSES` — what HAPPENED, recorded in Security activity
|
|
39
|
+
* when sessions are revoked. Each cause names its trigger and the reason the
|
|
40
|
+
* signed-out client is told.
|
|
41
|
+
* - `SESSION_REVOCATION_TRIGGERS` — who or what did it.
|
|
42
|
+
*
|
|
43
|
+
* ## Unknown is a member, and it is never hidden
|
|
44
|
+
*
|
|
45
|
+
* Each list carries an explicit `unknown`. A missing, empty or unrecognised
|
|
46
|
+
* value normalizes to it, and its copy says plainly that we could not tell why.
|
|
47
|
+
* It is never folded into the nearest reassuring reading: "Everything reads
|
|
48
|
+
* healthy and the thing is unusable" (root CLAUDE.md) is exactly what an
|
|
49
|
+
* optimistic default here would produce.
|
|
50
|
+
*
|
|
51
|
+
* Copy avoids contractions in code strings so a terminal and a source file read
|
|
52
|
+
* them the same; the web reads the localized keys instead.
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* The CLI binary the `cli` surface names when the caller passes no `bin`. A
|
|
56
|
+
* literal because this module imports nothing; `@skrr-ai/data-provider`'s
|
|
57
|
+
* `sessionRevocation.spec` asserts it equals `BRAND_NAME`, so the two cannot
|
|
58
|
+
* drift.
|
|
59
|
+
*/
|
|
60
|
+
export const SESSION_REVOCATION_DEFAULT_BIN = 'skrr';
|
|
61
|
+
/* ------------------------------------------------------------------------ */
|
|
62
|
+
/* Reasons — what a refused client is told */
|
|
63
|
+
/* ------------------------------------------------------------------------ */
|
|
64
|
+
export const SESSION_REVOCATION_REASONS = [
|
|
65
|
+
'password_change',
|
|
66
|
+
'sessions_revoked',
|
|
67
|
+
'logged_out',
|
|
68
|
+
'session_limit',
|
|
69
|
+
'sign_in_method_removed',
|
|
70
|
+
'security_check',
|
|
71
|
+
'machine_removed',
|
|
72
|
+
'banned',
|
|
73
|
+
'disabled',
|
|
74
|
+
'deleted',
|
|
75
|
+
'pending_deletion',
|
|
76
|
+
'unknown',
|
|
77
|
+
];
|
|
78
|
+
export const SESSION_REVOCATION_UNKNOWN = 'unknown';
|
|
79
|
+
/**
|
|
80
|
+
* The login-page query parameter that carries a revocation reason across the
|
|
81
|
+
* sign-out redirect (`/login?reason=SESSION_REVOKED&revocation=password_change`).
|
|
82
|
+
* `reason` keeps the refusal CODE it always carried, so a login page that
|
|
83
|
+
* predates this still says something.
|
|
84
|
+
*/
|
|
85
|
+
export const SESSION_REVOCATION_QUERY_PARAM = 'revocation';
|
|
86
|
+
/**
|
|
87
|
+
* Other spellings that already reach clients for the SAME reason: the
|
|
88
|
+
* revocation-bus `cause` strings an older server put on `auth:revoked`, and the
|
|
89
|
+
* `missing` account state. Kept so a client newer than its server still names
|
|
90
|
+
* them; a new server sends the canonical member.
|
|
91
|
+
*/
|
|
92
|
+
const SESSION_REVOCATION_REASON_ALIASES = Object.freeze({
|
|
93
|
+
logout: 'logged_out',
|
|
94
|
+
explicit_logout: 'logged_out',
|
|
95
|
+
session_limit_reached: 'session_limit',
|
|
96
|
+
reuse: 'security_check',
|
|
97
|
+
reuse_detected: 'security_check',
|
|
98
|
+
missing: 'deleted',
|
|
99
|
+
});
|
|
100
|
+
export function isSessionRevocationReason(value) {
|
|
101
|
+
return (typeof value === 'string' && SESSION_REVOCATION_REASONS.includes(value));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The canonical reason for any value a server or a URL handed us. Anything not
|
|
105
|
+
* in the vocabulary is `unknown` — never a guess.
|
|
106
|
+
*/
|
|
107
|
+
export function normalizeSessionRevocationReason(value) {
|
|
108
|
+
if (isSessionRevocationReason(value))
|
|
109
|
+
return value;
|
|
110
|
+
if (typeof value === 'string' &&
|
|
111
|
+
Object.prototype.hasOwnProperty.call(SESSION_REVOCATION_REASON_ALIASES, value)) {
|
|
112
|
+
return SESSION_REVOCATION_REASON_ALIASES[value];
|
|
113
|
+
}
|
|
114
|
+
return SESSION_REVOCATION_UNKNOWN;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Refusal codes that end a session WITHOUT revoking it, each of which a surface
|
|
118
|
+
* explains in its own sentence (expired, no longer valid). Every other code a
|
|
119
|
+
* refusal latch can carry is read as a revocation.
|
|
120
|
+
*/
|
|
121
|
+
export const NON_REVOCATION_REFUSAL_CODES = [
|
|
122
|
+
'REFRESH_EXPIRED',
|
|
123
|
+
'TOKEN_EXPIRED',
|
|
124
|
+
'REFRESH_INVALID',
|
|
125
|
+
'TOKEN_INVALID',
|
|
126
|
+
];
|
|
127
|
+
export function isNonRevocationRefusalCode(value) {
|
|
128
|
+
return (typeof value === 'string' && NON_REVOCATION_REFUSAL_CODES.includes(value));
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The revocation reason a refusal names — from a refusal CODE (`SESSION_REVOKED`,
|
|
132
|
+
* `REFRESH_REUSED`, ...) and the revocation reason that travelled beside it —
|
|
133
|
+
* or `null` when the code is one of `NON_REVOCATION_REFUSAL_CODES`.
|
|
134
|
+
*
|
|
135
|
+
* - A revocation reason, when present, always wins.
|
|
136
|
+
* - `SESSION_REVOKED` with no reason beside it IS a revocation whose reason we
|
|
137
|
+
* do not know, so it is `unknown`.
|
|
138
|
+
* - `REFRESH_REUSED` is the refresh-family burn, i.e. a security check.
|
|
139
|
+
* - Any other code, including none at all, is `unknown`: "we could not tell
|
|
140
|
+
* why", never a guess.
|
|
141
|
+
*
|
|
142
|
+
* Shared by the web banner and the desktop main process so the two read one
|
|
143
|
+
* latch the same way.
|
|
144
|
+
*/
|
|
145
|
+
export function sessionRevocationForRefusal(code, revocation) {
|
|
146
|
+
if (revocation)
|
|
147
|
+
return normalizeSessionRevocationReason(revocation);
|
|
148
|
+
if (code === 'SESSION_REVOKED')
|
|
149
|
+
return SESSION_REVOCATION_UNKNOWN;
|
|
150
|
+
if (code === 'REFRESH_REUSED')
|
|
151
|
+
return 'security_check';
|
|
152
|
+
if (isNonRevocationRefusalCode(code))
|
|
153
|
+
return null;
|
|
154
|
+
return normalizeSessionRevocationReason(code);
|
|
155
|
+
}
|
|
156
|
+
/* ------------------------------------------------------------------------ */
|
|
157
|
+
/* Next steps */
|
|
158
|
+
/* ------------------------------------------------------------------------ */
|
|
159
|
+
export const SESSION_REVOCATION_NEXT_STEPS = [
|
|
160
|
+
'sign_in',
|
|
161
|
+
'sign_in_and_review',
|
|
162
|
+
'cancel_deletion',
|
|
163
|
+
'contact_support',
|
|
164
|
+
'use_another_account',
|
|
165
|
+
];
|
|
166
|
+
const REASON_COPY = Object.freeze({
|
|
167
|
+
password_change: {
|
|
168
|
+
title: 'Your password was changed.',
|
|
169
|
+
detail: 'Changing the password signs out every session that was opened before the change, including this one.',
|
|
170
|
+
nextStep: 'sign_in_and_review',
|
|
171
|
+
},
|
|
172
|
+
sessions_revoked: {
|
|
173
|
+
title: 'Every session on your account was signed out.',
|
|
174
|
+
detail: 'All sessions were ended at once. That happens when someone signed in to the account chooses to sign out everywhere, changes two-factor or email settings, uses a recovery key or reports a sign-in, and when an administrator or an automatic security measure revokes sessions. Security activity records which one it was.',
|
|
175
|
+
nextStep: 'sign_in_and_review',
|
|
176
|
+
},
|
|
177
|
+
logged_out: {
|
|
178
|
+
title: 'This session was signed out.',
|
|
179
|
+
detail: 'It was signed out on this device or from another device signed in to your account.',
|
|
180
|
+
nextStep: 'sign_in',
|
|
181
|
+
},
|
|
182
|
+
session_limit: {
|
|
183
|
+
title: 'This session was signed out to make room for a newer one.',
|
|
184
|
+
detail: 'Your account reached its limit of signed-in sessions, so the oldest one was ended.',
|
|
185
|
+
nextStep: 'sign_in',
|
|
186
|
+
},
|
|
187
|
+
sign_in_method_removed: {
|
|
188
|
+
title: 'The way this session signed in was removed from your account.',
|
|
189
|
+
detail: 'The password, passkey or sign-in provider this session used is no longer on the account.',
|
|
190
|
+
nextStep: 'sign_in_and_review',
|
|
191
|
+
},
|
|
192
|
+
security_check: {
|
|
193
|
+
title: 'This session was ended by a security check.',
|
|
194
|
+
detail: 'Its credential was presented in a way that suggested it may have been copied, so it was ended to protect your account.',
|
|
195
|
+
nextStep: 'sign_in_and_review',
|
|
196
|
+
},
|
|
197
|
+
machine_removed: {
|
|
198
|
+
title: 'The machine this session belonged to was removed.',
|
|
199
|
+
detail: 'The machine connection that held this sign-in was removed or replaced.',
|
|
200
|
+
nextStep: 'sign_in',
|
|
201
|
+
},
|
|
202
|
+
banned: {
|
|
203
|
+
title: 'This account has been suspended.',
|
|
204
|
+
detail: 'An administrator suspended the account, so its sessions no longer work.',
|
|
205
|
+
nextStep: 'contact_support',
|
|
206
|
+
},
|
|
207
|
+
disabled: {
|
|
208
|
+
title: 'This account is disabled.',
|
|
209
|
+
detail: 'The account was disabled, so its sessions no longer work.',
|
|
210
|
+
nextStep: 'contact_support',
|
|
211
|
+
},
|
|
212
|
+
deleted: {
|
|
213
|
+
title: 'This account no longer exists.',
|
|
214
|
+
detail: 'The account this session belonged to was deleted.',
|
|
215
|
+
nextStep: 'use_another_account',
|
|
216
|
+
},
|
|
217
|
+
pending_deletion: {
|
|
218
|
+
title: 'This account is scheduled for deletion.',
|
|
219
|
+
detail: 'Until the deletion is carried out, signing in can only cancel it.',
|
|
220
|
+
nextStep: 'cancel_deletion',
|
|
221
|
+
},
|
|
222
|
+
unknown: {
|
|
223
|
+
title: 'You were signed out, and we could not tell why.',
|
|
224
|
+
detail: 'The server ended this session without saying why. That can happen with an older server or an unexpected error.',
|
|
225
|
+
nextStep: 'sign_in_and_review',
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
function nextStepCopy(step, surface, bin) {
|
|
229
|
+
const signIn = surface === 'cli' ? `Run \`${bin} login\` to sign in again.` : 'Sign in again to continue.';
|
|
230
|
+
switch (step) {
|
|
231
|
+
case 'sign_in':
|
|
232
|
+
return signIn;
|
|
233
|
+
case 'sign_in_and_review':
|
|
234
|
+
return (`${signIn} If this was not you, open Settings > Account > Security activity to see ` +
|
|
235
|
+
'what happened, and change your password.');
|
|
236
|
+
case 'cancel_deletion':
|
|
237
|
+
return surface === 'cli'
|
|
238
|
+
? 'Sign in on the web to cancel the deletion if you want to keep the account.'
|
|
239
|
+
: 'Sign in to cancel the deletion if you want to keep the account.';
|
|
240
|
+
case 'contact_support':
|
|
241
|
+
return 'Contact support if you think this is a mistake.';
|
|
242
|
+
case 'use_another_account':
|
|
243
|
+
return surface === 'cli'
|
|
244
|
+
? `Run \`${bin} login\` to sign in with a different account.`
|
|
245
|
+
: 'Sign in with a different account, or create a new one.';
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* THE copy for a revoked session. Never throws, whatever it is given: the server
|
|
250
|
+
* can ship a reason before a client knows it, and that case must still say
|
|
251
|
+
* something true ("we could not tell why"), not nothing.
|
|
252
|
+
*/
|
|
253
|
+
export function describeSessionRevocation(value, { surface = 'app', bin = SESSION_REVOCATION_DEFAULT_BIN, } = {}) {
|
|
254
|
+
const reason = normalizeSessionRevocationReason(value);
|
|
255
|
+
const unrecognized = reason === SESSION_REVOCATION_UNKNOWN &&
|
|
256
|
+
typeof value === 'string' &&
|
|
257
|
+
value.trim() !== '' &&
|
|
258
|
+
value !== SESSION_REVOCATION_UNKNOWN
|
|
259
|
+
? value.trim().slice(0, 64)
|
|
260
|
+
: null;
|
|
261
|
+
const copy = REASON_COPY[reason];
|
|
262
|
+
return {
|
|
263
|
+
reason,
|
|
264
|
+
unrecognized,
|
|
265
|
+
title: copy.title,
|
|
266
|
+
detail: copy.detail,
|
|
267
|
+
nextStep: copy.nextStep,
|
|
268
|
+
nextStepText: nextStepCopy(copy.nextStep, surface, bin),
|
|
269
|
+
reviewSecurityActivity: copy.nextStep === 'sign_in_and_review',
|
|
270
|
+
keys: {
|
|
271
|
+
title: `com_auth_revoked_${reason}_title`,
|
|
272
|
+
detail: `com_auth_revoked_${reason}_detail`,
|
|
273
|
+
nextStep: `com_auth_revoked_next_${copy.nextStep}`,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/** One line for a terminal or a notification: title, detail and next step. */
|
|
278
|
+
export function formatSessionRevocation(value, options = {}) {
|
|
279
|
+
const d = describeSessionRevocation(value, options);
|
|
280
|
+
const code = d.unrecognized ? ` (reason code: ${d.unrecognized})` : '';
|
|
281
|
+
return `${d.title}${code} ${d.detail} ${d.nextStepText}`;
|
|
282
|
+
}
|
|
283
|
+
/* ------------------------------------------------------------------------ */
|
|
284
|
+
/* Triggers and causes — the Security activity record */
|
|
285
|
+
/* ------------------------------------------------------------------------ */
|
|
286
|
+
export const SESSION_REVOCATION_TRIGGERS = [
|
|
287
|
+
'account_owner',
|
|
288
|
+
'administrator',
|
|
289
|
+
'security_system',
|
|
290
|
+
'external_provider',
|
|
291
|
+
'account_lifecycle',
|
|
292
|
+
'unknown',
|
|
293
|
+
];
|
|
294
|
+
export const SESSION_REVOCATION_CAUSES = [
|
|
295
|
+
'password_change',
|
|
296
|
+
'password_reset',
|
|
297
|
+
'sign_out_everywhere',
|
|
298
|
+
'sign_out_other_sessions',
|
|
299
|
+
'session_signed_out',
|
|
300
|
+
'two_factor_change',
|
|
301
|
+
'email_change',
|
|
302
|
+
'email_change_reverted',
|
|
303
|
+
'account_recovery',
|
|
304
|
+
'reported_not_me',
|
|
305
|
+
'sign_in_method_removed',
|
|
306
|
+
'machine_removed',
|
|
307
|
+
'oauth_app_revoked',
|
|
308
|
+
'session_limit',
|
|
309
|
+
'suspicious_reuse',
|
|
310
|
+
'administrator',
|
|
311
|
+
'account_suspended',
|
|
312
|
+
'external_provider',
|
|
313
|
+
'account_deletion_scheduled',
|
|
314
|
+
'account_superseded',
|
|
315
|
+
'unverified_account_cleanup',
|
|
316
|
+
'unknown',
|
|
317
|
+
];
|
|
318
|
+
export const SESSION_REVOCATION_CAUSE_FACTS = Object.freeze({
|
|
319
|
+
password_change: {
|
|
320
|
+
trigger: 'account_owner',
|
|
321
|
+
reason: 'password_change',
|
|
322
|
+
copy: 'The password was changed.',
|
|
323
|
+
},
|
|
324
|
+
password_reset: {
|
|
325
|
+
trigger: 'account_owner',
|
|
326
|
+
reason: 'password_change',
|
|
327
|
+
copy: 'The password was reset from an emailed link.',
|
|
328
|
+
},
|
|
329
|
+
sign_out_everywhere: {
|
|
330
|
+
trigger: 'account_owner',
|
|
331
|
+
reason: 'sessions_revoked',
|
|
332
|
+
copy: 'Sign out everywhere was chosen.',
|
|
333
|
+
},
|
|
334
|
+
sign_out_other_sessions: {
|
|
335
|
+
trigger: 'account_owner',
|
|
336
|
+
reason: 'logged_out',
|
|
337
|
+
copy: 'Every other session was signed out.',
|
|
338
|
+
},
|
|
339
|
+
session_signed_out: {
|
|
340
|
+
trigger: 'account_owner',
|
|
341
|
+
reason: 'logged_out',
|
|
342
|
+
copy: 'A session was signed out.',
|
|
343
|
+
},
|
|
344
|
+
two_factor_change: {
|
|
345
|
+
trigger: 'account_owner',
|
|
346
|
+
reason: 'sessions_revoked',
|
|
347
|
+
copy: 'Two-factor authentication settings changed.',
|
|
348
|
+
},
|
|
349
|
+
email_change: {
|
|
350
|
+
trigger: 'account_owner',
|
|
351
|
+
reason: 'sessions_revoked',
|
|
352
|
+
copy: 'The account email address was changed.',
|
|
353
|
+
},
|
|
354
|
+
email_change_reverted: {
|
|
355
|
+
trigger: 'account_owner',
|
|
356
|
+
reason: 'sessions_revoked',
|
|
357
|
+
copy: 'An email address change was undone from the link sent to the previous address.',
|
|
358
|
+
},
|
|
359
|
+
account_recovery: {
|
|
360
|
+
trigger: 'account_owner',
|
|
361
|
+
reason: 'sessions_revoked',
|
|
362
|
+
copy: 'The account was recovered with a recovery key.',
|
|
363
|
+
},
|
|
364
|
+
reported_not_me: {
|
|
365
|
+
trigger: 'account_owner',
|
|
366
|
+
reason: 'sessions_revoked',
|
|
367
|
+
copy: 'A sign-in was reported as not you.',
|
|
368
|
+
},
|
|
369
|
+
sign_in_method_removed: {
|
|
370
|
+
trigger: 'account_owner',
|
|
371
|
+
reason: 'sign_in_method_removed',
|
|
372
|
+
copy: 'A sign-in method was removed, and the sessions that used it were ended.',
|
|
373
|
+
},
|
|
374
|
+
machine_removed: {
|
|
375
|
+
trigger: 'account_owner',
|
|
376
|
+
reason: 'machine_removed',
|
|
377
|
+
copy: 'A machine connection was removed, and the sessions it held were ended.',
|
|
378
|
+
},
|
|
379
|
+
oauth_app_revoked: {
|
|
380
|
+
trigger: 'account_owner',
|
|
381
|
+
reason: 'logged_out',
|
|
382
|
+
copy: 'Access for a connected application was revoked.',
|
|
383
|
+
},
|
|
384
|
+
session_limit: {
|
|
385
|
+
trigger: 'security_system',
|
|
386
|
+
reason: 'session_limit',
|
|
387
|
+
copy: 'The limit of signed-in sessions was reached, so the oldest session was ended.',
|
|
388
|
+
},
|
|
389
|
+
suspicious_reuse: {
|
|
390
|
+
trigger: 'security_system',
|
|
391
|
+
reason: 'security_check',
|
|
392
|
+
copy: 'A sign-in credential was presented twice, which can mean it was copied, so its sessions were ended.',
|
|
393
|
+
},
|
|
394
|
+
administrator: {
|
|
395
|
+
trigger: 'administrator',
|
|
396
|
+
reason: 'sessions_revoked',
|
|
397
|
+
copy: 'An administrator revoked the sessions.',
|
|
398
|
+
},
|
|
399
|
+
account_suspended: {
|
|
400
|
+
trigger: 'administrator',
|
|
401
|
+
reason: 'banned',
|
|
402
|
+
copy: 'An administrator suspended the account, which ends every session.',
|
|
403
|
+
},
|
|
404
|
+
external_provider: {
|
|
405
|
+
trigger: 'external_provider',
|
|
406
|
+
reason: 'sessions_revoked',
|
|
407
|
+
copy: 'Your sign-in provider reported a change to the account it vouches for.',
|
|
408
|
+
},
|
|
409
|
+
account_deletion_scheduled: {
|
|
410
|
+
trigger: 'account_owner',
|
|
411
|
+
reason: 'pending_deletion',
|
|
412
|
+
copy: 'Deletion of the account was requested.',
|
|
413
|
+
},
|
|
414
|
+
account_superseded: {
|
|
415
|
+
trigger: 'account_lifecycle',
|
|
416
|
+
reason: 'password_change',
|
|
417
|
+
copy: 'A new registration proved this email address and replaced the unverified account.',
|
|
418
|
+
},
|
|
419
|
+
unverified_account_cleanup: {
|
|
420
|
+
trigger: 'account_lifecycle',
|
|
421
|
+
reason: 'deleted',
|
|
422
|
+
copy: 'The unverified account was cleaned up.',
|
|
423
|
+
},
|
|
424
|
+
unknown: {
|
|
425
|
+
trigger: 'unknown',
|
|
426
|
+
reason: 'unknown',
|
|
427
|
+
copy: 'Sessions were revoked, and the server did not record why.',
|
|
428
|
+
},
|
|
429
|
+
});
|
|
430
|
+
export const SESSION_REVOCATION_TRIGGER_COPY = Object.freeze({
|
|
431
|
+
account_owner: 'Someone signed in to this account',
|
|
432
|
+
administrator: 'An administrator',
|
|
433
|
+
security_system: 'An automatic security measure',
|
|
434
|
+
external_provider: 'Your sign-in provider',
|
|
435
|
+
account_lifecycle: 'Account cleanup',
|
|
436
|
+
unknown: 'Unknown: the server could not tell who or what',
|
|
437
|
+
});
|
|
438
|
+
export function normalizeSessionRevocationCause(value) {
|
|
439
|
+
return typeof value === 'string' &&
|
|
440
|
+
SESSION_REVOCATION_CAUSES.includes(value)
|
|
441
|
+
? value
|
|
442
|
+
: 'unknown';
|
|
443
|
+
}
|
|
444
|
+
export function normalizeSessionRevocationTrigger(value) {
|
|
445
|
+
return typeof value === 'string' &&
|
|
446
|
+
SESSION_REVOCATION_TRIGGERS.includes(value)
|
|
447
|
+
? value
|
|
448
|
+
: 'unknown';
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* How Security activity explains one recorded revocation. A stored trigger wins
|
|
452
|
+
* over the cause's usual one (an administrator can change a password too); an
|
|
453
|
+
* unreadable one is `unknown`, never the cause's default.
|
|
454
|
+
*/
|
|
455
|
+
export function describeSessionRevocationActivity(record) {
|
|
456
|
+
const cause = normalizeSessionRevocationCause(record?.cause);
|
|
457
|
+
const trigger = record?.trigger === undefined || record?.trigger === null
|
|
458
|
+
? 'unknown'
|
|
459
|
+
: normalizeSessionRevocationTrigger(record.trigger);
|
|
460
|
+
const facts = SESSION_REVOCATION_CAUSE_FACTS[cause];
|
|
461
|
+
return {
|
|
462
|
+
cause,
|
|
463
|
+
trigger,
|
|
464
|
+
reason: facts.reason,
|
|
465
|
+
causeText: facts.copy,
|
|
466
|
+
triggerText: SESSION_REVOCATION_TRIGGER_COPY[trigger],
|
|
467
|
+
keys: {
|
|
468
|
+
cause: `com_nav_security_activity_revocation_cause_${cause}`,
|
|
469
|
+
trigger: `com_nav_security_activity_revocation_trigger_${trigger}`,
|
|
470
|
+
},
|
|
471
|
+
};
|
|
472
|
+
}
|
|
@@ -35,6 +35,13 @@
|
|
|
35
35
|
* `api/server/services/HostedPreview/__tests__/telemetryRedaction.spec.js` mints credentials with the real minting
|
|
36
36
|
* code and requires every one to come out as the marker, so a change to either side fails there.
|
|
37
37
|
*
|
|
38
|
+
* HUMAN QR SIGN-IN. Its locator has no token prefix, so redact only the known
|
|
39
|
+
* `/api/auth/qr/requests/<locator>` path and `/auth/qr?request=<locator>` query
|
|
40
|
+
* (including percent-encoded nested URLs). Private protocol field names are
|
|
41
|
+
* redacted in serialized text and structured records, including numeric
|
|
42
|
+
* comparison codes. Ordinary request ids, operation names and error/metric
|
|
43
|
+
* categories remain usable. All existing preview-redaction sinks inherit it.
|
|
44
|
+
*
|
|
38
45
|
* WHAT IT DOES NOT. A prefix that is itself percent-encoded (`%70vw_`) is not recognised: nothing in this
|
|
39
46
|
* repository writes one, and a scan that decoded every string first would cost every sink on every record. A
|
|
40
47
|
* credential cut off before its id is whole (`pinv_0123abc`) is an identifier, not yet the secret, and is left as it
|
|
@@ -50,6 +57,10 @@
|
|
|
50
57
|
*/
|
|
51
58
|
/** What replaces a token. Fixed, so a trace can say a preview was involved but not which one. */
|
|
52
59
|
export declare const PREVIEW_TOKEN_REDACTION: "pvw_[redacted]";
|
|
60
|
+
/** QR locators have no identifying prefix, so match only their protocol locations. */
|
|
61
|
+
export declare const QR_SIGN_IN_REDACTION: "[redacted]";
|
|
62
|
+
/** Fields are protocol-specific; preserve ordinary request ids, error codes and metrics. */
|
|
63
|
+
export declare function isQrSignInSecretField(key: string): boolean;
|
|
53
64
|
/**
|
|
54
65
|
* Replace every credential that travels in a URL with a marker: a Hosted Machine preview token with
|
|
55
66
|
* {@link PREVIEW_TOKEN_REDACTION}, and a workspace invitation, platform invitation, member link or operator code with
|
|
@@ -35,6 +35,13 @@
|
|
|
35
35
|
* `api/server/services/HostedPreview/__tests__/telemetryRedaction.spec.js` mints credentials with the real minting
|
|
36
36
|
* code and requires every one to come out as the marker, so a change to either side fails there.
|
|
37
37
|
*
|
|
38
|
+
* HUMAN QR SIGN-IN. Its locator has no token prefix, so redact only the known
|
|
39
|
+
* `/api/auth/qr/requests/<locator>` path and `/auth/qr?request=<locator>` query
|
|
40
|
+
* (including percent-encoded nested URLs). Private protocol field names are
|
|
41
|
+
* redacted in serialized text and structured records, including numeric
|
|
42
|
+
* comparison codes. Ordinary request ids, operation names and error/metric
|
|
43
|
+
* categories remain usable. All existing preview-redaction sinks inherit it.
|
|
44
|
+
*
|
|
38
45
|
* WHAT IT DOES NOT. A prefix that is itself percent-encoded (`%70vw_`) is not recognised: nothing in this
|
|
39
46
|
* repository writes one, and a scan that decoded every string first would cost every sink on every record. A
|
|
40
47
|
* credential cut off before its id is whole (`pinv_0123abc`) is an identifier, not yet the secret, and is left as it
|
|
@@ -82,14 +89,45 @@ const SIGNED_CREDENTIAL = new RegExp(`(wsi|pinv|usr|adm2)${UNDERSCORE}(?=[0-9a-f
|
|
|
82
89
|
* `TOKEN_CHAR`, whose dot would swallow the full stop at the end of a sentence.
|
|
83
90
|
*/
|
|
84
91
|
const LEGACY_OPERATOR_CODE = new RegExp(`(adm)${UNDERSCORE}(?=[A-Za-z0-9_-]{43}(?![A-Za-z0-9_-]))[A-Za-z0-9_-]{43}`, 'g');
|
|
85
|
-
/**
|
|
92
|
+
/** QR locators have no identifying prefix, so match only their protocol locations. */
|
|
93
|
+
export const QR_SIGN_IN_REDACTION = '[redacted]';
|
|
94
|
+
const escapedLiteral = (value) => [...value].map((char) => {
|
|
95
|
+
const literal = char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
96
|
+
return `(?:${literal}|%(?:25)*${char.charCodeAt(0).toString(16)})`;
|
|
97
|
+
}).join('');
|
|
98
|
+
const QR_REQUEST_PATH = new RegExp(`(${escapedLiteral('/api/auth/qr/requests/')})${TOKEN_CHAR}+`, 'gi');
|
|
99
|
+
const QR_LINK_QUERY = new RegExp(`(${escapedLiteral('/auth/qr?')})([^\\s"'<>#]*)`, 'gi');
|
|
100
|
+
const QR_REQUEST_QUERY = new RegExp(`(^|${escapedLiteral('&')})(${escapedLiteral('request')}${escapedLiteral('=')})${TOKEN_CHAR}+`, 'gi');
|
|
101
|
+
const QR_SECRET_FIELDS = new Set([
|
|
102
|
+
'statustoken', 'claimtoken', 'codeverifier', 'codechallenge', 'comparisoncode',
|
|
103
|
+
]);
|
|
104
|
+
/** Fields are protocol-specific; preserve ordinary request ids, error codes and metrics. */
|
|
105
|
+
export function isQrSignInSecretField(key) {
|
|
106
|
+
const leaf = key.split('.').pop() || '';
|
|
107
|
+
return QR_SECRET_FIELDS.has(leaf.replace(/[_-]/g, '').toLowerCase());
|
|
108
|
+
}
|
|
109
|
+
const QR_SECRET_ASSIGNMENT = /((?:["']?)(?:statusToken|claimToken|codeVerifier|codeChallenge|comparisonCode|status_token|claim_token|code_verifier|code_challenge|comparison_code)(?:["']?)\s*[:=]\s*["']?)([A-Za-z0-9._~%+-]+)/gi;
|
|
110
|
+
function redactQrSignInText(value) {
|
|
111
|
+
// Undici/Sentry may split url.query/query_string from its path. The QR's
|
|
112
|
+
// direction vocabulary identifies that standalone query without treating an
|
|
113
|
+
// ordinary application's `request` query key as a secret globally.
|
|
114
|
+
const standaloneQuery = /(?:^|[?&])direction=(?:mobile_approves_web|web_approves_mobile)(?:&|$)/.test(value)
|
|
115
|
+
? value.replace(QR_REQUEST_QUERY, `$1$2${QR_SIGN_IN_REDACTION}`) : value;
|
|
116
|
+
return standaloneQuery
|
|
117
|
+
.replace(QR_REQUEST_PATH, `$1${QR_SIGN_IN_REDACTION}`)
|
|
118
|
+
.replace(QR_LINK_QUERY, (_match, prefix, query) => prefix + query.replace(QR_REQUEST_QUERY, `$1$2${QR_SIGN_IN_REDACTION}`))
|
|
119
|
+
.replace(QR_SECRET_ASSIGNMENT, `$1${QR_SIGN_IN_REDACTION}`);
|
|
120
|
+
}
|
|
121
|
+
/** Cheap test before the older prefix-based credential expressions. */
|
|
86
122
|
const CREDENTIAL_HINTS = ['pvw', 'wsi', 'pinv', 'usr', 'adm'];
|
|
87
123
|
const credentialMarker = (_match, prefix) => `${prefix}_[redacted]`;
|
|
88
124
|
export function redactPreviewTokens(value) {
|
|
89
|
-
if (typeof value !== 'string'
|
|
125
|
+
if (typeof value !== 'string')
|
|
90
126
|
return value;
|
|
91
|
-
|
|
92
|
-
|
|
127
|
+
const qrSafe = redactQrSignInText(value);
|
|
128
|
+
if (!CREDENTIAL_HINTS.some((hint) => qrSafe.indexOf(hint) !== -1))
|
|
129
|
+
return qrSafe;
|
|
130
|
+
return qrSafe
|
|
93
131
|
.replace(PREVIEW_TOKEN, PREVIEW_TOKEN_REDACTION)
|
|
94
132
|
.replace(SIGNED_CREDENTIAL, credentialMarker)
|
|
95
133
|
.replace(LEGACY_OPERATOR_CODE, credentialMarker);
|
|
@@ -115,7 +153,7 @@ export function redactPreviewTokensDeep(root, limits = {}) {
|
|
|
115
153
|
let visited = 0;
|
|
116
154
|
let complete = true;
|
|
117
155
|
const rewrite = (holder, key, current) => {
|
|
118
|
-
const next = redactPreviewTokens(current);
|
|
156
|
+
const next = isQrSignInSecretField(key) ? QR_SIGN_IN_REDACTION : redactPreviewTokens(current);
|
|
119
157
|
if (next === current) {
|
|
120
158
|
return;
|
|
121
159
|
}
|
|
@@ -157,7 +195,7 @@ export function redactPreviewTokensDeep(root, limits = {}) {
|
|
|
157
195
|
complete = false;
|
|
158
196
|
continue;
|
|
159
197
|
}
|
|
160
|
-
if (typeof child === 'string') {
|
|
198
|
+
if (isQrSignInSecretField(key) || typeof child === 'string') {
|
|
161
199
|
rewrite(holder, key, child);
|
|
162
200
|
}
|
|
163
201
|
else if (child !== null && typeof child === 'object') {
|