1import * as NodeServices from "@effect/platform-node/NodeServices";
2import { assert, it } from "@effect/vitest";
3import * as Effect from "effect/Effect";
4import * as Layer from "effect/Layer";
5import * as Option from "effect/Option";
6
7import * as ServerSecretStore from "../auth/ServerSecretStore.ts";
8import * as ServerConfig from "../config.ts";
9import * as CliState from "./CliState.ts";
10import {
11 CLOUD_ENDPOINT_CONFIRMED_ORIGIN,
12 CLOUD_ENDPOINT_RUNTIME_CONFIG,
13 CLOUD_LINK_REVOKED,
14 CLOUD_LINKED_USER_ID,
15 CLOUD_MINT_PUBLIC_KEY,
16 PUBLISH_AGENT_ACTIVITY_SECRET,
17 RELAY_ENVIRONMENT_CREDENTIAL_SECRET,
18 RELAY_ISSUER_SECRET,
19 RELAY_URL_SECRET,
20} from "./config.ts";
21
22const persistedCloudLinkSecrets = [
23 CLOUD_LINKED_USER_ID,
24 RELAY_URL_SECRET,
25 RELAY_ISSUER_SECRET,
26 RELAY_ENVIRONMENT_CREDENTIAL_SECRET,
27 CLOUD_MINT_PUBLIC_KEY,
28 CLOUD_ENDPOINT_RUNTIME_CONFIG,
29 CLOUD_ENDPOINT_CONFIRMED_ORIGIN,
30 PUBLISH_AGENT_ACTIVITY_SECRET,
31] as const;
32
33const layerTest = () =>
34 ServerSecretStore.layer.pipe(
35 Layer.provide(
36 ServerConfig.layerTest(process.cwd(), {
37 prefix: "t3-cloud-cli-state-test-",
38 }),
39 ),
40 );
41
42it.layer(NodeServices.layer)("CliState", (it) => {
43 it.effect("persists desired exposure and clears provisioned relay state", () =>
44 Effect.gen(function* () {
45 const secrets = yield* ServerSecretStore.ServerSecretStore;
46
47 assert.isFalse(yield* CliState.readCliDesiredCloudLink);
48 yield* CliState.setCliDesiredCloudLink(true);
49 assert.isTrue(yield* CliState.readCliDesiredCloudLink);
50
51 for (const name of persistedCloudLinkSecrets) {
52 yield* secrets.set(name, new TextEncoder().encode(name));
53 }
54 yield* CliState.clearPersistedCloudLink;
55
56 assert.isFalse(yield* CliState.readCliDesiredCloudLink);
57 for (const name of persistedCloudLinkSecrets) {
58 assert.isTrue(Option.isNone(yield* secrets.get(name)));
59 }
60 }).pipe(Effect.provide(layerTest())),
61 );
62
63 it.effect("drops only a revoked link, keeping the sign-in and preferences", () =>
64 Effect.gen(function* () {
65 const secrets = yield* ServerSecretStore.ServerSecretStore;
66 const dropped = [
67 CLOUD_LINKED_USER_ID,
68 RELAY_ENVIRONMENT_CREDENTIAL_SECRET,
69 CLOUD_MINT_PUBLIC_KEY,
70 CLOUD_ENDPOINT_RUNTIME_CONFIG,
71 CLOUD_ENDPOINT_CONFIRMED_ORIGIN,
72 ];
73 const kept = [RELAY_URL_SECRET, PUBLISH_AGENT_ACTIVITY_SECRET];
74 for (const name of [...dropped, ...kept]) {
75 yield* secrets.set(name, new TextEncoder().encode(name));
76 }
77 yield* CliState.setCliDesiredCloudLink(true);
78
79 assert.isFalse(yield* CliState.dropRevokedCloudLink);
80 assert.isTrue(Option.isSome(yield* secrets.get(CLOUD_LINKED_USER_ID)));
81
82 yield* secrets.set(CLOUD_LINK_REVOKED, new TextEncoder().encode("true"));
83 assert.isTrue(yield* CliState.dropRevokedCloudLink);
84 for (const name of [...dropped, CLOUD_LINK_REVOKED]) {
85 assert.isTrue(Option.isNone(yield* secrets.get(name)));
86 }
87 for (const name of kept) {
88 assert.isTrue(Option.isSome(yield* secrets.get(name)));
89 }
90 assert.isTrue(yield* CliState.readCliDesiredCloudLink);
91 }).pipe(Effect.provide(layerTest())),
92 );
93
94 it.effect("round-trips the desired link mode and defaults legacy links to managed", () =>
95 Effect.gen(function* () {
96 const secrets = yield* ServerSecretStore.ServerSecretStore;
97
98 assert.equal(yield* CliState.readCliDesiredLinkMode, "managed");
99
100 yield* CliState.setCliDesiredCloudLink(true, "publish_only");
101 assert.isTrue(yield* CliState.readCliDesiredCloudLink);
102 assert.equal(yield* CliState.readCliDesiredLinkMode, "publish_only");
103
104 yield* CliState.setCliDesiredCloudLink(true, "managed");
105 assert.equal(yield* CliState.readCliDesiredLinkMode, "managed");
106
107 // A pre-existing link persisted the literal "true"; treat it as managed.
108 yield* secrets.set(CliState.CLOUD_CLI_DESIRED_LINK_SECRET, new TextEncoder().encode("true"));
109 assert.isTrue(yield* CliState.readCliDesiredCloudLink);
110 assert.equal(yield* CliState.readCliDesiredLinkMode, "managed");
111
112 yield* CliState.setCliDesiredCloudLink(false);
113 assert.equal(yield* CliState.readCliDesiredLinkMode, "managed");
114 }).pipe(Effect.provide(layerTest())),
115 );
116});