@ascendkit/cli 0.3.11 → 0.3.13
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/cli.js +39 -15
- package/dist/commands/auth.d.ts +3 -1
- package/dist/commands/auth.js +6 -5
- package/dist/commands/platform.js +5 -2
- package/dist/tools/auth.js +37 -2
- package/dist/tools/platform.js +8 -8
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -40,7 +40,7 @@ Services:
|
|
|
40
40
|
survey Surveys, questions, distribution, analytics
|
|
41
41
|
journey Lifecycle journeys, nodes, transitions
|
|
42
42
|
email-identity Email domains, sender identities, and DNS
|
|
43
|
-
|
|
43
|
+
env Environment variable settings
|
|
44
44
|
webhook Webhook endpoints and testing
|
|
45
45
|
campaign Email campaigns, scheduling, analytics
|
|
46
46
|
import Import users from external auth providers
|
|
@@ -61,7 +61,7 @@ Commands:
|
|
|
61
61
|
auth provider list
|
|
62
62
|
auth provider set <p1,p2,...>
|
|
63
63
|
auth oauth open <provider>
|
|
64
|
-
auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin]
|
|
64
|
+
auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin]
|
|
65
65
|
auth oauth remove <provider>
|
|
66
66
|
auth user list
|
|
67
67
|
auth user remove <user-id>
|
|
@@ -167,12 +167,12 @@ Commands:
|
|
|
167
167
|
environment show
|
|
168
168
|
environment update [<env-id>] [--name <name>] [--description <desc>]
|
|
169
169
|
environment promote [<env-id>] --target <tier>`,
|
|
170
|
-
|
|
170
|
+
env: `Usage: ascendkit env <command>
|
|
171
171
|
|
|
172
172
|
Commands:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
env list
|
|
174
|
+
env set <key> <value>
|
|
175
|
+
env remove <key>`,
|
|
176
176
|
import: `Usage: ascendkit import <source> <action> [options]
|
|
177
177
|
|
|
178
178
|
Sources:
|
|
@@ -214,7 +214,7 @@ function printSectionHelp(section) {
|
|
|
214
214
|
key = "email-identity";
|
|
215
215
|
if (key === "projects")
|
|
216
216
|
key = "project";
|
|
217
|
-
if (key === "
|
|
217
|
+
if (key === "environments")
|
|
218
218
|
key = "environment";
|
|
219
219
|
const text = HELP_SECTION[key];
|
|
220
220
|
if (!text)
|
|
@@ -294,6 +294,11 @@ function printAuthSettingsSummary(data) {
|
|
|
294
294
|
if (data.sessionDuration) {
|
|
295
295
|
console.log(`Session: ${data.sessionDuration}`);
|
|
296
296
|
}
|
|
297
|
+
const allowedDomains = Array.isArray(data.allowedDomains) ? data.allowedDomains : [];
|
|
298
|
+
if (allowedDomains.length > 0)
|
|
299
|
+
console.log(`Allowed domains: ${allowedDomains.join(", ")}`);
|
|
300
|
+
if (data.blockPersonalDomains)
|
|
301
|
+
console.log("Block personal domains: on");
|
|
297
302
|
}
|
|
298
303
|
function printTemplateSummary(data, opts) {
|
|
299
304
|
console.log(`Template: ${data.name} (${data.id})`);
|
|
@@ -309,7 +314,7 @@ function printTemplateSummary(data, opts) {
|
|
|
309
314
|
}
|
|
310
315
|
if (Array.isArray(data.unconfiguredVariables) && data.unconfiguredVariables.length > 0) {
|
|
311
316
|
console.log(`\n⚠ Unconfigured variables: ${data.unconfiguredVariables.join(", ")}`);
|
|
312
|
-
console.log(` Set values with: ascendkit
|
|
317
|
+
console.log(` Set values with: ascendkit env set <key> <value>`);
|
|
313
318
|
}
|
|
314
319
|
if (Array.isArray(data.relatedJourneys) && data.relatedJourneys.length > 0) {
|
|
315
320
|
const refs = data.relatedJourneys.map((j) => `${j.name} (${j.id})`).join(", ");
|
|
@@ -697,7 +702,7 @@ async function run() {
|
|
|
697
702
|
case "environment":
|
|
698
703
|
await runEnvironment(action, args.slice(2));
|
|
699
704
|
return;
|
|
700
|
-
case "
|
|
705
|
+
case "env":
|
|
701
706
|
await runKeystore(action, args.slice(2));
|
|
702
707
|
return;
|
|
703
708
|
}
|
|
@@ -1013,7 +1018,7 @@ async function runKeystore(action, rest) {
|
|
|
1013
1018
|
const key = rest[0];
|
|
1014
1019
|
const value = rest[1];
|
|
1015
1020
|
if (!key || value === undefined) {
|
|
1016
|
-
console.error("Usage: ascendkit
|
|
1021
|
+
console.error("Usage: ascendkit env set <key> <value>");
|
|
1017
1022
|
return await exitCli(1);
|
|
1018
1023
|
}
|
|
1019
1024
|
vars[key] = value;
|
|
@@ -1024,7 +1029,7 @@ async function runKeystore(action, rest) {
|
|
|
1024
1029
|
case "remove": {
|
|
1025
1030
|
const key = rest[0];
|
|
1026
1031
|
if (!key) {
|
|
1027
|
-
console.error("Usage: ascendkit
|
|
1032
|
+
console.error("Usage: ascendkit env remove <key>");
|
|
1028
1033
|
return await exitCli(1);
|
|
1029
1034
|
}
|
|
1030
1035
|
if (!(key in vars)) {
|
|
@@ -1063,8 +1068,8 @@ async function runKeystore(action, rest) {
|
|
|
1063
1068
|
return;
|
|
1064
1069
|
}
|
|
1065
1070
|
default:
|
|
1066
|
-
console.error(`Unknown
|
|
1067
|
-
console.error("Usage: ascendkit
|
|
1071
|
+
console.error(`Unknown env command: ${action}`);
|
|
1072
|
+
console.error("Usage: ascendkit env list|set|remove");
|
|
1068
1073
|
return await exitCli(1);
|
|
1069
1074
|
}
|
|
1070
1075
|
}
|
|
@@ -1094,6 +1099,12 @@ async function runAuth(client, action, rest) {
|
|
|
1094
1099
|
}
|
|
1095
1100
|
if (flags["session-duration"])
|
|
1096
1101
|
params.sessionDuration = flags["session-duration"];
|
|
1102
|
+
if (flags["allowed-domains"] !== undefined) {
|
|
1103
|
+
const raw = flags["allowed-domains"].trim();
|
|
1104
|
+
params.allowedDomains = raw === "" ? [] : raw.split(",").map((d) => d.trim()).filter(Boolean);
|
|
1105
|
+
}
|
|
1106
|
+
if (flags["block-personal-domains"] !== undefined)
|
|
1107
|
+
params.blockPersonalDomains = flags["block-personal-domains"] === "true";
|
|
1097
1108
|
printAuthSettingsSummary(await auth.updateSettings(client, params));
|
|
1098
1109
|
break;
|
|
1099
1110
|
}
|
|
@@ -1121,7 +1132,7 @@ async function runAuth(client, action, rest) {
|
|
|
1121
1132
|
const provider = oauthAction === "open" && rest[0] !== "open" ? rest[0] : rest[1];
|
|
1122
1133
|
if (oauthAction === "set") {
|
|
1123
1134
|
if (!provider || !flags["client-id"]) {
|
|
1124
|
-
console.error("Usage: ascendkit auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin]
|
|
1135
|
+
console.error("Usage: ascendkit auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin]");
|
|
1125
1136
|
return await exitCli(1);
|
|
1126
1137
|
}
|
|
1127
1138
|
const secretFromArg = flags["client-secret"];
|
|
@@ -1139,7 +1150,20 @@ async function runAuth(client, action, rest) {
|
|
|
1139
1150
|
console.error("Client secret cannot be empty.");
|
|
1140
1151
|
return await exitCli(1);
|
|
1141
1152
|
}
|
|
1142
|
-
|
|
1153
|
+
const ctx = loadEnvContext();
|
|
1154
|
+
if (!ctx) {
|
|
1155
|
+
console.error("No environment set. Run: ascendkit set-env <public-key>");
|
|
1156
|
+
return await exitCli(1);
|
|
1157
|
+
}
|
|
1158
|
+
const env = await platform.getEnvironment(ctx.projectId, ctx.environmentId);
|
|
1159
|
+
const variables = (env.variables ?? {});
|
|
1160
|
+
const appUrl = (variables.APP_URL ?? "").trim();
|
|
1161
|
+
if (!appUrl) {
|
|
1162
|
+
console.error("Set APP_URL for this environment first. AscendKit uses APP_URL to generate the redirect URI for custom OAuth credentials.");
|
|
1163
|
+
console.error("Use: ascendkit env set APP_URL https://your-app.com");
|
|
1164
|
+
return await exitCli(1);
|
|
1165
|
+
}
|
|
1166
|
+
await auth.updateOAuthCredentials(client, provider, flags["client-id"], clientSecret);
|
|
1143
1167
|
console.log(`Saved OAuth credentials for ${provider}.`);
|
|
1144
1168
|
}
|
|
1145
1169
|
else if (oauthAction === "remove") {
|
package/dist/commands/auth.d.ts
CHANGED
|
@@ -8,11 +8,13 @@ export interface UpdateSettingsParams {
|
|
|
8
8
|
requireUsername?: boolean;
|
|
9
9
|
};
|
|
10
10
|
sessionDuration?: string;
|
|
11
|
+
allowedDomains?: string[];
|
|
12
|
+
blockPersonalDomains?: boolean;
|
|
11
13
|
}
|
|
12
14
|
export declare function getSettings(client: AscendKitClient): Promise<unknown>;
|
|
13
15
|
export declare function updateSettings(client: AscendKitClient, params: UpdateSettingsParams): Promise<unknown>;
|
|
14
16
|
export declare function updateProviders(client: AscendKitClient, providers: string[]): Promise<unknown>;
|
|
15
|
-
export declare function updateOAuthCredentials(client: AscendKitClient, provider: string, clientId: string, clientSecret: string
|
|
17
|
+
export declare function updateOAuthCredentials(client: AscendKitClient, provider: string, clientId: string, clientSecret: string): Promise<unknown>;
|
|
16
18
|
export declare function deleteOAuthCredentials(client: AscendKitClient, provider: string): Promise<unknown>;
|
|
17
19
|
export declare function getOAuthSetupUrl(portalUrl: string, provider: string, publicKey?: string): string;
|
|
18
20
|
export declare function listUsers(client: AscendKitClient): Promise<unknown>;
|
package/dist/commands/auth.js
CHANGED
|
@@ -9,16 +9,17 @@ export async function updateSettings(client, params) {
|
|
|
9
9
|
body.features = params.features;
|
|
10
10
|
if (params.sessionDuration !== undefined)
|
|
11
11
|
body.sessionDuration = params.sessionDuration;
|
|
12
|
+
if (params.allowedDomains !== undefined)
|
|
13
|
+
body.allowedDomains = params.allowedDomains;
|
|
14
|
+
if (params.blockPersonalDomains !== undefined)
|
|
15
|
+
body.blockPersonalDomains = params.blockPersonalDomains;
|
|
12
16
|
return client.managedPut("/api/auth/settings", body);
|
|
13
17
|
}
|
|
14
18
|
export async function updateProviders(client, providers) {
|
|
15
19
|
return client.managedPut("/api/auth/settings/providers", { providers });
|
|
16
20
|
}
|
|
17
|
-
export async function updateOAuthCredentials(client, provider, clientId, clientSecret
|
|
18
|
-
|
|
19
|
-
if (callbackUrl)
|
|
20
|
-
body.callbackUrl = callbackUrl;
|
|
21
|
-
return client.managedPut(`/api/auth/settings/oauth/${provider}`, body);
|
|
21
|
+
export async function updateOAuthCredentials(client, provider, clientId, clientSecret) {
|
|
22
|
+
return client.managedPut(`/api/auth/settings/oauth/${provider}`, { clientId, clientSecret });
|
|
22
23
|
}
|
|
23
24
|
export async function deleteOAuthCredentials(client, provider) {
|
|
24
25
|
return client.managedDelete(`/api/auth/settings/oauth/${provider}`);
|
|
@@ -13,6 +13,7 @@ const ASCENDKIT_ENV_KEYS = [
|
|
|
13
13
|
"ASCENDKIT_API_URL",
|
|
14
14
|
"NEXT_PUBLIC_ASCENDKIT_ENV_KEY",
|
|
15
15
|
"ASCENDKIT_ENV_KEY",
|
|
16
|
+
"APP_URL",
|
|
16
17
|
"ASCENDKIT_APP_URL",
|
|
17
18
|
"ASCENDKIT_SECRET_KEY",
|
|
18
19
|
"ASCENDKIT_WEBHOOK_SECRET",
|
|
@@ -139,7 +140,7 @@ function buildAscendKitEnvBlock(values) {
|
|
|
139
140
|
"# Public URL where your app is hosted (used for auth callbacks and redirects)",
|
|
140
141
|
"# Example: https://app.yourdomain.com",
|
|
141
142
|
"# Leave blank in local dev if the SDK should infer from the incoming request.",
|
|
142
|
-
`
|
|
143
|
+
`APP_URL=${values.APP_URL}`,
|
|
143
144
|
"",
|
|
144
145
|
"# AscendKit secret key (server-only; never expose to client/browser)",
|
|
145
146
|
`ASCENDKIT_SECRET_KEY=${values.ASCENDKIT_SECRET_KEY}`,
|
|
@@ -189,6 +190,7 @@ async function updateEnvExampleFile(filePath) {
|
|
|
189
190
|
ASCENDKIT_API_URL: "",
|
|
190
191
|
NEXT_PUBLIC_ASCENDKIT_ENV_KEY: "",
|
|
191
192
|
ASCENDKIT_ENV_KEY: "",
|
|
193
|
+
APP_URL: "",
|
|
192
194
|
ASCENDKIT_APP_URL: "",
|
|
193
195
|
ASCENDKIT_SECRET_KEY: "",
|
|
194
196
|
ASCENDKIT_WEBHOOK_SECRET: "",
|
|
@@ -215,7 +217,8 @@ async function updateRuntimeEnvFile(filePath, apiUrl, publicKey, secretKey, opti
|
|
|
215
217
|
ASCENDKIT_API_URL: resolvedApiUrl,
|
|
216
218
|
NEXT_PUBLIC_ASCENDKIT_ENV_KEY: resolvedPublicKey,
|
|
217
219
|
ASCENDKIT_ENV_KEY: resolvedPublicKey,
|
|
218
|
-
|
|
220
|
+
APP_URL: readEnvValue(original, "APP_URL") ?? readEnvValue(original, "ASCENDKIT_APP_URL") ?? "",
|
|
221
|
+
ASCENDKIT_APP_URL: "",
|
|
219
222
|
ASCENDKIT_SECRET_KEY: resolvedSecretKey,
|
|
220
223
|
ASCENDKIT_WEBHOOK_SECRET: resolvedWebhookSecret,
|
|
221
224
|
});
|
package/dist/tools/auth.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import * as auth from "../commands/auth.js";
|
|
3
|
+
import * as platform from "../commands/platform.js";
|
|
3
4
|
function formatAuthSettings(data) {
|
|
4
5
|
const providers = Array.isArray(data.providers) ? data.providers : [];
|
|
5
6
|
const features = data.features ?? {};
|
|
@@ -12,6 +13,11 @@ function formatAuthSettings(data) {
|
|
|
12
13
|
];
|
|
13
14
|
if (data.sessionDuration)
|
|
14
15
|
lines.push(`Session: ${data.sessionDuration}`);
|
|
16
|
+
const allowedDomains = Array.isArray(data.allowedDomains) ? data.allowedDomains : [];
|
|
17
|
+
if (allowedDomains.length > 0)
|
|
18
|
+
lines.push(`Allowed domains: ${allowedDomains.join(", ")}`);
|
|
19
|
+
if (data.blockPersonalDomains)
|
|
20
|
+
lines.push("Block personal domains: on");
|
|
15
21
|
return lines.join("\n");
|
|
16
22
|
}
|
|
17
23
|
export function registerAuthTools(server, client) {
|
|
@@ -41,6 +47,24 @@ export function registerAuthTools(server, client) {
|
|
|
41
47
|
const data = await auth.updateSettings(client, params);
|
|
42
48
|
return { content: [{ type: "text", text: formatAuthSettings(data) }] };
|
|
43
49
|
});
|
|
50
|
+
server.tool("auth_domain_restrictions", "Configure email domain restrictions for signups. Set an allowlist of specific domains, or block personal email providers (gmail, yahoo, etc.), or both. Allowlist takes precedence when both are set.", {
|
|
51
|
+
allowedDomains: z
|
|
52
|
+
.array(z.string())
|
|
53
|
+
.optional()
|
|
54
|
+
.describe('Allowed email domains for signup, e.g. ["company.com", "partner.org"]. Pass empty array to clear.'),
|
|
55
|
+
blockPersonalDomains: z
|
|
56
|
+
.boolean()
|
|
57
|
+
.optional()
|
|
58
|
+
.describe("Block signups from common personal email providers (gmail, yahoo, hotmail, etc.)"),
|
|
59
|
+
}, async (params) => {
|
|
60
|
+
const body = {};
|
|
61
|
+
if (params.allowedDomains !== undefined)
|
|
62
|
+
body.allowedDomains = params.allowedDomains;
|
|
63
|
+
if (params.blockPersonalDomains !== undefined)
|
|
64
|
+
body.blockPersonalDomains = params.blockPersonalDomains;
|
|
65
|
+
const data = await client.managedPut("/api/auth/settings", body);
|
|
66
|
+
return { content: [{ type: "text", text: formatAuthSettings(data) }] };
|
|
67
|
+
});
|
|
44
68
|
server.tool("auth_provider_set", "Set which auth providers are enabled for the project. Credentials and magic-link are mutually exclusive. Social-only login (e.g. [\"google\"]) is valid. At least one provider required.", {
|
|
45
69
|
providers: z
|
|
46
70
|
.array(z.string())
|
|
@@ -60,7 +84,6 @@ export function registerAuthTools(server, client) {
|
|
|
60
84
|
provider: z.string().describe('OAuth provider name, e.g. "google", "github"'),
|
|
61
85
|
clientId: z.string().optional().describe("OAuth client ID (to set credentials directly)"),
|
|
62
86
|
clientSecret: z.string().optional().describe("OAuth client secret (to set credentials directly)"),
|
|
63
|
-
callbackUrl: z.string().optional().describe("Auth callback URL for this provider"),
|
|
64
87
|
useProxy: z.boolean().optional().describe("Clear custom credentials and use AscendKit managed proxy credentials"),
|
|
65
88
|
}, async (params) => {
|
|
66
89
|
if (params.useProxy && (params.clientId || params.clientSecret)) {
|
|
@@ -91,7 +114,19 @@ export function registerAuthTools(server, client) {
|
|
|
91
114
|
};
|
|
92
115
|
}
|
|
93
116
|
if (params.clientId && params.clientSecret) {
|
|
94
|
-
const
|
|
117
|
+
const env = await platform.mcpGetEnvironment(client, {});
|
|
118
|
+
const variables = env.variables ?? {};
|
|
119
|
+
const appUrl = (variables.APP_URL ?? "").trim();
|
|
120
|
+
if (!appUrl) {
|
|
121
|
+
return {
|
|
122
|
+
content: [{
|
|
123
|
+
type: "text",
|
|
124
|
+
text: "Set APP_URL for the active environment first. AscendKit uses APP_URL to generate the redirect URI for custom OAuth credentials.",
|
|
125
|
+
}],
|
|
126
|
+
isError: true,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const data = await auth.updateOAuthCredentials(client, params.provider, params.clientId, params.clientSecret);
|
|
95
130
|
return {
|
|
96
131
|
content: [{
|
|
97
132
|
type: "text",
|
package/dist/tools/platform.js
CHANGED
|
@@ -206,7 +206,7 @@ export function registerPlatformTools(server, client) {
|
|
|
206
206
|
};
|
|
207
207
|
}
|
|
208
208
|
});
|
|
209
|
-
server.tool("
|
|
209
|
+
server.tool("env_list", "List environment variable values for the active environment. Uses the shared .ascendkit environment context by default.", {
|
|
210
210
|
projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
|
|
211
211
|
envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
|
|
212
212
|
}, async (params) => {
|
|
@@ -235,10 +235,10 @@ export function registerPlatformTools(server, client) {
|
|
|
235
235
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
236
236
|
}
|
|
237
237
|
});
|
|
238
|
-
server.tool("
|
|
238
|
+
server.tool("env_replace", "Replace the full environment variable map for the active environment. Pass the full key-value map.", {
|
|
239
239
|
projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
|
|
240
240
|
envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
|
|
241
|
-
variables: z.record(z.string()).describe("Key-value map of
|
|
241
|
+
variables: z.record(z.string()).describe("Key-value map of environment variables"),
|
|
242
242
|
}, async (params) => {
|
|
243
243
|
try {
|
|
244
244
|
const data = await platform.mcpUpdateEnvironmentVariables(client, params);
|
|
@@ -265,11 +265,11 @@ export function registerPlatformTools(server, client) {
|
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
});
|
|
268
|
-
server.tool("
|
|
268
|
+
server.tool("env_set", "Set a single environment variable for the active environment.", {
|
|
269
269
|
projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
|
|
270
270
|
envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
|
|
271
|
-
key: z.string().describe("
|
|
272
|
-
value: z.string().describe("
|
|
271
|
+
key: z.string().describe("Environment variable key"),
|
|
272
|
+
value: z.string().describe("Environment variable value"),
|
|
273
273
|
}, async (params) => {
|
|
274
274
|
try {
|
|
275
275
|
const env = await platform.mcpGetEnvironment(client, {
|
|
@@ -291,10 +291,10 @@ export function registerPlatformTools(server, client) {
|
|
|
291
291
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
292
292
|
}
|
|
293
293
|
});
|
|
294
|
-
server.tool("
|
|
294
|
+
server.tool("env_remove", "Remove a single environment variable from the active environment.", {
|
|
295
295
|
projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
|
|
296
296
|
envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
|
|
297
|
-
key: z.string().describe("
|
|
297
|
+
key: z.string().describe("Environment variable key to remove"),
|
|
298
298
|
}, async (params) => {
|
|
299
299
|
try {
|
|
300
300
|
const env = await platform.mcpGetEnvironment(client, {
|