@settlemint/dalp-cli 3.1.32-main.42600267094 → 3.1.32-main.42608383459
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/dalp.js +41 -20
- package/dist/dalp.js.map +4 -4
- package/package.json +4 -4
- package/src/lib/credential-store.ts +50 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@settlemint/dalp-cli",
|
|
3
|
-
"version": "3.1.32-main.
|
|
3
|
+
"version": "3.1.32-main.42608383459",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "CLI for the Digital Asset Lifecycle Platform — manage tokens, identities, compliance, and more from the command line.",
|
|
6
6
|
"homepage": "https://settlemint.com",
|
|
@@ -50,14 +50,14 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@modelcontextprotocol/server": "2.4.0",
|
|
53
|
-
"@settlemint/dalp-sdk": "3.1.32-main.
|
|
53
|
+
"@settlemint/dalp-sdk": "3.1.32-main.42608383459",
|
|
54
54
|
"incur": "0.7.1",
|
|
55
55
|
"zod": "4.6.7"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@arethetypeswrong/cli": "0.18.5",
|
|
59
|
-
"@testkit/effect-bun-test": "3.1.32-main.
|
|
60
|
-
"@tools/typescript-config": "3.1.32-main.
|
|
59
|
+
"@testkit/effect-bun-test": "3.1.32-main.42608383459",
|
|
60
|
+
"@tools/typescript-config": "3.1.32-main.42608383459",
|
|
61
61
|
"@types/bun": "1.4.4",
|
|
62
62
|
"publint": "0.3.25"
|
|
63
63
|
},
|
|
@@ -8,6 +8,9 @@ const KEYCHAIN_ENTRY_SEPARATOR_PATTERN = /\n(?=keychain:)/u;
|
|
|
8
8
|
const ACCOUNT_PATTERN = /"acct"<blob>="([^"]*)"/u;
|
|
9
9
|
|
|
10
10
|
const SERVICE_NAME = "dalp-cli";
|
|
11
|
+
const SECURITY_INTERACTIVE_MAX_LINE_BYTES = 4094;
|
|
12
|
+
const SECURITY_QUOTED_ESCAPE_PATTERN = /["\\]/gu;
|
|
13
|
+
const SECURITY_LINE_BREAK_PATTERN = /[\n\r\0]/u;
|
|
11
14
|
|
|
12
15
|
const StoredCredentialsSchema = z.object({
|
|
13
16
|
apiKey: z.string().min(1),
|
|
@@ -24,14 +27,20 @@ export interface CredentialStoreOptions {
|
|
|
24
27
|
readonly configDir?: string;
|
|
25
28
|
readonly platform?: NodeJS.Platform;
|
|
26
29
|
readonly runSecurity?: (
|
|
27
|
-
args: ReadonlyArray<string
|
|
30
|
+
args: ReadonlyArray<string>,
|
|
31
|
+
stdin?: string
|
|
28
32
|
) => Promise<{ readonly exitCode: number; readonly stdout: string }>;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
const defaultRunSecurity = async (
|
|
32
|
-
args: ReadonlyArray<string
|
|
36
|
+
args: ReadonlyArray<string>,
|
|
37
|
+
stdin?: string
|
|
33
38
|
): Promise<{ readonly exitCode: number; readonly stdout: string }> => {
|
|
34
|
-
const proc = Bun.spawn(["security", ...args], {
|
|
39
|
+
const proc = Bun.spawn(["security", ...args], {
|
|
40
|
+
stdin: stdin === undefined ? "ignore" : new TextEncoder().encode(stdin),
|
|
41
|
+
stdout: "pipe",
|
|
42
|
+
stderr: "pipe",
|
|
43
|
+
});
|
|
35
44
|
const [stdout, exitCode] = await Promise.all([new Response(proc.stdout).text(), proc.exited]);
|
|
36
45
|
return { exitCode, stdout };
|
|
37
46
|
};
|
|
@@ -76,6 +85,43 @@ async function deleteKeychainAccount(
|
|
|
76
85
|
}
|
|
77
86
|
}
|
|
78
87
|
|
|
88
|
+
function quoteSecurityArgument(value: string): string {
|
|
89
|
+
return `"${value.replaceAll(SECURITY_QUOTED_ESCAPE_PATTERN, (character) => `\\${character}`)}"`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function addKeychainPassword(
|
|
93
|
+
runSecurity: NonNullable<CredentialStoreOptions["runSecurity"]>,
|
|
94
|
+
account: string,
|
|
95
|
+
password: string
|
|
96
|
+
): Promise<void> {
|
|
97
|
+
const command = [
|
|
98
|
+
"add-generic-password",
|
|
99
|
+
"-s",
|
|
100
|
+
quoteSecurityArgument(SERVICE_NAME),
|
|
101
|
+
"-a",
|
|
102
|
+
quoteSecurityArgument(account),
|
|
103
|
+
"-X",
|
|
104
|
+
Buffer.from(password, "utf8").toString("hex"),
|
|
105
|
+
"-U",
|
|
106
|
+
].join(" ");
|
|
107
|
+
if (
|
|
108
|
+
SECURITY_LINE_BREAK_PATTERN.test(account) ||
|
|
109
|
+
Buffer.byteLength(command, "utf8") > SECURITY_INTERACTIVE_MAX_LINE_BYTES
|
|
110
|
+
) {
|
|
111
|
+
throw makeCliError({
|
|
112
|
+
code: "kit.cli.CREDENTIAL_STORE_FAILED",
|
|
113
|
+
message: `The ${SERVICE_NAME} keychain item for ${JSON.stringify(account)} cannot be passed to the macOS security tool as one command line.`,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const result = await runSecurity(["-i"], `${command}\n`);
|
|
117
|
+
if (result.exitCode !== 0) {
|
|
118
|
+
throw makeCliError({
|
|
119
|
+
code: "kit.cli.CREDENTIAL_STORE_FAILED",
|
|
120
|
+
message: `Keychain save failed with exit code ${result.exitCode}`,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
79
125
|
function resolvePlatform(options: CredentialStoreOptions): NodeJS.Platform {
|
|
80
126
|
if (options.platform !== undefined) {
|
|
81
127
|
return options.platform;
|
|
@@ -99,22 +145,7 @@ export async function saveCredentials(
|
|
|
99
145
|
|
|
100
146
|
if (platform === "darwin") {
|
|
101
147
|
const existing = await keychainAccounts(runSecurity);
|
|
102
|
-
|
|
103
|
-
"add-generic-password",
|
|
104
|
-
"-s",
|
|
105
|
-
SERVICE_NAME,
|
|
106
|
-
"-a",
|
|
107
|
-
parsed.userEmail,
|
|
108
|
-
"-w",
|
|
109
|
-
encoded,
|
|
110
|
-
"-U",
|
|
111
|
-
]);
|
|
112
|
-
if (result.exitCode !== 0) {
|
|
113
|
-
throw makeCliError({
|
|
114
|
-
code: "kit.cli.CREDENTIAL_STORE_FAILED",
|
|
115
|
-
message: `Keychain save failed with exit code ${result.exitCode}`,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
148
|
+
await addKeychainPassword(runSecurity, parsed.userEmail, encoded);
|
|
118
149
|
try {
|
|
119
150
|
for (const account of existing.filter((name) => name !== parsed.userEmail)) {
|
|
120
151
|
await deleteKeychainAccount(runSecurity, account);
|