@unito/integration-cli 0.57.0 → 0.57.2
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/integrationGenerator/test/resources/integration.test.js +7 -8
- package/dist/src/commands/activity.d.ts +2 -2
- package/dist/src/commands/activity.js +2 -2
- package/dist/src/commands/dev.d.ts +4 -4
- package/dist/src/commands/dev.js +3 -2
- package/dist/src/commands/encrypt.d.ts +1 -1
- package/dist/src/commands/encrypt.js +1 -1
- package/dist/src/commands/init.d.ts +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/invite.d.ts +1 -1
- package/dist/src/commands/invite.js +2 -2
- package/dist/src/commands/login.d.ts +1 -1
- package/dist/src/commands/login.js +1 -1
- package/dist/src/commands/oauth2.d.ts +3 -3
- package/dist/src/commands/oauth2.js +4 -4
- package/dist/src/commands/publish.d.ts +2 -2
- package/dist/src/commands/publish.js +12 -12
- package/dist/src/commands/test.js +5 -3
- package/dist/src/commands/upgrade.js +3 -3
- package/dist/src/oauth2Helper/oauth2Helper.d.ts +4 -2
- package/dist/src/oauth2Helper/oauth2Helper.js +31 -11
- package/dist/src/services/oauth2Helper.d.ts +2 -1
- package/dist/src/services/oauth2Helper.js +4 -3
- package/dist/test/commands/activity.test.js +12 -9
- package/dist/test/commands/dev.test.js +38 -10
- package/dist/test/commands/encrypt.test.js +6 -7
- package/dist/test/commands/init.test.js +6 -8
- package/dist/test/commands/invite.test.js +11 -11
- package/dist/test/commands/login.test.js +19 -23
- package/dist/test/commands/oauth2.test.js +4 -1
- package/dist/test/commands/publish.test.js +151 -218
- package/dist/test/commands/test.test.js +43 -13
- package/dist/test/commands/upgrade.test.js +3 -6
- package/dist/test/errors.test.js +36 -36
- package/dist/test/helpers/integrations.d.ts +26 -0
- package/dist/test/helpers/integrations.js +25 -0
- package/dist/test/helpers/styles.d.ts +1 -0
- package/dist/test/helpers/styles.js +8 -0
- package/dist/test/oauth2Helper/oauth2Helper.test.js +20 -20
- package/dist/test/resources/configuration.test.js +24 -24
- package/dist/test/resources/decryption.test.js +9 -9
- package/dist/test/resources/globalConfiguration.test.js +4 -4
- package/dist/test/services/integrationsPlatform.test.js +20 -20
- package/dist/test/services/oauth2Helper.test.js +7 -7
- package/oclif.manifest.json +1 -1
- package/package.json +3 -7
- package/dist/test/mocha.hooks.d.ts +0 -2
- package/dist/test/mocha.hooks.js +0 -37
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const
|
|
4
|
+
const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
|
|
5
5
|
const path = tslib_1.__importStar(require("path"));
|
|
6
6
|
const sinon = tslib_1.__importStar(require("sinon"));
|
|
7
7
|
const tmp_1 = tslib_1.__importDefault(require("tmp"));
|
|
@@ -19,7 +19,6 @@ describe('Integration Resource Generation', () => {
|
|
|
19
19
|
});
|
|
20
20
|
afterEach(async () => {
|
|
21
21
|
await fs_1.default.promises.rm(tempDir, { recursive: true });
|
|
22
|
-
sinon.restore();
|
|
23
22
|
});
|
|
24
23
|
it('should not create a new integration directory if it already exists', async () => {
|
|
25
24
|
const existingIntegrationName = 'existingIntegration';
|
|
@@ -28,24 +27,24 @@ describe('Integration Resource Generation', () => {
|
|
|
28
27
|
await Integration.generateIntegrationSkeleton(existingIntegrationName, tempDir);
|
|
29
28
|
}
|
|
30
29
|
catch (e) {
|
|
31
|
-
(0,
|
|
30
|
+
(0, strict_1.default)(e.message.includes('already exists with this name'));
|
|
32
31
|
}
|
|
33
32
|
});
|
|
34
33
|
it('should create a new integration directory if it does not exist', async () => {
|
|
35
34
|
const integrationName = 'NewIntegration';
|
|
36
35
|
const result = await Integration.generateIntegrationSkeleton(integrationName, tempDir);
|
|
37
|
-
|
|
38
|
-
(0,
|
|
36
|
+
strict_1.default.equal(result, path.join(tempDir, integrationName.toLowerCase()));
|
|
37
|
+
(0, strict_1.default)(fs_1.default.existsSync(result));
|
|
39
38
|
const expectedFiles = await fs_1.default.promises.readdir(boilerplatePath);
|
|
40
39
|
expectedFiles.push('.npmrc');
|
|
41
40
|
const createdFiles = await fs_1.default.promises.readdir(result);
|
|
42
|
-
(
|
|
43
|
-
createdFiles.forEach(createdField => (0,
|
|
41
|
+
strict_1.default.deepEqual(createdFiles, expectedFiles.sort());
|
|
42
|
+
createdFiles.forEach(createdField => (0, strict_1.default)(expectedFiles.includes(createdField)));
|
|
44
43
|
});
|
|
45
44
|
it('generates an .npmrc file', async () => {
|
|
46
45
|
const result = await Integration.generateIntegrationSkeleton('foo', tempDir);
|
|
47
46
|
const npmrc = await fs_1.default.promises.readFile(`${result}/.npmrc`, 'utf-8');
|
|
48
|
-
(0,
|
|
47
|
+
(0, strict_1.default)(npmrc.includes('//npm.pkg.github.com/:_authToken=${UNITO_GITHUB_PKG_TOKEN}'));
|
|
49
48
|
});
|
|
50
49
|
});
|
|
51
50
|
});
|
|
@@ -4,8 +4,8 @@ export default class Activity extends BaseCommand<typeof Activity> {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
number: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces
|
|
8
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment
|
|
7
|
+
number: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
9
|
follow: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
};
|
|
11
11
|
catch(error: Error): Promise<void>;
|
|
@@ -61,7 +61,7 @@ class Activity extends baseCommand_1.BaseCommand {
|
|
|
61
61
|
// Setup the platform client.
|
|
62
62
|
IntegrationsPlatform.setApiKey(apiKey);
|
|
63
63
|
IntegrationsPlatform.setEnvironment(environment);
|
|
64
|
-
core_1.ux.action.start('Finding the integration');
|
|
64
|
+
core_1.ux.action.start('Finding the integration', undefined, { stdout: true });
|
|
65
65
|
let integration;
|
|
66
66
|
try {
|
|
67
67
|
integration = await IntegrationsPlatform.getIntegrationByName(integrationConfiguration.name);
|
|
@@ -77,7 +77,7 @@ class Activity extends baseCommand_1.BaseCommand {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
core_1.ux.action.stop();
|
|
80
|
-
core_1.ux.action.start('Retrieving activity');
|
|
80
|
+
core_1.ux.action.start('Retrieving activity', undefined, { stdout: true });
|
|
81
81
|
let lastEventDate;
|
|
82
82
|
// eslint-disable-next-line no-constant-condition
|
|
83
83
|
while (true) {
|
|
@@ -5,11 +5,11 @@ export default class Dev extends BaseCommand<typeof Dev> {
|
|
|
5
5
|
static examples: string[];
|
|
6
6
|
catch(error: Error): Promise<void>;
|
|
7
7
|
static flags: {
|
|
8
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment
|
|
8
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
9
|
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
crawlMode: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces
|
|
11
|
-
checks: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces
|
|
12
|
-
'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces
|
|
10
|
+
crawlMode: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
checks: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
13
|
};
|
|
14
14
|
run(): Promise<void>;
|
|
15
15
|
}
|
package/dist/src/commands/dev.js
CHANGED
|
@@ -65,12 +65,13 @@ class Dev extends baseCommand_1.BaseCommand {
|
|
|
65
65
|
const configuration = await (0, configuration_1.getConfiguration)(environment, flags['config-path']);
|
|
66
66
|
let credentials = configuration.testAccounts?.[configuration_1.CredentialScope.DEVELOPMENT];
|
|
67
67
|
if (credentials) {
|
|
68
|
-
|
|
68
|
+
credentials = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, credentials)).entries;
|
|
69
69
|
}
|
|
70
70
|
let secrets = {};
|
|
71
71
|
// Decrypt secrets, if necessary.
|
|
72
72
|
if (configuration.secrets) {
|
|
73
|
-
secrets = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets)
|
|
73
|
+
secrets = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets))
|
|
74
|
+
.entries;
|
|
74
75
|
}
|
|
75
76
|
// Launch the debugger.
|
|
76
77
|
const commandArguments = [
|
|
@@ -4,7 +4,7 @@ export default class Encrypt extends BaseCommand<typeof Encrypt> {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment
|
|
7
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
};
|
|
9
9
|
catch(error: Error): Promise<void>;
|
|
10
10
|
run(): Promise<void>;
|
|
@@ -41,7 +41,7 @@ class Encrypt extends baseCommand_1.BaseCommand {
|
|
|
41
41
|
message: 'Enter text to encrypt',
|
|
42
42
|
type: 'input',
|
|
43
43
|
});
|
|
44
|
-
core_1.ux.action.start('Encrypting data');
|
|
44
|
+
core_1.ux.action.start('Encrypting data', undefined, { stdout: true });
|
|
45
45
|
const { encryptedData } = await IntegrationsPlatform.encryptData(integrationConfiguration.name, data);
|
|
46
46
|
core_1.ux.action.stop();
|
|
47
47
|
core_1.ux.log(`Encrypted Data: ${chalk_1.default.greenBright(encryptedData)}`);
|
|
@@ -3,7 +3,7 @@ export default class Init extends BaseCommand<typeof Init> {
|
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
|
-
name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces
|
|
6
|
+
name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
7
|
};
|
|
8
8
|
catch(error: Error): Promise<void>;
|
|
9
9
|
run(): Promise<void>;
|
|
@@ -40,7 +40,7 @@ class Init extends baseCommand_1.BaseCommand {
|
|
|
40
40
|
.replace(/[^a-z0-9_-]*/g, ''),
|
|
41
41
|
},
|
|
42
42
|
])).name;
|
|
43
|
-
core_1.ux.action.start('\nInitializing integration');
|
|
43
|
+
core_1.ux.action.start('\nInitializing integration', undefined, { stdout: true });
|
|
44
44
|
const generatedPath = await integrationGenerator_1.Resources.Integration.generateIntegrationSkeleton(name, process.cwd());
|
|
45
45
|
process.chdir(generatedPath);
|
|
46
46
|
await Configuration.writeConfiguration({ name });
|
|
@@ -4,7 +4,7 @@ export default class Invite extends BaseCommand<typeof Invite> {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment
|
|
7
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
};
|
|
9
9
|
catch(error: Error): Promise<void>;
|
|
10
10
|
run(): Promise<void>;
|
|
@@ -55,7 +55,7 @@ class Invite extends baseCommand_1.BaseCommand {
|
|
|
55
55
|
type: 'input',
|
|
56
56
|
},
|
|
57
57
|
]);
|
|
58
|
-
core_1.ux.action.start('Finding the integration');
|
|
58
|
+
core_1.ux.action.start('Finding the integration', undefined, { stdout: true });
|
|
59
59
|
let integration;
|
|
60
60
|
try {
|
|
61
61
|
integration = await IntegrationsPlatform.getIntegrationByName(integrationConfiguration.name);
|
|
@@ -71,7 +71,7 @@ class Invite extends baseCommand_1.BaseCommand {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
core_1.ux.action.stop();
|
|
74
|
-
core_1.ux.action.start('Inviting user');
|
|
74
|
+
core_1.ux.action.start('Inviting user', undefined, { stdout: true });
|
|
75
75
|
await IntegrationsPlatform.inviteUserToIntegration(integration.id, email);
|
|
76
76
|
core_1.ux.action.stop();
|
|
77
77
|
core_1.ux.log(`User successfully added! They should now be able to update and publish this integration.`);
|
|
@@ -4,7 +4,7 @@ export default class Login extends BaseCommand<typeof Login> {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment
|
|
7
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
};
|
|
9
9
|
catch(error: Error): Promise<void>;
|
|
10
10
|
run(): Promise<void>;
|
|
@@ -46,7 +46,7 @@ class Login extends baseCommand_1.BaseCommand {
|
|
|
46
46
|
this.exit(-1);
|
|
47
47
|
}
|
|
48
48
|
// Retrieve the user's profile.
|
|
49
|
-
core_1.ux.action.start('Log in...');
|
|
49
|
+
core_1.ux.action.start('Log in...', undefined, { stdout: true });
|
|
50
50
|
let profile = undefined;
|
|
51
51
|
IntegrationsPlatform.setEnvironment(environment);
|
|
52
52
|
IntegrationsPlatform.setApiKey(apiKey);
|
|
@@ -5,10 +5,10 @@ export default class Oauth2 extends Command {
|
|
|
5
5
|
static description: string;
|
|
6
6
|
static examples: string[];
|
|
7
7
|
static flags: {
|
|
8
|
-
'test-account': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces
|
|
9
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<Environment
|
|
8
|
+
'test-account': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
10
|
reauth: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces
|
|
11
|
+
'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
12
|
};
|
|
13
13
|
catch(error: Error): Promise<void>;
|
|
14
14
|
run(): Promise<void>;
|
|
@@ -66,8 +66,8 @@ class Oauth2 extends core_1.Command {
|
|
|
66
66
|
const account = testAccount === 'development' ? configuration.testAccounts?.development : configuration.testAccounts?.compliance;
|
|
67
67
|
let credentials;
|
|
68
68
|
if (!account || Object.entries(account).length === 0 || flags.reauth) {
|
|
69
|
-
core_1.ux.action.start(`Starting Oauth2 flow for account: ${testAccount}
|
|
70
|
-
credentials = await Oauth2Helper.performOAuth2Flow(oauth2);
|
|
69
|
+
core_1.ux.action.start(`Starting Oauth2 flow for account: ${testAccount}`, undefined, { stdout: true });
|
|
70
|
+
credentials = await Oauth2Helper.performOAuth2Flow(oauth2, environment);
|
|
71
71
|
core_1.ux.action.stop();
|
|
72
72
|
}
|
|
73
73
|
else {
|
|
@@ -76,7 +76,7 @@ class Oauth2 extends core_1.Command {
|
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
const decryptionResult = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, account);
|
|
79
|
-
core_1.ux.action.start(`Refreshing test account ${testAccount}
|
|
79
|
+
core_1.ux.action.start(`Refreshing test account ${testAccount}`, undefined, { stdout: true });
|
|
80
80
|
credentials = await Oauth2Helper.updateToken({
|
|
81
81
|
...oauth2,
|
|
82
82
|
refreshToken: decryptionResult.entries?.refreshToken,
|
|
@@ -93,7 +93,7 @@ class Oauth2 extends core_1.Command {
|
|
|
93
93
|
}
|
|
94
94
|
core_1.ux.action.stop();
|
|
95
95
|
}
|
|
96
|
-
core_1.ux.action.start(`Saving credentials for account: ${testAccount}
|
|
96
|
+
core_1.ux.action.start(`Saving credentials for account: ${testAccount}`, undefined, { stdout: true });
|
|
97
97
|
await (0, configuration_1.writeTestAccount)(configuration, credentials, testAccount);
|
|
98
98
|
core_1.ux.action.stop();
|
|
99
99
|
return;
|
|
@@ -4,11 +4,11 @@ export default class Publish extends BaseCommand<typeof Publish> {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment
|
|
7
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
'registry-only': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
9
|
preview: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
'live-preview': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces
|
|
11
|
+
'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
12
|
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
13
|
};
|
|
14
14
|
catch(error: Error): Promise<void>;
|
|
@@ -113,7 +113,7 @@ class Publish extends baseCommand_1.BaseCommand {
|
|
|
113
113
|
}
|
|
114
114
|
async livePreviewIntegration(integrationConfiguration) {
|
|
115
115
|
// Get the profile.
|
|
116
|
-
core_1.ux.action.start('Get profile');
|
|
116
|
+
core_1.ux.action.start('Get profile', undefined, { stdout: true });
|
|
117
117
|
const profile = await IntegrationsPlatform.getProfile();
|
|
118
118
|
core_1.ux.action.stop();
|
|
119
119
|
// Generate a new name.
|
|
@@ -131,7 +131,7 @@ class Publish extends baseCommand_1.BaseCommand {
|
|
|
131
131
|
].join(' - ');
|
|
132
132
|
}
|
|
133
133
|
// Start ngrok & update the base url.
|
|
134
|
-
core_1.ux.action.start('Starting ngrok');
|
|
134
|
+
core_1.ux.action.start('Starting ngrok', undefined, { stdout: true });
|
|
135
135
|
updatedConfiguration.baseUrl = await ngrok_1.default.connect(9200);
|
|
136
136
|
core_1.ux.action.stop();
|
|
137
137
|
// Update the registry.
|
|
@@ -164,11 +164,11 @@ class Publish extends baseCommand_1.BaseCommand {
|
|
|
164
164
|
authorization.instructionsMarkdown = await this.getInstructionsMarkdown(authorization.name);
|
|
165
165
|
}
|
|
166
166
|
if (existing) {
|
|
167
|
-
core_1.ux.action.start('Integration found. Updating');
|
|
167
|
+
core_1.ux.action.start('Integration found. Updating', undefined, { stdout: true });
|
|
168
168
|
updated = await IntegrationsPlatform.updateIntegration(existing.id, integrationConfiguration);
|
|
169
169
|
}
|
|
170
170
|
else {
|
|
171
|
-
core_1.ux.action.start('Integration not found. Creating');
|
|
171
|
+
core_1.ux.action.start('Integration not found. Creating', undefined, { stdout: true });
|
|
172
172
|
updated = await IntegrationsPlatform.createIntegration(integrationConfiguration);
|
|
173
173
|
}
|
|
174
174
|
core_1.ux.action.stop();
|
|
@@ -189,7 +189,7 @@ class Publish extends baseCommand_1.BaseCommand {
|
|
|
189
189
|
}
|
|
190
190
|
copyAndMoveToTmpDir() {
|
|
191
191
|
// Copy integration in tmp folder.
|
|
192
|
-
core_1.ux.action.start('Packaging');
|
|
192
|
+
core_1.ux.action.start('Packaging', undefined, { stdout: true });
|
|
193
193
|
const archivePath = this.archiveIntegration();
|
|
194
194
|
const tmpDir = tmp_1.default.dirSync();
|
|
195
195
|
child_process_1.default.execSync(`unzip ${archivePath} -d ${tmpDir.name}`);
|
|
@@ -199,14 +199,14 @@ class Publish extends baseCommand_1.BaseCommand {
|
|
|
199
199
|
}
|
|
200
200
|
async previewIntegration(integrationConfiguration) {
|
|
201
201
|
// Get the profile.
|
|
202
|
-
core_1.ux.action.start('Get profile');
|
|
202
|
+
core_1.ux.action.start('Get profile', undefined, { stdout: true });
|
|
203
203
|
const profile = await IntegrationsPlatform.getProfile();
|
|
204
204
|
core_1.ux.action.stop();
|
|
205
205
|
// Generate a new name.
|
|
206
206
|
const newName = `${integrationConfiguration.name}-preview-${this.hashEmail(profile.email)}`;
|
|
207
207
|
// Update the secrets.
|
|
208
208
|
const updatedConfiguration = await this.generateNewSecrets(integrationConfiguration, newName);
|
|
209
|
-
core_1.ux.action.start('Creating preview');
|
|
209
|
+
core_1.ux.action.start('Creating preview', undefined, { stdout: true });
|
|
210
210
|
// Update the name.
|
|
211
211
|
updatedConfiguration.name = newName;
|
|
212
212
|
// Update the display name.
|
|
@@ -225,20 +225,20 @@ class Publish extends baseCommand_1.BaseCommand {
|
|
|
225
225
|
}
|
|
226
226
|
async publishIntegration(integrationConfiguration) {
|
|
227
227
|
// Packaging the integration.
|
|
228
|
-
core_1.ux.action.start('Packaging');
|
|
228
|
+
core_1.ux.action.start('Packaging', undefined, { stdout: true });
|
|
229
229
|
// Write the final configuration on disk.
|
|
230
230
|
await IntegrationConfiguration.writeConfiguration(integrationConfiguration);
|
|
231
231
|
const archivePath = this.archiveIntegration();
|
|
232
232
|
core_1.ux.action.stop();
|
|
233
233
|
// Publish the integration.
|
|
234
|
-
core_1.ux.action.start('Publishing');
|
|
234
|
+
core_1.ux.action.start('Publishing', undefined, { stdout: true });
|
|
235
235
|
await IntegrationsPlatform.publishIntegration(archivePath);
|
|
236
236
|
core_1.ux.action.stop();
|
|
237
237
|
// Summary of the operation.
|
|
238
238
|
core_1.ux.log('');
|
|
239
239
|
core_1.ux.log(['Your integration', gradient.fruit(integrationConfiguration.name), 'is being published.'].join(' '));
|
|
240
|
-
core_1.ux.log(
|
|
241
|
-
core_1.ux.log(chalk_1.default.blueBright(`
|
|
240
|
+
core_1.ux.log("Note that if the code of your integration did not change, it won't be republished.");
|
|
241
|
+
core_1.ux.log(chalk_1.default.blueBright(`To follow the publication, execute ${chalk_1.default.yellowBright('integration-cli activity --follow')}.`));
|
|
242
242
|
}
|
|
243
243
|
indent(paragraph, tabs = 1) {
|
|
244
244
|
return paragraph
|
|
@@ -258,7 +258,7 @@ class Publish extends baseCommand_1.BaseCommand {
|
|
|
258
258
|
return crypto_1.default.createHash('shake256', { outputLength: 2 }).update(email).digest('hex');
|
|
259
259
|
}
|
|
260
260
|
async generateNewSecrets(integrationConfiguration, newIntegrationName) {
|
|
261
|
-
core_1.ux.action.start(`Reencrypting with name ${newIntegrationName}
|
|
261
|
+
core_1.ux.action.start(`Reencrypting with name ${newIntegrationName}`, undefined, { stdout: true });
|
|
262
262
|
const updatedConfiguration = JSON.parse(JSON.stringify(integrationConfiguration)); // deep copy.
|
|
263
263
|
for (const authorization of updatedConfiguration.authorizations ?? []) {
|
|
264
264
|
/* istanbul ignore if */
|
|
@@ -80,7 +80,7 @@ class Test extends baseCommand_1.BaseCommand {
|
|
|
80
80
|
(0, integrations_1.validateIsIntegrationDirectory)();
|
|
81
81
|
const { flags } = await this.parse(Test);
|
|
82
82
|
// Install NPM dependencies.
|
|
83
|
-
core_1.ux.action.start('Installing NPM dependencies');
|
|
83
|
+
core_1.ux.action.start('Installing NPM dependencies', undefined, { stdout: true });
|
|
84
84
|
child_process_1.default.execSync('npm install', {
|
|
85
85
|
env: { ...process.env, NODE_ENV: 'development' },
|
|
86
86
|
stdio: ['ignore', 'ignore', 'inherit'],
|
|
@@ -94,14 +94,16 @@ class Test extends baseCommand_1.BaseCommand {
|
|
|
94
94
|
if (credentialPayload === null || credentialPayload === undefined) {
|
|
95
95
|
let credentials = configuration.testAccounts?.[flags['test-account']];
|
|
96
96
|
if (credentials) {
|
|
97
|
-
|
|
97
|
+
credentials = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, credentials))
|
|
98
|
+
.entries;
|
|
98
99
|
}
|
|
99
100
|
credentialPayload = JSON.stringify(credentials);
|
|
100
101
|
}
|
|
101
102
|
let secrets = {};
|
|
102
103
|
// Decrypt secrets, if necessary.
|
|
103
104
|
if (configuration.secrets) {
|
|
104
|
-
secrets = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets)
|
|
105
|
+
secrets = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets))
|
|
106
|
+
.entries;
|
|
105
107
|
}
|
|
106
108
|
// Launch the tests.
|
|
107
109
|
const commandArguments = [
|
|
@@ -26,7 +26,7 @@ class Upgrade extends baseCommand_1.BaseCommand {
|
|
|
26
26
|
//
|
|
27
27
|
// Current version
|
|
28
28
|
//
|
|
29
|
-
core_1.ux.action.start('Checking the current version');
|
|
29
|
+
core_1.ux.action.start('Checking the current version', undefined, { stdout: true });
|
|
30
30
|
const currentVersion = child_process_1.default
|
|
31
31
|
.execSync(`npm list ${npmOptions} --depth 0 | grep ${packageName} | sed "s/.*@\\([^@]*\\)$/\\1/"`, execOptions)
|
|
32
32
|
.toString()
|
|
@@ -35,7 +35,7 @@ class Upgrade extends baseCommand_1.BaseCommand {
|
|
|
35
35
|
//
|
|
36
36
|
// Next version
|
|
37
37
|
//
|
|
38
|
-
core_1.ux.action.start('Checking the available version');
|
|
38
|
+
core_1.ux.action.start('Checking the available version', undefined, { stdout: true });
|
|
39
39
|
const newVersion = child_process_1.default
|
|
40
40
|
.execSync(`npm show ${npmOptions} ${packageName} version`, execOptions)
|
|
41
41
|
.toString()
|
|
@@ -51,7 +51,7 @@ class Upgrade extends baseCommand_1.BaseCommand {
|
|
|
51
51
|
//
|
|
52
52
|
// Validate / Upgrade the package globally.
|
|
53
53
|
//
|
|
54
|
-
core_1.ux.action.start(`${latestVersion ? 'Validating' : 'Upgrading'} the package
|
|
54
|
+
core_1.ux.action.start(`${latestVersion ? 'Validating' : 'Upgrading'} the package`, undefined, { stdout: true });
|
|
55
55
|
// To make sure we have a clean version of the CLI, with updated packages, we force the re-installation.
|
|
56
56
|
child_process_1.default.execSync(`npm install --force ${npmOptions} ${packageName}`, {
|
|
57
57
|
...execOptions,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as openUrl from 'openurl';
|
|
2
2
|
import { Oauth2Response, Oauth2Payload } from './types';
|
|
3
|
+
import { Environment } from '../resources/globalConfiguration';
|
|
3
4
|
export declare const open: typeof openUrl;
|
|
4
5
|
declare class OAuth2Helper {
|
|
6
|
+
private environment;
|
|
5
7
|
private server;
|
|
6
8
|
private clientId;
|
|
7
9
|
private clientSecret;
|
|
@@ -24,7 +26,7 @@ declare class OAuth2Helper {
|
|
|
24
26
|
* @param scopes The scopes required for the OAuth authorization.
|
|
25
27
|
* @param providerTokenUrl The URL for the token endpoint of the provider.
|
|
26
28
|
*/
|
|
27
|
-
constructor(authorizationInfo: Oauth2Payload);
|
|
29
|
+
constructor(authorizationInfo: Oauth2Payload, environment?: Environment);
|
|
28
30
|
/**
|
|
29
31
|
* Handles the authorization request and redirects the user to the provider's authorization page.
|
|
30
32
|
* @param req The express Request object.
|
|
@@ -49,7 +51,7 @@ declare class OAuth2Helper {
|
|
|
49
51
|
* Starts the Express server for handling OAuth callbacks.
|
|
50
52
|
* @returns The URL of the server.
|
|
51
53
|
*/
|
|
52
|
-
startServer(): string
|
|
54
|
+
startServer(): Promise<string>;
|
|
53
55
|
/**
|
|
54
56
|
* Stops the Express server.
|
|
55
57
|
*/
|
|
@@ -5,11 +5,15 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const express_1 = tslib_1.__importDefault(require("express"));
|
|
6
6
|
const cors_1 = tslib_1.__importDefault(require("cors"));
|
|
7
7
|
const openUrl = tslib_1.__importStar(require("openurl"));
|
|
8
|
+
const ngrok_1 = tslib_1.__importDefault(require("ngrok"));
|
|
9
|
+
const IntegrationsPlatformClient = tslib_1.__importStar(require("../services/integrationsPlatform"));
|
|
8
10
|
const configurationTypes_1 = require("../configurationTypes");
|
|
9
11
|
const errors_1 = require("../errors");
|
|
12
|
+
const globalConfiguration_1 = require("../resources/globalConfiguration");
|
|
10
13
|
// It allows to stub openUrl library in the test
|
|
11
14
|
exports.open = openUrl;
|
|
12
15
|
class OAuth2Helper {
|
|
16
|
+
environment;
|
|
13
17
|
server = null;
|
|
14
18
|
clientId;
|
|
15
19
|
clientSecret;
|
|
@@ -32,7 +36,7 @@ class OAuth2Helper {
|
|
|
32
36
|
* @param scopes The scopes required for the OAuth authorization.
|
|
33
37
|
* @param providerTokenUrl The URL for the token endpoint of the provider.
|
|
34
38
|
*/
|
|
35
|
-
constructor(authorizationInfo) {
|
|
39
|
+
constructor(authorizationInfo, environment = globalConfiguration_1.Environment.Production) {
|
|
36
40
|
const { clientId, clientSecret, authorizationUrl, scopes, tokenUrl, grantType, requestContentType, responseContentType, refreshToken, refreshRequestParameters, tokenRequestParameters, } = authorizationInfo;
|
|
37
41
|
this.startServer = this.startServer.bind(this);
|
|
38
42
|
this.stopServer = this.stopServer.bind(this);
|
|
@@ -50,6 +54,7 @@ class OAuth2Helper {
|
|
|
50
54
|
this.refreshToken = refreshToken;
|
|
51
55
|
this.tokenRequestParameters = tokenRequestParameters;
|
|
52
56
|
this.refreshRequestParameters = refreshRequestParameters;
|
|
57
|
+
this.environment = environment;
|
|
53
58
|
}
|
|
54
59
|
/**
|
|
55
60
|
* Handles the authorization request and redirects the user to the provider's authorization page.
|
|
@@ -66,14 +71,18 @@ class OAuth2Helper {
|
|
|
66
71
|
if (this.clientId) {
|
|
67
72
|
params.set('client_id', this.clientId);
|
|
68
73
|
}
|
|
69
|
-
params.set('redirect_uri', `${this.
|
|
74
|
+
params.set('redirect_uri', `${IntegrationsPlatformClient.Servers[this.environment]}/credentials/new/oauth2/callback-cli`);
|
|
75
|
+
const state = Buffer.from(JSON.stringify({
|
|
76
|
+
cliCallbackUrl: `${this.serverUrl}/credentials/new/oauth2/callback`,
|
|
77
|
+
})).toString('base64');
|
|
78
|
+
params.set('state', state);
|
|
70
79
|
if (this.scopes) {
|
|
71
80
|
params.set('scope', this.scopes.join(' '));
|
|
72
81
|
}
|
|
73
82
|
params.set('response_type', 'code');
|
|
74
83
|
authUrl.search = params.toString();
|
|
75
84
|
exports.open.open(authUrl.toString());
|
|
76
|
-
res.
|
|
85
|
+
res.sendStatus(200);
|
|
77
86
|
}
|
|
78
87
|
/**
|
|
79
88
|
* Handles the callback request from the provider and stores the authorization code.
|
|
@@ -81,9 +90,16 @@ class OAuth2Helper {
|
|
|
81
90
|
* @param res The express Response object.
|
|
82
91
|
*/
|
|
83
92
|
async handleCallback(req, res) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
try {
|
|
94
|
+
const { code } = req.body.query;
|
|
95
|
+
this.code = code;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
// If we do not receive a code, set it 'error' to let the command know that the callback failed
|
|
99
|
+
console.error('Error during OAuth2 callback', error);
|
|
100
|
+
this.code = 'error';
|
|
101
|
+
}
|
|
102
|
+
res.sendStatus(200);
|
|
87
103
|
}
|
|
88
104
|
encodeBody(bodyData, contentType) {
|
|
89
105
|
switch (contentType) {
|
|
@@ -102,10 +118,13 @@ class OAuth2Helper {
|
|
|
102
118
|
if (!Object.values(configurationTypes_1.RequestContentType).includes(this.requestContentType)) {
|
|
103
119
|
res.status(400).json({ error: `Request content type not supported: ${this.requestContentType}` });
|
|
104
120
|
}
|
|
121
|
+
if (this.code === 'error') {
|
|
122
|
+
throw new errors_1.FailedToRetrieveAccessTokenError('Error during OAuth2 callback - aborting');
|
|
123
|
+
}
|
|
105
124
|
const bodyData = {
|
|
106
125
|
code: this.code,
|
|
107
126
|
grant_type: this.grantType,
|
|
108
|
-
redirect_uri: `${this.
|
|
127
|
+
redirect_uri: `${IntegrationsPlatformClient.Servers[this.environment]}/credentials/new/oauth2/callback-cli`,
|
|
109
128
|
};
|
|
110
129
|
if (this.clientId) {
|
|
111
130
|
bodyData.client_id = this.clientId;
|
|
@@ -184,20 +203,21 @@ class OAuth2Helper {
|
|
|
184
203
|
* @returns The URL of the server.
|
|
185
204
|
*/
|
|
186
205
|
/* istanbul ignore next */
|
|
187
|
-
startServer() {
|
|
206
|
+
async startServer() {
|
|
188
207
|
const app = (0, express_1.default)();
|
|
189
208
|
const PORT = process.env.OAUTH2_PORT ?? 9002;
|
|
209
|
+
this.serverUrl = await ngrok_1.default.connect(Number(PORT));
|
|
190
210
|
app.use((0, cors_1.default)({ credentials: true, origin: true }));
|
|
191
|
-
app.
|
|
211
|
+
app.use(express_1.default.json());
|
|
212
|
+
app.get('/health', (_req, res) => {
|
|
192
213
|
res.send('pong');
|
|
193
214
|
});
|
|
194
215
|
app.get('/credentials/new/oauth2/authorize', this.handleAuthorize);
|
|
195
|
-
app.
|
|
216
|
+
app.post('/credentials/new/oauth2/callback', this.handleCallback);
|
|
196
217
|
app.get('/credentials/new/oauth2/token', this.handleToken);
|
|
197
218
|
this.server = app.listen(PORT, () => {
|
|
198
219
|
console.log(`Listening at port ${PORT}`);
|
|
199
220
|
});
|
|
200
|
-
this.serverUrl = `http://localhost:${PORT}`;
|
|
201
221
|
return this.serverUrl;
|
|
202
222
|
}
|
|
203
223
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { Oauth2Response, Oauth2Payload } from '../oauth2Helper/types';
|
|
2
|
-
|
|
2
|
+
import { Environment } from '../resources/globalConfiguration';
|
|
3
|
+
export declare function performOAuth2Flow(applicationCredentials: Oauth2Payload, environment?: Environment): Promise<Oauth2Response>;
|
|
3
4
|
export declare function updateToken(applicationCredentials: Oauth2Payload): Promise<Oauth2Response>;
|
|
@@ -4,9 +4,10 @@ exports.updateToken = exports.performOAuth2Flow = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const oauth2Helper_1 = tslib_1.__importDefault(require("../oauth2Helper/oauth2Helper"));
|
|
6
6
|
const errors_1 = require("../errors");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
7
|
+
const globalConfiguration_1 = require("../resources/globalConfiguration");
|
|
8
|
+
async function performOAuth2Flow(applicationCredentials, environment = globalConfiguration_1.Environment.Production) {
|
|
9
|
+
const oauthHelper = new oauth2Helper_1.default(applicationCredentials, environment);
|
|
10
|
+
const serverUrl = await oauthHelper.startServer();
|
|
10
11
|
const healthCheck = await fetch(`${serverUrl}/health`);
|
|
11
12
|
if (healthCheck.status !== 200) {
|
|
12
13
|
throw new Error('OAuthServer did not start');
|