diff --git a/cli/README.md b/cli/README.md index 7f9c27ec4..012302b8e 100644 --- a/cli/README.md +++ b/cli/README.md @@ -115,8 +115,14 @@ grid customers kyc-link \ --customer-id \ --redirect-url https://example.com/kyc-complete -# Update customer -grid customers update --full-name "Jane Doe" +# Update customer (--type is the required discriminator) +grid customers update --type INDIVIDUAL --full-name "Jane Doe" + +# Contact verification (only required in some regulatory jurisdictions) +grid customers verify-email +grid customers confirm-email --code 123456 +grid customers verify-phone +grid customers confirm-phone --code 123456 # Delete customer (prompts for confirmation) grid customers delete diff --git a/cli/src/commands/customers.ts b/cli/src/commands/customers.ts index 53ad2b65c..ff7fa8a3f 100644 --- a/cli/src/commands/customers.ts +++ b/cli/src/commands/customers.ts @@ -419,4 +419,64 @@ export function registerCustomersCommand( ); outputResponse(response); }); + + customersCmd + .command("verify-email ") + .description("Send an email verification code to a customer") + .action(async (customerId: string) => { + const opts = program.opts(); + const client = getClient(opts); + if (!client) return; + + const response = await client.post( + `/customers/${customerId}/verify-email` + ); + outputResponse(response); + }); + + customersCmd + .command("confirm-email ") + .description("Confirm a customer's email verification code") + .requiredOption("--code ", "The verification code the customer received") + .action(async (customerId: string, options) => { + const opts = program.opts(); + const client = getClient(opts); + if (!client) return; + + const response = await client.post( + `/customers/${customerId}/verify-email/confirm`, + { code: options.code } + ); + outputResponse(response); + }); + + customersCmd + .command("verify-phone ") + .description("Send a phone verification code to a customer") + .action(async (customerId: string) => { + const opts = program.opts(); + const client = getClient(opts); + if (!client) return; + + const response = await client.post( + `/customers/${customerId}/verify-phone` + ); + outputResponse(response); + }); + + customersCmd + .command("confirm-phone ") + .description("Confirm a customer's phone verification code") + .requiredOption("--code ", "The verification code the customer received") + .action(async (customerId: string, options) => { + const opts = program.opts(); + const client = getClient(opts); + if (!client) return; + + const response = await client.post( + `/customers/${customerId}/verify-phone/confirm`, + { code: options.code } + ); + outputResponse(response); + }); } diff --git a/cli/test/customers-verification.test.ts b/cli/test/customers-verification.test.ts new file mode 100644 index 000000000..1e337cd49 --- /dev/null +++ b/cli/test/customers-verification.test.ts @@ -0,0 +1,52 @@ +import { describe, it, expect } from "vitest"; +import { runCli } from "./helpers"; + +describe("customers verify-email", () => { + it("posts to the verify-email endpoint", async () => { + const { request } = await runCli(["customers", "verify-email", "cust_1"]); + + expect(request?.method).toBe("POST"); + expect(request?.path).toBe("/grid/v1/customers/cust_1/verify-email"); + }); +}); + +describe("customers confirm-email", () => { + it("posts the code to the verify-email/confirm endpoint", async () => { + const { request } = await runCli([ + "customers", + "confirm-email", + "cust_1", + "--code", + "123456", + ]); + + expect(request?.method).toBe("POST"); + expect(request?.path).toBe("/grid/v1/customers/cust_1/verify-email/confirm"); + expect(request?.body).toMatchObject({ code: "123456" }); + }); +}); + +describe("customers verify-phone", () => { + it("posts to the verify-phone endpoint", async () => { + const { request } = await runCli(["customers", "verify-phone", "cust_1"]); + + expect(request?.method).toBe("POST"); + expect(request?.path).toBe("/grid/v1/customers/cust_1/verify-phone"); + }); +}); + +describe("customers confirm-phone", () => { + it("posts the code to the verify-phone/confirm endpoint", async () => { + const { request } = await runCli([ + "customers", + "confirm-phone", + "cust_1", + "--code", + "654321", + ]); + + expect(request?.method).toBe("POST"); + expect(request?.path).toBe("/grid/v1/customers/cust_1/verify-phone/confirm"); + expect(request?.body).toMatchObject({ code: "654321" }); + }); +});