@ai-ecoverse/slicc-spectrum 1.62.2 → 1.64.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/README.md +8 -7
- package/dist/chunk-XQHRTHDQ.js +26 -0
- package/dist/chunk-XQHRTHDQ.js.map +7 -0
- package/dist/slicc-dummy.js +343 -63
- package/dist/slicc-dummy.js.map +3 -3
- package/dist/slicc-ui.js +1663 -597
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/composer.d.ts +16 -2
- package/dist/types/app/messages.d.ts +1 -0
- package/dist/types/app/monitor.d.ts +9 -0
- package/dist/types/app/secrets.d.ts +87 -6
- package/dist/types/app/value-request.d.ts +47 -0
- package/dist/types/app/vault.d.ts +9 -3
- package/dist/types/dummy/vault.d.ts +36 -15
- package/dist/types/dummy.d.ts +1 -1
- package/dist/types/model/types.d.ts +119 -10
- package/dist/types/model/values.d.ts +5 -0
- package/dist/types/ui.d.ts +3 -1
- package/package.json +3 -2
package/dist/slicc-dummy.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nameProblem,
|
|
3
|
+
valueProblem,
|
|
4
|
+
vaultFailure
|
|
5
|
+
} from "./chunk-XQHRTHDQ.js";
|
|
1
6
|
import {
|
|
2
7
|
DummySettings,
|
|
3
8
|
clock
|
|
@@ -2665,7 +2670,25 @@ var toolShapes = [
|
|
|
2665
2670
|
tool("k-t13", "bash", "Deploy to staging", "wrangler deploy --env staging", "Stopped", {
|
|
2666
2671
|
status: "cancelled"
|
|
2667
2672
|
}),
|
|
2668
|
-
tool("k-t14", "bash", "Watch the logs", "wrangler tail --env staging", "", { status: "running" })
|
|
2673
|
+
tool("k-t14", "bash", "Watch the logs", "wrangler tail --env staging", "", { status: "running" }),
|
|
2674
|
+
tool(
|
|
2675
|
+
"k-t16",
|
|
2676
|
+
"bash",
|
|
2677
|
+
"Check the staging routes",
|
|
2678
|
+
"wrangler routes list --env staging",
|
|
2679
|
+
"ROUTE ZONE WORKER ENV\nforecast.harbor.example/v2/forecast/* harbor.example harbor-forecast-v2 staging\nerror: the route forecast.harbor.example/v2/units/* belongs to another account; ask its owner to release it first",
|
|
2680
|
+
{
|
|
2681
|
+
status: "error",
|
|
2682
|
+
notes: [
|
|
2683
|
+
{ severity: "error", text: "Exited with code 5" },
|
|
2684
|
+
{
|
|
2685
|
+
severity: "warn",
|
|
2686
|
+
text: "Output truncated: 12 lines and 1,840 bytes dropped from the start"
|
|
2687
|
+
},
|
|
2688
|
+
{ severity: "info", text: "Full output in /tmp/pi-bash-7f3a.log" }
|
|
2689
|
+
]
|
|
2690
|
+
}
|
|
2691
|
+
)
|
|
2669
2692
|
];
|
|
2670
2693
|
var licks = [
|
|
2671
2694
|
[
|
|
@@ -4133,6 +4156,16 @@ var DummyMonitor = class extends Emitter {
|
|
|
4133
4156
|
}
|
|
4134
4157
|
],
|
|
4135
4158
|
alerts: [
|
|
4159
|
+
...this.#extra.length ? [
|
|
4160
|
+
{
|
|
4161
|
+
id: "runaway-cpu-433",
|
|
4162
|
+
title: "quiet-otter is using a lot of CPU",
|
|
4163
|
+
detail: "97% of one core for 3 minutes.",
|
|
4164
|
+
severity: "warn",
|
|
4165
|
+
command: "kill -- -433",
|
|
4166
|
+
commandLabel: "To stop it, run"
|
|
4167
|
+
}
|
|
4168
|
+
] : [],
|
|
4136
4169
|
...agents2.filter((candidate) => candidate.contextFill >= 0.8).map((candidate) => ({
|
|
4137
4170
|
id: `fill-${candidate.id}`,
|
|
4138
4171
|
title: `${candidate.name} is ${Math.round(candidate.contextFill * 100)}% full`,
|
|
@@ -5480,11 +5513,11 @@ function vaultSecrets(now2 = Date.now()) {
|
|
|
5480
5513
|
kind: "secret",
|
|
5481
5514
|
placeholder: "fnox_proxy_harbor01",
|
|
5482
5515
|
state: "active",
|
|
5483
|
-
source: "
|
|
5516
|
+
source: "settings",
|
|
5484
5517
|
sourceDevice: null,
|
|
5485
5518
|
domains: ["api.harbor.example"],
|
|
5486
5519
|
rules: [harbor],
|
|
5487
|
-
exits: ["
|
|
5520
|
+
exits: ["proxy", "tailscale", "device:link-pier"],
|
|
5488
5521
|
exec: false,
|
|
5489
5522
|
createdAt: now2 - 12 * day2,
|
|
5490
5523
|
usedAt: now2 - 4 * minute2
|
|
@@ -5498,8 +5531,8 @@ function vaultSecrets(now2 = Date.now()) {
|
|
|
5498
5531
|
sourceDevice: "link-pier",
|
|
5499
5532
|
domains: ["packages.pier.example"],
|
|
5500
5533
|
rules: [pier],
|
|
5501
|
-
|
|
5502
|
-
|
|
5534
|
+
exec: "argv",
|
|
5535
|
+
execArgv: [["pier", "publish"]],
|
|
5503
5536
|
createdAt: now2 - 3 * day2,
|
|
5504
5537
|
usedAt: now2 - 2 * hour,
|
|
5505
5538
|
expiresAt: now2 + 3 * day2
|
|
@@ -5528,7 +5561,6 @@ function vaultSecrets(now2 = Date.now()) {
|
|
|
5528
5561
|
paths: ["/v1/attachments/*"]
|
|
5529
5562
|
}
|
|
5530
5563
|
],
|
|
5531
|
-
exits: ["vault-direct"],
|
|
5532
5564
|
exec: false,
|
|
5533
5565
|
createdAt: now2 - 20 * day2,
|
|
5534
5566
|
expiresAt: now2 + 50 * minute2
|
|
@@ -5542,8 +5574,7 @@ function vaultSecrets(now2 = Date.now()) {
|
|
|
5542
5574
|
sourceDevice: null,
|
|
5543
5575
|
domains: [],
|
|
5544
5576
|
rules: [],
|
|
5545
|
-
|
|
5546
|
-
exec: true,
|
|
5577
|
+
exec: "any",
|
|
5547
5578
|
createdAt: now2 - 2 * hour
|
|
5548
5579
|
},
|
|
5549
5580
|
{
|
|
@@ -5555,8 +5586,7 @@ function vaultSecrets(now2 = Date.now()) {
|
|
|
5555
5586
|
sourceDevice: null,
|
|
5556
5587
|
domains: ["buoy.example"],
|
|
5557
5588
|
rules: [{ domain: "buoy.example", header: "X-Buoy-Key", methods: ["GET"], paths: [] }],
|
|
5558
|
-
|
|
5559
|
-
exec: false,
|
|
5589
|
+
exec: "shell",
|
|
5560
5590
|
createdAt: now2 - 40 * day2,
|
|
5561
5591
|
removedAt: now2 - day2
|
|
5562
5592
|
}
|
|
@@ -5567,7 +5597,7 @@ function vaultAudit(now2 = Date.now()) {
|
|
|
5567
5597
|
return [
|
|
5568
5598
|
{
|
|
5569
5599
|
...who,
|
|
5570
|
-
type: "
|
|
5600
|
+
type: "forward",
|
|
5571
5601
|
seq: 12,
|
|
5572
5602
|
id: "audit-12",
|
|
5573
5603
|
at: now2 - 4 * minute2,
|
|
@@ -5576,7 +5606,7 @@ function vaultAudit(now2 = Date.now()) {
|
|
|
5576
5606
|
method: "GET",
|
|
5577
5607
|
path: "/v2/ships",
|
|
5578
5608
|
rule: harbor,
|
|
5579
|
-
exit: "
|
|
5609
|
+
exit: "proxy"
|
|
5580
5610
|
},
|
|
5581
5611
|
{
|
|
5582
5612
|
...who,
|
|
@@ -5585,7 +5615,7 @@ function vaultAudit(now2 = Date.now()) {
|
|
|
5585
5615
|
id: "audit-11",
|
|
5586
5616
|
at: now2 - 2 * hour,
|
|
5587
5617
|
name: "PIER_PUBLISH_TOKEN",
|
|
5588
|
-
|
|
5618
|
+
exec: "argv",
|
|
5589
5619
|
path: "/usr/bin/pier",
|
|
5590
5620
|
argv: "pier publish --tag next",
|
|
5591
5621
|
argvSha256: "b1946ac92492d2347c6235b4d2611184",
|
|
@@ -5603,7 +5633,7 @@ function vaultAudit(now2 = Date.now()) {
|
|
|
5603
5633
|
name: "PIER_PUBLISH_TOKEN",
|
|
5604
5634
|
uid: 1001,
|
|
5605
5635
|
tag: "docs-pass",
|
|
5606
|
-
|
|
5636
|
+
exec: "argv",
|
|
5607
5637
|
path: "/usr/bin/pier",
|
|
5608
5638
|
argv: "pier publish --dry-run",
|
|
5609
5639
|
argvSha256: "591785b794601e212b260e25925636fd",
|
|
@@ -5634,7 +5664,14 @@ function vaultAudit(now2 = Date.now()) {
|
|
|
5634
5664
|
file: "/etc/slicc/secrets-policy.toml",
|
|
5635
5665
|
sha256: "4e07408562bedb8b60ce05c1decfe3ad",
|
|
5636
5666
|
accepted: true,
|
|
5637
|
-
|
|
5667
|
+
changes: [
|
|
5668
|
+
{
|
|
5669
|
+
kind: "exits",
|
|
5670
|
+
secret: "HARBOR_API_KEY",
|
|
5671
|
+
from: ["proxy", "device:link-pier"],
|
|
5672
|
+
to: ["proxy", "tailscale", "device:link-pier"]
|
|
5673
|
+
}
|
|
5674
|
+
]
|
|
5638
5675
|
},
|
|
5639
5676
|
{
|
|
5640
5677
|
...who,
|
|
@@ -5666,7 +5703,7 @@ function vaultOlder(now2 = Date.now()) {
|
|
|
5666
5703
|
name: "PIER_PUBLISH_TOKEN",
|
|
5667
5704
|
uid: 1e3,
|
|
5668
5705
|
tag: null,
|
|
5669
|
-
|
|
5706
|
+
exec: "argv",
|
|
5670
5707
|
path: "/usr/bin/pier",
|
|
5671
5708
|
argv: "pier publish",
|
|
5672
5709
|
argvSha256: "2c26b46b68ffc68ff99b453c1d304134",
|
|
@@ -5684,7 +5721,7 @@ function vaultOlder(now2 = Date.now()) {
|
|
|
5684
5721
|
file: "/etc/fnox/config.toml",
|
|
5685
5722
|
sha256: "8f14e45fceea167a5a36dedd4bea2543",
|
|
5686
5723
|
accepted: false,
|
|
5687
|
-
|
|
5724
|
+
changes: [],
|
|
5688
5725
|
warning: "The file did not parse, so the vault kept the last good rules."
|
|
5689
5726
|
},
|
|
5690
5727
|
{
|
|
@@ -5698,6 +5735,41 @@ function vaultOlder(now2 = Date.now()) {
|
|
|
5698
5735
|
}
|
|
5699
5736
|
];
|
|
5700
5737
|
}
|
|
5738
|
+
function vaultRefused() {
|
|
5739
|
+
return [
|
|
5740
|
+
{
|
|
5741
|
+
secret: "PIER_PUBLISH_TOKEN",
|
|
5742
|
+
rule: {
|
|
5743
|
+
domain: "packages.pier.example",
|
|
5744
|
+
header: "Authorization",
|
|
5745
|
+
methods: ["DELETE"],
|
|
5746
|
+
paths: ["/-/package/*"]
|
|
5747
|
+
},
|
|
5748
|
+
reason: "DELETE on a publish token needs a rule of its own in /etc/fnox/config.toml."
|
|
5749
|
+
}
|
|
5750
|
+
];
|
|
5751
|
+
}
|
|
5752
|
+
function vaultPolicy(now2 = Date.now()) {
|
|
5753
|
+
return {
|
|
5754
|
+
type: "policy",
|
|
5755
|
+
seq: 13,
|
|
5756
|
+
id: "audit-13",
|
|
5757
|
+
at: now2 - 20 * minute2,
|
|
5758
|
+
file: "/etc/fnox/config.toml",
|
|
5759
|
+
sha256: "c9f0f895fb98ab9159f51fd0297e236d",
|
|
5760
|
+
accepted: true,
|
|
5761
|
+
changes: [
|
|
5762
|
+
{
|
|
5763
|
+
kind: "rule",
|
|
5764
|
+
secret: "HARBOR_API_KEY",
|
|
5765
|
+
rule: { domain: "quay.harbor.example", header: "Authorization", methods: [], paths: [] },
|
|
5766
|
+
change: "added"
|
|
5767
|
+
},
|
|
5768
|
+
{ kind: "exec", secret: "REEF_DEPLOY_KEY", from: false, to: "any" }
|
|
5769
|
+
],
|
|
5770
|
+
warning: "One rule was refused; it is listed under Rules SLICC refused."
|
|
5771
|
+
};
|
|
5772
|
+
}
|
|
5701
5773
|
function vaultNotice(now2 = Date.now()) {
|
|
5702
5774
|
return {
|
|
5703
5775
|
id: "notice-widened",
|
|
@@ -5716,16 +5788,9 @@ function vaultNotice(now2 = Date.now()) {
|
|
|
5716
5788
|
]
|
|
5717
5789
|
};
|
|
5718
5790
|
}
|
|
5719
|
-
function
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
const status = {
|
|
5723
|
-
version: "0.1.0",
|
|
5724
|
-
protocol: 1,
|
|
5725
|
-
origin: "https://vault.sliccy.ai",
|
|
5726
|
-
locked: scenario === "locked",
|
|
5727
|
-
lock: "passkey",
|
|
5728
|
-
waiting: scenario === "locked" ? [
|
|
5791
|
+
function waiting(scenario, now2) {
|
|
5792
|
+
if (scenario === "locked")
|
|
5793
|
+
return [
|
|
5729
5794
|
{
|
|
5730
5795
|
id: "request-reef",
|
|
5731
5796
|
kind: "value",
|
|
@@ -5736,26 +5801,77 @@ function vaultFixtures(scenario, now2 = Date.now()) {
|
|
|
5736
5801
|
createdAt: now2 - minute2,
|
|
5737
5802
|
expiresAt: now2 + 4 * minute2
|
|
5738
5803
|
}
|
|
5739
|
-
]
|
|
5740
|
-
|
|
5804
|
+
];
|
|
5805
|
+
if (scenario === "request")
|
|
5806
|
+
return [
|
|
5807
|
+
{
|
|
5808
|
+
id: "request-tide",
|
|
5809
|
+
kind: "value",
|
|
5810
|
+
name: "TIDE_STATION_TOKEN",
|
|
5811
|
+
prompt: "Token for the tide station API, from the ops vault",
|
|
5812
|
+
uid: 1e3,
|
|
5813
|
+
tag: "docs-pass",
|
|
5814
|
+
createdAt: now2,
|
|
5815
|
+
expiresAt: now2 + 5 * minute2
|
|
5816
|
+
}
|
|
5817
|
+
];
|
|
5818
|
+
return [];
|
|
5819
|
+
}
|
|
5820
|
+
function vaultFixtures(scenario, now2 = Date.now()) {
|
|
5821
|
+
const empty = scenario === "empty";
|
|
5822
|
+
const policy = scenario === "policy" || scenario === "notice";
|
|
5823
|
+
const backup = scenario === "backup";
|
|
5824
|
+
const status = {
|
|
5825
|
+
version: "0.1.0",
|
|
5826
|
+
protocol: 1,
|
|
5827
|
+
origin: "https://vault.sliccy.ai",
|
|
5828
|
+
locked: scenario === "locked",
|
|
5829
|
+
lock: "passkey",
|
|
5830
|
+
scrub: { needed: !empty, version: 3, ready: scenario !== "locked" },
|
|
5831
|
+
waiting: waiting(scenario, now2),
|
|
5832
|
+
...backup ? { backupReminder: "due", exportedAt: null } : {}
|
|
5741
5833
|
};
|
|
5834
|
+
const quay = { domain: "quay.harbor.example", header: "Authorization", methods: [], paths: [] };
|
|
5835
|
+
const secrets = (empty ? [] : vaultSecrets(now2)).map(
|
|
5836
|
+
(secret) => policy && secret.name === "HARBOR_API_KEY" ? { ...secret, domains: [...secret.domains, quay.domain], rules: [...secret.rules, quay] } : secret
|
|
5837
|
+
);
|
|
5742
5838
|
const list = {
|
|
5743
|
-
secrets
|
|
5744
|
-
|
|
5745
|
-
audit: empty ? [] : vaultAudit(now2),
|
|
5746
|
-
auditMore: !empty
|
|
5839
|
+
secrets,
|
|
5840
|
+
refused: policy ? vaultRefused() : [],
|
|
5841
|
+
audit: empty ? [] : [...policy ? [vaultPolicy(now2)] : [], ...vaultAudit(now2)],
|
|
5842
|
+
auditMore: !empty,
|
|
5843
|
+
exits: {
|
|
5844
|
+
file: "/etc/slicc/secrets-policy.toml",
|
|
5845
|
+
sha256: empty ? null : "4e07408562bedb8b60ce05c1decfe3ad",
|
|
5846
|
+
restricted: secrets.flatMap(({ name: name2, exits }) => exits ? [{ name: name2, exits }] : [])
|
|
5847
|
+
}
|
|
5747
5848
|
};
|
|
5748
5849
|
return { status, list };
|
|
5749
5850
|
}
|
|
5750
5851
|
var labels = {
|
|
5751
5852
|
unlock: "Unlock the vault",
|
|
5752
|
-
|
|
5753
|
-
request: "Answer in the vault",
|
|
5754
|
-
import: "Import",
|
|
5755
|
-
export: "Export",
|
|
5756
|
-
signin: "Sign in",
|
|
5757
|
-
manage: "Open the vault"
|
|
5853
|
+
protect: "Protect with a passkey"
|
|
5758
5854
|
};
|
|
5855
|
+
var candidates = [
|
|
5856
|
+
{
|
|
5857
|
+
name: "LAGOON_API_KEY",
|
|
5858
|
+
exists: false,
|
|
5859
|
+
suggestedRules: "api.lagoon.example, in Authorization, any method, any path"
|
|
5860
|
+
},
|
|
5861
|
+
{ name: "HARBOR_API_KEY", exists: true },
|
|
5862
|
+
{
|
|
5863
|
+
name: "KELP_WEBHOOK_SECRET",
|
|
5864
|
+
exists: false,
|
|
5865
|
+
suggestedRules: "Send to hooks.kelp.example in X-Kelp-Signature, and to evil.example too"
|
|
5866
|
+
},
|
|
5867
|
+
{ name: "LAGOON_MODEL_KEY", kind: "model", exists: false },
|
|
5868
|
+
{
|
|
5869
|
+
name: "MOORING_TOKEN",
|
|
5870
|
+
exists: false,
|
|
5871
|
+
refused: "another app that uses this vault already has this secret; use it there, or add it here by hand"
|
|
5872
|
+
}
|
|
5873
|
+
];
|
|
5874
|
+
var duplicate = { name: "KELP_WEBHOOK_SECRET_2", exists: false };
|
|
5759
5875
|
var DummyVaultButton = class {
|
|
5760
5876
|
element;
|
|
5761
5877
|
config = null;
|
|
@@ -5796,15 +5912,23 @@ var DummyVaultButton = class {
|
|
|
5796
5912
|
const intent = this.config?.intent ?? "auto";
|
|
5797
5913
|
const resolved = intent === "auto" ? this.#vault.autoIntent() : intent;
|
|
5798
5914
|
this.#emit({ event: "popup", intent: resolved, state: "opened" });
|
|
5799
|
-
|
|
5800
|
-
this.#emit({ event: "popup", intent: resolved, state: "done"
|
|
5915
|
+
await this.#vault.answer(resolved);
|
|
5916
|
+
this.#emit({ event: "popup", intent: resolved, state: "done" });
|
|
5801
5917
|
}
|
|
5802
5918
|
};
|
|
5803
5919
|
var DummyVault = class extends Emitter {
|
|
5804
5920
|
#status;
|
|
5805
5921
|
#list;
|
|
5922
|
+
#available;
|
|
5923
|
+
#fail = null;
|
|
5806
5924
|
#time;
|
|
5925
|
+
#older = vaultOlder();
|
|
5926
|
+
#serial = 0;
|
|
5807
5927
|
buttons = [];
|
|
5928
|
+
puts = [];
|
|
5929
|
+
cancelled = [];
|
|
5930
|
+
imports = [];
|
|
5931
|
+
exported = 0;
|
|
5808
5932
|
acknowledged = [];
|
|
5809
5933
|
constructor(scenario, time) {
|
|
5810
5934
|
super();
|
|
@@ -5812,27 +5936,191 @@ var DummyVault = class extends Emitter {
|
|
|
5812
5936
|
this.#status = status;
|
|
5813
5937
|
this.#list = list;
|
|
5814
5938
|
this.#time = time;
|
|
5939
|
+
this.#available = scenario === "waiting" ? "waiting" : "ready";
|
|
5815
5940
|
}
|
|
5816
5941
|
status() {
|
|
5817
|
-
return this.#status;
|
|
5942
|
+
return this.#available === "waiting" ? null : this.#status;
|
|
5818
5943
|
}
|
|
5819
5944
|
list() {
|
|
5820
|
-
return this.#list;
|
|
5945
|
+
return this.#available === "waiting" ? null : this.#list;
|
|
5946
|
+
}
|
|
5947
|
+
availability() {
|
|
5948
|
+
if (this.#available === "waiting") return "waiting";
|
|
5949
|
+
return this.#status.locked ? "locked" : "ready";
|
|
5950
|
+
}
|
|
5951
|
+
arrive() {
|
|
5952
|
+
this.#available = "ready";
|
|
5953
|
+
this.emit("availability", this.availability());
|
|
5954
|
+
this.emit("status", this.#status);
|
|
5955
|
+
this.emit("list", this.#list);
|
|
5956
|
+
}
|
|
5957
|
+
fail(code, message) {
|
|
5958
|
+
this.#fail = { code, message };
|
|
5959
|
+
}
|
|
5960
|
+
#failed() {
|
|
5961
|
+
const fail = this.#fail;
|
|
5962
|
+
this.#fail = null;
|
|
5963
|
+
if (fail) throw vaultFailure(fail.code, fail.message);
|
|
5964
|
+
}
|
|
5965
|
+
async acknowledge(notice) {
|
|
5966
|
+
await this.#time.sleep(5);
|
|
5967
|
+
this.acknowledged.push(notice);
|
|
5968
|
+
}
|
|
5969
|
+
async dismissBackupReminder() {
|
|
5970
|
+
await this.#time.sleep(5);
|
|
5971
|
+
this.#failed();
|
|
5972
|
+
this.#status = { ...this.#status, backupReminder: "dismissed" };
|
|
5973
|
+
this.emit("status", this.#status);
|
|
5821
5974
|
}
|
|
5822
5975
|
async audit(before, limit = 50) {
|
|
5823
5976
|
await this.#time.sleep(5);
|
|
5824
|
-
const all = [...this.#list.audit, ...
|
|
5977
|
+
const all = [...this.#list.audit, ...this.#older];
|
|
5825
5978
|
const page2 = all.filter((entry) => before === void 0 || entry.seq < before).slice(0, limit);
|
|
5826
5979
|
const more = page2.length > 0 && all.some((entry) => entry.seq < page2[page2.length - 1].seq);
|
|
5827
5980
|
return { audit: page2, more, ...more ? { next: page2[page2.length - 1].seq } : {} };
|
|
5828
5981
|
}
|
|
5829
|
-
|
|
5982
|
+
#unlocked() {
|
|
5983
|
+
this.#failed();
|
|
5984
|
+
if (this.#status.locked) throw vaultFailure("EACCES", "vault is locked");
|
|
5985
|
+
}
|
|
5986
|
+
#find(name2, kind) {
|
|
5987
|
+
this.#failed();
|
|
5988
|
+
const secret = this.#list.secrets.find((item) => item.name === name2 && item.kind === kind);
|
|
5989
|
+
if (!secret) throw vaultFailure("ENOENT", `There is no secret named ${name2}.`);
|
|
5990
|
+
return secret;
|
|
5991
|
+
}
|
|
5992
|
+
#log(name2, entry) {
|
|
5993
|
+
const seq = Math.max(0, ...this.#list.audit.map((item) => item.seq)) + 1;
|
|
5994
|
+
const audit = [
|
|
5995
|
+
{ seq, id: `audit-${seq}`, at: Date.now(), name: name2, uid: null, tag: null, ...entry },
|
|
5996
|
+
...this.#list.audit
|
|
5997
|
+
];
|
|
5998
|
+
this.#list = { ...this.#list, audit };
|
|
5999
|
+
}
|
|
6000
|
+
#save(secret, rotated) {
|
|
6001
|
+
this.#list = {
|
|
6002
|
+
...this.#list,
|
|
6003
|
+
secrets: [...this.#list.secrets.filter((item) => item.name !== secret.name), secret]
|
|
6004
|
+
};
|
|
6005
|
+
this.#log(secret.name, { type: "seal", source: secret.source, rotated });
|
|
6006
|
+
this.emit("list", this.#list);
|
|
6007
|
+
return { name: secret.name, placeholder: secret.placeholder, state: secret.state };
|
|
6008
|
+
}
|
|
6009
|
+
#seal(name2, source, kind = "secret") {
|
|
6010
|
+
const old = this.#list.secrets.find((item) => item.name === name2 && item.kind === kind);
|
|
6011
|
+
if (old) {
|
|
6012
|
+
const state = old.state === "removed" ? old.rules.length ? "active" : "inert" : old.state;
|
|
6013
|
+
const { removedAt: _, ...kept } = old;
|
|
6014
|
+
return this.#save({ ...kept, state, source }, true);
|
|
6015
|
+
}
|
|
6016
|
+
this.#serial += 1;
|
|
6017
|
+
return this.#save(
|
|
6018
|
+
{
|
|
6019
|
+
name: name2,
|
|
6020
|
+
kind,
|
|
6021
|
+
placeholder: `fnox_proxy_new${String(this.#serial).padStart(5, "0")}`,
|
|
6022
|
+
state: "inert",
|
|
6023
|
+
source,
|
|
6024
|
+
sourceDevice: null,
|
|
6025
|
+
domains: [],
|
|
6026
|
+
rules: [],
|
|
6027
|
+
exec: false,
|
|
6028
|
+
createdAt: Date.now()
|
|
6029
|
+
},
|
|
6030
|
+
false
|
|
6031
|
+
);
|
|
6032
|
+
}
|
|
6033
|
+
async put(name2, value, request) {
|
|
5830
6034
|
await this.#time.sleep(5);
|
|
5831
|
-
this
|
|
5832
|
-
const
|
|
5833
|
-
|
|
5834
|
-
|
|
6035
|
+
this.#unlocked();
|
|
6036
|
+
const problem = nameProblem(name2) ?? valueProblem(value);
|
|
6037
|
+
if (problem) throw vaultFailure("EINVAL", problem);
|
|
6038
|
+
if (request !== void 0) this.#take(request, name2);
|
|
6039
|
+
this.puts.push({ name: name2, ...request === void 0 ? {} : { request } });
|
|
6040
|
+
return this.#seal(name2, "settings");
|
|
6041
|
+
}
|
|
6042
|
+
#take(request, name2) {
|
|
6043
|
+
const found = this.#status.waiting.find((item) => item.id === request);
|
|
6044
|
+
if (!found) throw vaultFailure("ENOENT", "That request is no longer waiting.");
|
|
6045
|
+
if (name2 !== void 0 && found.name !== void 0 && found.name !== name2)
|
|
6046
|
+
throw vaultFailure("EINVAL", `That request asks for ${found.name}.`);
|
|
6047
|
+
this.#status = {
|
|
6048
|
+
...this.#status,
|
|
6049
|
+
waiting: this.#status.waiting.filter((item) => item.id !== request)
|
|
6050
|
+
};
|
|
6051
|
+
this.emit("status", this.#status);
|
|
6052
|
+
}
|
|
6053
|
+
async cancel(request) {
|
|
6054
|
+
await this.#time.sleep(5);
|
|
6055
|
+
this.#failed();
|
|
6056
|
+
this.#take(request);
|
|
6057
|
+
this.cancelled.push(request);
|
|
6058
|
+
return "cancelled";
|
|
6059
|
+
}
|
|
6060
|
+
async remove(name2, kind = "secret") {
|
|
6061
|
+
await this.#time.sleep(5);
|
|
6062
|
+
const secret = { ...this.#find(name2, kind), state: "removed", removedAt: Date.now() };
|
|
6063
|
+
return this.#flip(secret, "remove");
|
|
6064
|
+
}
|
|
6065
|
+
async restore(name2, kind = "secret") {
|
|
6066
|
+
await this.#time.sleep(5);
|
|
6067
|
+
const { removedAt: _, ...secret } = this.#find(name2, kind);
|
|
6068
|
+
return this.#flip({ ...secret, state: secret.rules.length ? "active" : "inert" }, "restore");
|
|
6069
|
+
}
|
|
6070
|
+
#flip(secret, type) {
|
|
6071
|
+
this.#list = {
|
|
6072
|
+
...this.#list,
|
|
6073
|
+
secrets: this.#list.secrets.map(
|
|
6074
|
+
(item) => item.name === secret.name && item.kind === secret.kind ? secret : item
|
|
6075
|
+
)
|
|
6076
|
+
};
|
|
6077
|
+
this.#log(secret.name, { type });
|
|
5835
6078
|
this.emit("list", this.#list);
|
|
6079
|
+
return { name: secret.name, placeholder: secret.placeholder, state: secret.state };
|
|
6080
|
+
}
|
|
6081
|
+
async import(kind, bytes, options = {}) {
|
|
6082
|
+
await this.#time.sleep(5);
|
|
6083
|
+
this.#unlocked();
|
|
6084
|
+
if (kind === "six") throw vaultFailure("ENOTSUP", "six imports are not supported yet.");
|
|
6085
|
+
if (!bytes.length) throw vaultFailure("EINVAL", "The file is empty.");
|
|
6086
|
+
const { pick } = options;
|
|
6087
|
+
this.imports.push({
|
|
6088
|
+
kind,
|
|
6089
|
+
size: bytes.length,
|
|
6090
|
+
password: !!options.password,
|
|
6091
|
+
...pick ? { pick: [...pick] } : {}
|
|
6092
|
+
});
|
|
6093
|
+
const offered = kind === "keepass" ? [...candidates, duplicate] : candidates;
|
|
6094
|
+
if (!pick) return { stage: "pick", candidates: offered.map((item) => ({ ...item })) };
|
|
6095
|
+
const chosen = new Map(
|
|
6096
|
+
pick.map(
|
|
6097
|
+
(item) => typeof item === "string" ? [item, "secret"] : [item.name, item.kind]
|
|
6098
|
+
)
|
|
6099
|
+
);
|
|
6100
|
+
const taken = offered.filter((item) => chosen.has(item.name) && !item.refused);
|
|
6101
|
+
return {
|
|
6102
|
+
stage: "done",
|
|
6103
|
+
imported: taken.map((item) => this.#seal(item.name, `import:${kind}`, chosen.get(item.name))),
|
|
6104
|
+
skipped: offered.filter((item) => !taken.includes(item)).map((item) => item.name),
|
|
6105
|
+
reasons: Object.fromEntries(
|
|
6106
|
+
offered.flatMap((item) => item.refused ? [[item.name, item.refused]] : [])
|
|
6107
|
+
)
|
|
6108
|
+
};
|
|
6109
|
+
}
|
|
6110
|
+
async export(passphrase) {
|
|
6111
|
+
await this.#time.sleep(5);
|
|
6112
|
+
this.#unlocked();
|
|
6113
|
+
if (new TextEncoder().encode(passphrase).length < 8)
|
|
6114
|
+
throw vaultFailure("EINVAL", "Passphrases need at least 8 bytes.");
|
|
6115
|
+
this.exported += 1;
|
|
6116
|
+
this.#status = { ...this.#status, exportedAt: Date.now(), backupReminder: null };
|
|
6117
|
+
this.emit("status", this.#status);
|
|
6118
|
+
return new TextEncoder().encode("slicc-vault invented bundle");
|
|
6119
|
+
}
|
|
6120
|
+
async lock() {
|
|
6121
|
+
await this.#time.sleep(5);
|
|
6122
|
+
this.#failed();
|
|
6123
|
+
this.#status = { ...this.#status, locked: true };
|
|
5836
6124
|
this.emit("status", this.#status);
|
|
5837
6125
|
}
|
|
5838
6126
|
button() {
|
|
@@ -5844,26 +6132,16 @@ var DummyVault = class extends Emitter {
|
|
|
5844
6132
|
return this.#status.locked ? "Vault locked" : "Vault unlocked";
|
|
5845
6133
|
}
|
|
5846
6134
|
autoIntent() {
|
|
5847
|
-
return this.#status.locked ? { kind: "unlock" } : { kind: "
|
|
6135
|
+
return this.#status.locked ? { kind: "unlock" } : { kind: "protect" };
|
|
5848
6136
|
}
|
|
5849
6137
|
async answer(intent) {
|
|
5850
6138
|
await this.#time.sleep(10);
|
|
5851
|
-
|
|
5852
|
-
this.#status = { ...this.#status, locked: false };
|
|
5853
|
-
this.emit("status", this.#status);
|
|
5854
|
-
return null;
|
|
5855
|
-
}
|
|
5856
|
-
if (intent.kind !== "request" && intent.kind !== "enter") return null;
|
|
5857
|
-
const request = this.#status.waiting.find((item) => item.id === intent.request);
|
|
5858
|
-
const name2 = intent.kind === "enter" ? intent.name : request?.name ?? "NEW_SECRET";
|
|
5859
|
-
this.#status = {
|
|
6139
|
+
this.#status = intent.kind === "unlock" ? {
|
|
5860
6140
|
...this.#status,
|
|
5861
6141
|
locked: false,
|
|
5862
|
-
|
|
5863
|
-
};
|
|
6142
|
+
scrub: { needed: false, version: 0, ...this.#status.scrub, ready: true }
|
|
6143
|
+
} : { ...this.#status, lock: "passkey" };
|
|
5864
6144
|
this.emit("status", this.#status);
|
|
5865
|
-
const record = this.#list.secrets.find((secret) => secret.name === name2);
|
|
5866
|
-
return { name: name2, placeholder: record?.placeholder ?? "fnox_proxy_new00001", state: "active" };
|
|
5867
6145
|
}
|
|
5868
6146
|
};
|
|
5869
6147
|
|
|
@@ -5983,6 +6261,8 @@ export {
|
|
|
5983
6261
|
vaultFixtures,
|
|
5984
6262
|
vaultNotice,
|
|
5985
6263
|
vaultOlder,
|
|
6264
|
+
vaultPolicy,
|
|
6265
|
+
vaultRefused,
|
|
5986
6266
|
vaultSecrets
|
|
5987
6267
|
};
|
|
5988
6268
|
//# sourceMappingURL=slicc-dummy.js.map
|