@govuk-pay/cli 0.0.120 → 0.0.122

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@govuk-pay/cli",
3
- "version": "0.0.120",
3
+ "version": "0.0.122",
4
4
  "description": "GOV.UK Pay Command Line Interface",
5
5
  "bin": {
6
6
  "pay": "bin/cli.js",
@@ -39,10 +39,12 @@ const appClient = {
39
39
  const typedBody = body;
40
40
  return typedBody._links;
41
41
  },
42
- async createService() {
42
+ async createService(serviceName = 'My service') {
43
43
  const createServiceData = {
44
- en: 'My service',
45
- cy: 'Welsh name for My service'
44
+ service_name: {
45
+ en: serviceName,
46
+ cy: `Welsh name for ${serviceName}`
47
+ }
46
48
  };
47
49
  const url = urlFor('adminusers', '/v1/api/services');
48
50
  const result = await (0, fetch_wrapper_1.postRequest)(url, createServiceData);
@@ -78,11 +80,11 @@ const appClient = {
78
80
  }
79
81
  return account;
80
82
  },
81
- async createAccount(serviceID) {
83
+ async createAccount(serviceID, paymentProvider = 'sandbox', type = 'test') {
82
84
  const createAccountData = {
83
- payment_provider: 'sandbox',
84
- service_name: 'My service',
85
- type: 'test',
85
+ payment_provider: paymentProvider,
86
+ service_name: `My ${type} ${paymentProvider} service`,
87
+ type,
86
88
  service_id: serviceID
87
89
  };
88
90
  const url = urlFor('connector', '/v1/api/accounts');
@@ -99,6 +101,97 @@ const appClient = {
99
101
  const typedBody = body;
100
102
  return typedBody;
101
103
  },
104
+ async completeStripeOnboarding(serviceID) {
105
+ const patchStripeAccountSetupData = [{
106
+ op: 'replace',
107
+ path: 'bank_account',
108
+ value: true
109
+ }, {
110
+ op: 'replace',
111
+ path: 'responsible_person',
112
+ value: true
113
+ }, {
114
+ op: 'replace',
115
+ path: 'vat_number',
116
+ value: true
117
+ }, {
118
+ op: 'replace',
119
+ path: 'company_number',
120
+ value: true
121
+ }, {
122
+ op: 'replace',
123
+ path: 'director',
124
+ value: true
125
+ }, {
126
+ op: 'replace',
127
+ path: 'government_entity_document',
128
+ value: true
129
+ }, {
130
+ op: 'replace',
131
+ path: 'organisation_details',
132
+ value: true
133
+ }];
134
+ const url = urlFor('connector', `/v1/api/service/${serviceID}/account/live/stripe-setup`);
135
+ const result = await (0, fetch_wrapper_1.patchRequest)(url, patchStripeAccountSetupData);
136
+ if (!result.success) {
137
+ console.error((0, fetch_wrapper_1.formatErrorMessageForFailedRequest)(result.unsuccessfulResult));
138
+ return;
139
+ }
140
+ return true;
141
+ },
142
+ async enableProviderSwitching(serviceID) {
143
+ const patchProviderSwitchingEnabledData = {
144
+ op: 'replace',
145
+ path: 'provider_switch_enabled',
146
+ value: true
147
+ };
148
+ const url = urlFor('connector', `/v1/api/service/${serviceID}/account/live`);
149
+ const result = await (0, fetch_wrapper_1.patchRequest)(url, patchProviderSwitchingEnabledData);
150
+ if (!result.success) {
151
+ console.error((0, fetch_wrapper_1.formatErrorMessageForFailedRequest)(result.unsuccessfulResult));
152
+ return;
153
+ }
154
+ return true;
155
+ },
156
+ async createAccountCredentials(serviceID, paymentProvider) {
157
+ const url = urlFor('connector', `/v1/api/service/${serviceID}/account/live/credentials`);
158
+ const credentialsData = {
159
+ credentials: {},
160
+ payment_provider: paymentProvider
161
+ };
162
+ const result = await (0, fetch_wrapper_1.postRequest)(url, credentialsData);
163
+ if (!result.success) {
164
+ console.error((0, fetch_wrapper_1.formatErrorMessageForFailedRequest)(result.unsuccessfulResult));
165
+ return;
166
+ }
167
+ const body = result.successfulResult?.body;
168
+ if (body === undefined || typeof body === 'string') {
169
+ console.error('The response to a create an account did not have a body, or the body was not JSON!');
170
+ return;
171
+ }
172
+ const typedBody = body;
173
+ return typedBody;
174
+ },
175
+ async updateStripeAccountCredentials(serviceID, credentialID) {
176
+ const url = urlFor('connector', `/v1/api/service/${serviceID}/account/live/credentials/${credentialID}`);
177
+ const patchAccountCredentialsData = [{
178
+ op: 'replace',
179
+ path: 'credentials',
180
+ value: { stripe_account_id: 'stripe-account-123' }
181
+ }];
182
+ const result = await (0, fetch_wrapper_1.patchRequest)(url, patchAccountCredentialsData);
183
+ if (!result.success) {
184
+ console.error((0, fetch_wrapper_1.formatErrorMessageForFailedRequest)(result.unsuccessfulResult));
185
+ return;
186
+ }
187
+ const body = result.successfulResult?.body;
188
+ if (body === undefined || typeof body === 'string') {
189
+ console.error('The response to a update a credential did not have a body, or the body was not JSON!');
190
+ return;
191
+ }
192
+ const typedBody = body;
193
+ return typedBody;
194
+ },
102
195
  async getAccount(gatewayAccountId) {
103
196
  const url = urlFor('connector', `/v1/api/accounts/${gatewayAccountId}`);
104
197
  const result = await (0, fetch_wrapper_1.getRequest)(url);
@@ -137,6 +230,20 @@ const appClient = {
137
230
  }
138
231
  return true;
139
232
  },
233
+ async setGoLiveStatusToLive(serviceID) {
234
+ const patchGoLiveStatusData = {
235
+ op: 'replace',
236
+ path: 'current_go_live_stage',
237
+ value: 'LIVE'
238
+ };
239
+ const url = urlFor('adminusers', `/v1/api/services/${serviceID}`);
240
+ const result = await (0, fetch_wrapper_1.patchRequest)(url, patchGoLiveStatusData);
241
+ if (!result.success) {
242
+ console.error((0, fetch_wrapper_1.formatErrorMessageForFailedRequest)(result.unsuccessfulResult));
243
+ return;
244
+ }
245
+ return true;
246
+ },
140
247
  async createToken(gatewayAccountID, serviceExternalId, serviceMode) {
141
248
  const createTokenData = {
142
249
  account_id: gatewayAccountID,
@@ -205,6 +312,32 @@ const appClient = {
205
312
  };
206
313
  return typedAugmentedBody;
207
314
  },
315
+ async getUser(userEmailAddress) {
316
+ const url = urlFor('adminusers', '/v1/api/users/find');
317
+ const emailData = {
318
+ email: userEmailAddress
319
+ };
320
+ const result = await (0, fetch_wrapper_1.postRequest)(url, emailData);
321
+ if (!result.success) {
322
+ console.error((0, fetch_wrapper_1.formatErrorMessageForFailedRequest)(result.unsuccessfulResult));
323
+ return;
324
+ }
325
+ const body = result.successfulResult?.body;
326
+ return body;
327
+ },
328
+ async assignUserAsAdminToService(userExternalID, serviceExternalID) {
329
+ const url = urlFor('adminusers', `/v1/api/users/${userExternalID}/services`);
330
+ const serviceRoleData = {
331
+ service_external_id: serviceExternalID,
332
+ role_name: 'admin'
333
+ };
334
+ const result = await (0, fetch_wrapper_1.postRequest)(url, serviceRoleData);
335
+ if (!result.success) {
336
+ console.error((0, fetch_wrapper_1.formatErrorMessageForFailedRequest)(result.unsuccessfulResult));
337
+ return;
338
+ }
339
+ return true;
340
+ },
208
341
  async isHealthy(serviceName) {
209
342
  const url = urlFor(serviceName, '/healthcheck');
210
343
  const response = await (0, fetch_wrapper_1.getRequest)(url);
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.builder = exports.handler = exports.desc = exports.command = void 0;
7
+ const standardContent_1 = require("../../../core/standardContent");
8
+ const app_client_1 = __importDefault(require("../app_client/app_client"));
9
+ exports.command = 'service <email>';
10
+ exports.desc = 'Create an Adyen migration service';
11
+ exports.handler = serviceHandler;
12
+ const builder = (yargs) => {
13
+ return yargs
14
+ .usage(`$0 local service <email> \n\n${exports.desc}`)
15
+ .positional('email', {
16
+ type: 'string',
17
+ description: 'Email address of an existing user to assign as admin for the service'
18
+ });
19
+ };
20
+ exports.builder = builder;
21
+ async function serviceHandler(argv) {
22
+ await (0, standardContent_1.showHeader)();
23
+ if (await app_client_1.default.isUnhealthy('adminusers')) {
24
+ console.error('Adminusers is unhealthy');
25
+ return;
26
+ }
27
+ if (await app_client_1.default.isUnhealthy('connector')) {
28
+ console.error('Connector is unhealthy');
29
+ return;
30
+ }
31
+ const serviceExternalID = await app_client_1.default.createService('Adyen migration service');
32
+ if (serviceExternalID === undefined) {
33
+ console.error('Unable to create a service');
34
+ return;
35
+ }
36
+ console.log(`💁 Service ID: ${serviceExternalID}`);
37
+ const userEmailAddress = argv.email;
38
+ const user = await app_client_1.default.getUser(userEmailAddress);
39
+ if (user === undefined) {
40
+ console.error('Failed to retrieve user');
41
+ return;
42
+ }
43
+ const userAssignedToService = await app_client_1.default.assignUserAsAdminToService(user.external_id, serviceExternalID);
44
+ if (userAssignedToService === undefined) {
45
+ console.error('Failed to add user');
46
+ return;
47
+ }
48
+ console.log(`🤓 Assigned user [${user.external_id}] as admin to service [${serviceExternalID}]`);
49
+ const testAccount = await app_client_1.default.createAccount(serviceExternalID);
50
+ if (testAccount === undefined) {
51
+ console.error('Failed to create a fully set up test account');
52
+ return;
53
+ }
54
+ console.log(`🆔 Test gateway account ID: ${testAccount.gateway_account_id}`);
55
+ const liveStripeAccount = await app_client_1.default.createAccount(serviceExternalID, 'stripe', 'live');
56
+ if (liveStripeAccount === undefined) {
57
+ console.error('Failed to create a live Stripe account');
58
+ return;
59
+ }
60
+ const testAccountID = testAccount.gateway_account_id;
61
+ const liveStripeAccountId = liveStripeAccount.gateway_account_id;
62
+ const gatewayAccountsIDs = [testAccountID, liveStripeAccountId];
63
+ console.log(`🆔 Live Stripe gateway account ID: ${liveStripeAccountId}`);
64
+ for (const accountId of gatewayAccountsIDs) {
65
+ const success = await app_client_1.default.addGatewayAccountToService(accountId, serviceExternalID);
66
+ if (!success) {
67
+ console.error('Failed to add the gateway account to the service');
68
+ }
69
+ else {
70
+ console.warn(`➕ Added gateway account ID [${accountId}] to Service ID [${serviceExternalID}]`);
71
+ }
72
+ }
73
+ const stripeAccountSetupTasksCompleted = await app_client_1.default.completeStripeOnboarding(serviceExternalID);
74
+ if (stripeAccountSetupTasksCompleted === undefined) {
75
+ console.error('Failed to complete Stripe onboarding tasks');
76
+ return;
77
+ }
78
+ console.log(`✅ Stripe onboarding tasks completed for gateway account [${liveStripeAccountId}]`);
79
+ const hasLiveStatus = await app_client_1.default.setGoLiveStatusToLive(serviceExternalID);
80
+ if (hasLiveStatus === undefined) {
81
+ console.error('Failed to update go live status for service');
82
+ return;
83
+ }
84
+ console.log(`▶️ Go live status set to live for Service ID [${serviceExternalID}]`);
85
+ const liveStripeAccountResponse = await app_client_1.default.getAccount(liveStripeAccountId);
86
+ if (liveStripeAccountResponse === undefined) {
87
+ console.error(`No gateway account exists with ID: ${liveStripeAccount.gateway_account_id}`);
88
+ return;
89
+ }
90
+ const stripeCredentialID = liveStripeAccountResponse.gateway_account_credentials[0].external_id;
91
+ const stripeGatewayAccountCredential = await app_client_1.default.updateStripeAccountCredentials(serviceExternalID, stripeCredentialID);
92
+ if (stripeGatewayAccountCredential === undefined) {
93
+ console.error('Failed to create a Stripe account credential');
94
+ return;
95
+ }
96
+ console.log(`⬆️ Live Stripe gateway account credential [${stripeGatewayAccountCredential.external_id}] set to active`);
97
+ const adyenGatewayAccountCredential = await app_client_1.default.createAccountCredentials(serviceExternalID, 'adyen');
98
+ if (adyenGatewayAccountCredential === undefined) {
99
+ console.error('Failed to create an Adyen account credential');
100
+ return;
101
+ }
102
+ console.log(`📑 Live Adyen gateway account credential ID: ${adyenGatewayAccountCredential.external_id}`);
103
+ const liveStripeAccountSwitchingFlagEnabled = await app_client_1.default.enableProviderSwitching(serviceExternalID);
104
+ if (liveStripeAccountSwitchingFlagEnabled === undefined) {
105
+ console.error('Failed to enable provider switching');
106
+ return;
107
+ }
108
+ console.log(`🔁 Provider switching enabled for account [${liveStripeAccountId}]`);
109
+ }
@@ -17,6 +17,8 @@ exports.PRODUCTION_2_CONFIG = {
17
17
  DB_SUPPORT_PASSWORD_READONLY: 'aws/rds/support_readonly_users/production/connector_support_readonly', // pragma: allowlist secret
18
18
  DB_SUPPORT_PASSWORD_READWRITE: 'aws/rds/support_readwrite_users/production/connector_support_readwrite', // pragma: allowlist secret
19
19
  NOTIFY_API_KEY: 'notify/api_key/deploy/production.connector.notify_api_key', // pragma: allowlist secret
20
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_TEST: 'adyen/production/test/company-account-api-key', // pragma: allowlist secret
21
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_LIVE: '', // pragma: allowlist secret
20
22
  GDS_CONNECTOR_STRIPE_AUTH_TOKEN: 'stripe/production/test/account-api-key',
21
23
  GDS_CONNECTOR_STRIPE_AUTH_LIVE_TOKEN: 'stripe/production/live/account-api-key',
22
24
  GDS_CONNECTOR_STRIPE_WEBHOOK_SIGN_SECRET: 'stripe/production/test/webhook-secret', // pragma: allowlist secret
@@ -17,6 +17,8 @@ exports.STAGING_2_CONFIG = {
17
17
  DB_SUPPORT_PASSWORD_READONLY: 'aws/rds/support_readonly_users/staging/connector_support_readonly', // pragma: allowlist secret
18
18
  DB_SUPPORT_PASSWORD_READWRITE: 'aws/rds/support_readwrite_users/staging/connector_support_readwrite', // pragma: allowlist secret
19
19
  NOTIFY_API_KEY: 'notify/api_key/deploy/staging.connector.notify_api_key', // pragma: allowlist secret
20
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_TEST: 'adyen/staging/test/company-account-api-key', // pragma: allowlist secret
21
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_LIVE: 'adyen/staging/test/company-account-api-key', // pragma: allowlist secret
20
22
  GDS_CONNECTOR_STRIPE_AUTH_TOKEN: 'stripe/staging/test/account-api-key',
21
23
  GDS_CONNECTOR_STRIPE_AUTH_LIVE_TOKEN: 'stripe/staging/test/account-api-key',
22
24
  GDS_CONNECTOR_STRIPE_WEBHOOK_SIGN_SECRET: 'stripe/staging/test/webhook-secret', // pragma: allowlist secret
@@ -17,6 +17,8 @@ exports.TEST_12_CONFIG = {
17
17
  DB_SUPPORT_PASSWORD_READONLY: 'aws/rds/support_readonly_users/test/connector_support_readonly', // pragma: allowlist secret
18
18
  DB_SUPPORT_PASSWORD_READWRITE: 'aws/rds/support_readwrite_users/test/connector_support_readwrite', // pragma: allowlist secret
19
19
  NOTIFY_API_KEY: 'notify/api_key/ci/test.connector.notify_api_key', // pragma: allowlist secret
20
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_TEST: 'adyen/test/test/company-account-api-key', // pragma: allowlist secret
21
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_LIVE: 'adyen/test/test/company-account-api-key', // pragma: allowlist secret
20
22
  GDS_CONNECTOR_STRIPE_AUTH_TOKEN: 'stripe/test/test/account-api-key',
21
23
  GDS_CONNECTOR_STRIPE_AUTH_LIVE_TOKEN: 'stripe/test/test/account-api-key',
22
24
  GDS_CONNECTOR_STRIPE_WEBHOOK_SIGN_SECRET: 'stripe/test/test/webhook-secret', // pragma: allowlist secret
@@ -17,6 +17,8 @@ exports.TEST_PERF_1_CONFIG = {
17
17
  DB_SUPPORT_PASSWORD_READONLY: 'aws/rds/support_readonly_users/test-perf/connector_support_readonly', // pragma: allowlist secret
18
18
  DB_SUPPORT_PASSWORD_READWRITE: 'aws/rds/support_readwrite_users/test-perf/connector_support_readwrite', // pragma: allowlist secret
19
19
  NOTIFY_API_KEY: 'notify/api_key/ci/test_perf.connector.notify_api_key', // pragma: allowlist secret
20
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_TEST: 'adyen/test/test/company-account-api-key', // pragma: allowlist secret
21
+ GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_LIVE: 'adyen/test/test/company-account-api-key', // pragma: allowlist secret
20
22
  GDS_CONNECTOR_STRIPE_AUTH_TOKEN: 'stripe/test/test/account-api-key',
21
23
  GDS_CONNECTOR_STRIPE_AUTH_LIVE_TOKEN: 'stripe/test/test/account-api-key',
22
24
  GDS_CONNECTOR_STRIPE_WEBHOOK_SIGN_SECRET: 'stripe/test/test/webhook-secret', // pragma: allowlist secret
@@ -99,6 +99,8 @@ exports.SERVICE_SECRETS = {
99
99
  'DB_SUPPORT_USER_READONLY',
100
100
  'DB_SUPPORT_USER_READWRITE',
101
101
  'DB_USER',
102
+ 'GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_TEST',
103
+ 'GDS_CONNECTOR_ADYEN_COMPANY_ACCOUNT_API_KEY_LIVE',
102
104
  'GDS_CONNECTOR_STRIPE_AUTH_LIVE_TOKEN',
103
105
  'GDS_CONNECTOR_STRIPE_AUTH_TOKEN',
104
106
  'GDS_CONNECTOR_STRIPE_CONNECT_APPLICATION_WEBHOOK_LIVE_SIGN_SECRET',