@unito/integration-cli 0.55.5 → 0.56.1
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/integrationBoilerplate/.nvmrc +1 -1
- package/dist/integrationGenerator/integrationBoilerplate/Dockerfile +2 -2
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.nvmrc +1 -1
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/Dockerfile +2 -2
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/package.json +2 -2
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +1 -1
- package/dist/integrationGenerator/integrationBoilerplate/package.json +2 -2
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +1 -1
- package/dist/src/commands/activity.js +14 -5
- package/dist/src/commands/dev.js +10 -4
- package/dist/src/commands/encrypt.js +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/invite.js +14 -5
- package/dist/src/commands/login.js +1 -1
- package/dist/src/commands/oauth2.d.ts +6 -1
- package/dist/src/commands/oauth2.js +59 -56
- package/dist/src/commands/publish.js +14 -3
- package/dist/src/commands/test.js +10 -4
- package/dist/src/commands/upgrade.js +1 -1
- package/dist/src/errors.d.ts +4 -1
- package/dist/src/errors.js +47 -37
- package/dist/src/resources/configuration.d.ts +1 -1
- package/dist/src/resources/configuration.js +5 -2
- package/dist/src/resources/decryption.d.ts +10 -4
- package/dist/src/resources/decryption.js +13 -40
- package/dist/src/services/integrationsPlatform.d.ts +1 -1
- package/dist/src/services/integrationsPlatform.js +1 -8
- package/dist/test/commands/activity.test.js +3 -1
- package/dist/test/commands/encrypt.test.js +2 -2
- package/dist/test/commands/invite.test.js +3 -1
- package/dist/test/commands/oauth2.test.js +155 -11
- package/dist/test/commands/publish.test.js +25 -25
- package/dist/test/errors.test.js +45 -40
- package/dist/test/resources/decryption.test.js +28 -19
- package/dist/test/services/integrationsPlatform.test.js +0 -4
- package/oclif.manifest.json +36 -5
- package/package.json +3 -3
package/dist/src/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.handleError = exports.ConfigurationInvalid = exports.EntryDecryptionError = exports.DecryptionAuthenticationError = exports.AuthenticationFailed = exports.MissingApiKey = exports.FileSizeExceeded = exports.MissingCredentialsError = exports.InvalidRequestContentTypeError = exports.FailedToRetrieveAccessTokenError = exports.NoRefreshTokenError = exports.MissingEnvironmentVariableError = exports.ConfigurationMalformed = exports.NoConfigurationFileError = exports.NoIntegrationFoundError = void 0;
|
|
3
|
+
exports.handleError = exports.ConfigurationInvalid = exports.EntryDecryptionError = exports.DecryptionAuthenticationError = exports.AuthenticationFailed = exports.MissingApiKey = exports.FileSizeExceeded = exports.MissingAuth2AuthorizationError = exports.MissingCredentialsError = exports.InvalidRequestContentTypeError = exports.FailedToRetrieveAccessTokenError = exports.NoRefreshTokenError = exports.MissingEnvironmentVariableError = exports.ConfigurationMalformed = exports.NoConfigurationFileError = exports.NoIntegrationFoundError = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const core_1 = require("@oclif/core");
|
|
6
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
@@ -32,6 +32,9 @@ exports.InvalidRequestContentTypeError = InvalidRequestContentTypeError;
|
|
|
32
32
|
class MissingCredentialsError extends Error {
|
|
33
33
|
}
|
|
34
34
|
exports.MissingCredentialsError = MissingCredentialsError;
|
|
35
|
+
class MissingAuth2AuthorizationError extends Error {
|
|
36
|
+
}
|
|
37
|
+
exports.MissingAuth2AuthorizationError = MissingAuth2AuthorizationError;
|
|
35
38
|
class FileSizeExceeded extends Error {
|
|
36
39
|
}
|
|
37
40
|
exports.FileSizeExceeded = FileSizeExceeded;
|
|
@@ -71,87 +74,94 @@ class ConfigurationInvalid extends Error {
|
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
exports.ConfigurationInvalid = ConfigurationInvalid;
|
|
74
|
-
function handleError(error) {
|
|
77
|
+
function handleError(command, error) {
|
|
75
78
|
/* istanbul ignore if */
|
|
76
79
|
if (core_1.ux.action.running) {
|
|
77
80
|
core_1.ux.action.stop(chalk_1.default.redBright('failed'));
|
|
78
81
|
}
|
|
79
82
|
let handled = false;
|
|
80
83
|
if (error instanceof NoIntegrationFoundError) {
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
command.logToStderr(chalk_1.default.redBright('Your directory does not seem to contain an integration :('));
|
|
85
|
+
command.logToStderr(`Make sure you are in the right directory and that you have a ${chalk_1.default.yellowBright(configuration_1.DEFAULT_CONFIGURATION_NAME)} file.`);
|
|
83
86
|
handled = true;
|
|
84
87
|
}
|
|
85
88
|
else if (error instanceof NoConfigurationFileError) {
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
command.logToStderr(chalk_1.default.redBright('This command requires a configuration file for your integration :('));
|
|
90
|
+
command.logToStderr(`This file should be located at ${chalk_1.default.yellowBright(path_1.default.relative(process.cwd(), (0, configuration_1.getConfigurationPath)()))}.`);
|
|
88
91
|
handled = true;
|
|
89
92
|
}
|
|
90
93
|
else if (error instanceof MissingEnvironmentVariableError) {
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
command.logToStderr(chalk_1.default.redBright('This command requires a variable which is missing from your environment :('));
|
|
95
|
+
command.logToStderr(`Make sure the environment variable ${chalk_1.default.yellowBright(error.message)} is defined.`);
|
|
93
96
|
handled = true;
|
|
94
97
|
}
|
|
95
98
|
else if (error instanceof ConfigurationMalformed) {
|
|
96
|
-
|
|
99
|
+
command.logToStderr(chalk_1.default.redBright(`Your ${chalk_1.default.yellowBright(configuration_1.DEFAULT_CONFIGURATION_NAME)} was found but its not a valid JSON file!`));
|
|
97
100
|
handled = true;
|
|
98
101
|
}
|
|
99
102
|
else if (error instanceof ConfigurationInvalid) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
command.logToStderr(chalk_1.default.redBright(`Your ${chalk_1.default.yellowBright(configuration_1.DEFAULT_CONFIGURATION_NAME)} is invalid!`));
|
|
104
|
+
command.logToStderr();
|
|
105
|
+
command.logToStderr(error.prettyDetails);
|
|
103
106
|
handled = true;
|
|
104
107
|
}
|
|
105
108
|
else if (error instanceof NoRefreshTokenError) {
|
|
106
|
-
|
|
109
|
+
command.logToStderr(chalk_1.default.redBright('No refresh token found in your configuration file'));
|
|
107
110
|
handled = true;
|
|
108
111
|
}
|
|
109
112
|
else if (error instanceof FailedToRetrieveAccessTokenError) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
command.logToStderr(chalk_1.default.redBright('Failed to retrieve access token'));
|
|
114
|
+
command.logToStderr();
|
|
115
|
+
command.logToStderr(error.message);
|
|
113
116
|
handled = true;
|
|
114
117
|
}
|
|
115
118
|
else if (error instanceof InvalidRequestContentTypeError) {
|
|
116
|
-
|
|
119
|
+
command.logToStderr(chalk_1.default.redBright('Invalid request content type'));
|
|
117
120
|
handled = true;
|
|
118
|
-
|
|
119
|
-
|
|
121
|
+
command.logToStderr();
|
|
122
|
+
command.logToStderr(error.message);
|
|
120
123
|
}
|
|
121
124
|
else if (error instanceof integrationsPlatform_1.HttpError) {
|
|
122
125
|
handled = true;
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
command.logToStderr();
|
|
127
|
+
command.logToStderr((0, json_colorizer_1.default)(JSON.stringify(error.data, null, 2)));
|
|
125
128
|
}
|
|
126
129
|
else if (error instanceof MissingCredentialsError) {
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
command.logToStderr();
|
|
131
|
+
command.logToStderr(chalk_1.default.redBright('The credentials are missing from your configuration file'));
|
|
129
132
|
handled = true;
|
|
130
133
|
}
|
|
131
134
|
else if (error instanceof MissingApiKey) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
command.logToStderr();
|
|
136
|
+
command.logToStderr(chalk_1.default.redBright('Your API key is not set!'));
|
|
137
|
+
command.logToStderr(`Make sure to run the ${chalk_1.default.yellowBright('login')} command first`);
|
|
135
138
|
handled = true;
|
|
136
139
|
}
|
|
137
140
|
else if (error instanceof AuthenticationFailed) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
command.logToStderr();
|
|
142
|
+
command.logToStderr(chalk_1.default.redBright('This command requires that you are logged to Unito!'));
|
|
143
|
+
command.logToStderr(`Make sure to run the ${chalk_1.default.yellowBright('login')} command first`);
|
|
141
144
|
handled = true;
|
|
142
145
|
}
|
|
143
146
|
else if (error instanceof DecryptionAuthenticationError) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
command.logToStderr();
|
|
148
|
+
command.logToStderr(chalk_1.default.yellowBright(`Your configuration contains encrypted ${error.encryptedEntityName}.`));
|
|
149
|
+
command.logToStderr('To use them locally, you must be authenticated to Unito.');
|
|
147
150
|
handled = true;
|
|
148
151
|
}
|
|
149
152
|
else if (error instanceof EntryDecryptionError) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
command.logToStderr();
|
|
154
|
+
command.logToStderr(chalk_1.default.yellowBright(`Error decrypting entry:`));
|
|
155
|
+
command.logToStderr(chalk_1.default.redBright(`${error.key}: ${error.value}`));
|
|
156
|
+
command.logToStderr();
|
|
157
|
+
command.logToStderr(`Make sure they were encrypted by the same environement (Currently targeting: ${error.environment}).`);
|
|
158
|
+
handled = true;
|
|
159
|
+
}
|
|
160
|
+
else if (error instanceof MissingAuth2AuthorizationError) {
|
|
161
|
+
command.logToStderr();
|
|
162
|
+
command.logToStderr(chalk_1.default.redBright(`No Oauth2 authorization found in your configuration file`));
|
|
163
|
+
// TODO: Update link once the documentation is made available publicly
|
|
164
|
+
command.logToStderr('See https://staging-dev.unito.io/docs/integrations/configuration/authorizations#oauth-2 for more information on how to configure Oauth2');
|
|
155
165
|
handled = true;
|
|
156
166
|
}
|
|
157
167
|
return handled;
|
|
@@ -23,7 +23,7 @@ export declare function getConfiguration(environment: Environment, customConfigP
|
|
|
23
23
|
/**
|
|
24
24
|
* Write the configuration to the default configuration file.
|
|
25
25
|
*/
|
|
26
|
-
export declare function writeConfiguration(configuration: Configuration): Promise<void>;
|
|
26
|
+
export declare function writeConfiguration(configuration: Configuration, environment?: Environment, customConfigPath?: string): Promise<void>;
|
|
27
27
|
export declare function writeTestAccount(configuration: Configuration, account: {
|
|
28
28
|
accessToken: string;
|
|
29
29
|
refreshToken?: string;
|
|
@@ -88,10 +88,13 @@ exports.getConfiguration = getConfiguration;
|
|
|
88
88
|
/**
|
|
89
89
|
* Write the configuration to the default configuration file.
|
|
90
90
|
*/
|
|
91
|
-
async function writeConfiguration(configuration) {
|
|
91
|
+
async function writeConfiguration(configuration, environment = globalConfiguration_1.Environment.Production, customConfigPath) {
|
|
92
92
|
(0, integrations_1.validateIsIntegrationDirectory)();
|
|
93
93
|
await validateConfiguration(configuration);
|
|
94
|
-
|
|
94
|
+
const configurationPath = customConfigPath
|
|
95
|
+
? `${process.cwd()}${customConfigPath.startsWith('/') ? customConfigPath : `/${customConfigPath}`}`
|
|
96
|
+
: getConfigurationPath(environment);
|
|
97
|
+
await fs.promises.writeFile(configurationPath, JSON.stringify(configuration, null, 2));
|
|
95
98
|
}
|
|
96
99
|
exports.writeConfiguration = writeConfiguration;
|
|
97
100
|
async function writeTestAccount(configuration, account, accountName) {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { Configuration } from '../configurationTypes';
|
|
2
1
|
import * as GlobalConfiguration from './globalConfiguration';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Object returned when decrypting
|
|
4
|
+
*
|
|
5
|
+
* Allows the caller to know which keys were decrypted to reencrypt them later as needed
|
|
6
|
+
*/
|
|
7
|
+
export type DecryptionResult = {
|
|
8
|
+
decryptedKeys: string[];
|
|
9
|
+
entries: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
export declare function decryptEntries(configurationName: string, environment: GlobalConfiguration.Environment, configDir: string, entries: Record<string, unknown>, fieldName?: string): Promise<DecryptionResult>;
|
|
@@ -1,62 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.decryptEntries = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const errors_1 = require("../errors");
|
|
6
6
|
const GlobalConfiguration = tslib_1.__importStar(require("./globalConfiguration"));
|
|
7
7
|
const integrationsPlatform_1 = require("./integrationsPlatform");
|
|
8
8
|
const configuration_1 = require("./configuration");
|
|
9
9
|
const integrationsPlatform_2 = require("../services/integrationsPlatform");
|
|
10
|
-
async function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return {};
|
|
14
|
-
}
|
|
15
|
-
// Get encrypted credential entries
|
|
16
|
-
const encryptedEntries = Object.entries(credentials).filter((entry) => typeof entry[1] === 'string' && entry[1].startsWith(configuration_1.ENCRYPTION_PREFIX));
|
|
10
|
+
async function decryptEntries(configurationName, environment, configDir, entries, fieldName = 'entries') {
|
|
11
|
+
// Get encrypted entries
|
|
12
|
+
const encryptedEntries = Object.entries(entries).filter((entry) => typeof entry[1] === 'string' && entry[1].startsWith(configuration_1.ENCRYPTION_PREFIX));
|
|
17
13
|
if (!encryptedEntries.length) {
|
|
18
|
-
return
|
|
19
|
-
}
|
|
20
|
-
// Copy credentials to avoid mutating the configuration.
|
|
21
|
-
const decryptedCredentials = structuredClone(credentials);
|
|
22
|
-
const globalConfiguration = await GlobalConfiguration.read(configDir);
|
|
23
|
-
try {
|
|
24
|
-
await (0, integrationsPlatform_1.validateAuthenticated)(globalConfiguration, environment);
|
|
25
|
-
}
|
|
26
|
-
catch (err) {
|
|
27
|
-
throw new errors_1.DecryptionAuthenticationError('credentials');
|
|
28
|
-
}
|
|
29
|
-
for (const [key, encryptedCredential] of encryptedEntries) {
|
|
30
|
-
try {
|
|
31
|
-
decryptedCredentials[key] = (await (0, integrationsPlatform_2.decryptData)(configuration.name, encryptedCredential)).decryptedData;
|
|
32
|
-
}
|
|
33
|
-
catch (err) {
|
|
34
|
-
throw new errors_1.EntryDecryptionError(key, encryptedCredential, environment);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return decryptedCredentials;
|
|
38
|
-
}
|
|
39
|
-
exports.decryptTestAccountCredentials = decryptTestAccountCredentials;
|
|
40
|
-
async function decryptSecrets(configuration, environment, configDir) {
|
|
41
|
-
if (!Object.entries(configuration.secrets ?? {}).length) {
|
|
42
|
-
return {};
|
|
14
|
+
return { decryptedKeys: [], entries };
|
|
43
15
|
}
|
|
44
16
|
const globalConfiguration = await GlobalConfiguration.read(configDir);
|
|
45
17
|
try {
|
|
46
18
|
await (0, integrationsPlatform_1.validateAuthenticated)(globalConfiguration, environment);
|
|
47
19
|
}
|
|
48
20
|
catch (err) {
|
|
49
|
-
throw new errors_1.DecryptionAuthenticationError(
|
|
21
|
+
throw new errors_1.DecryptionAuthenticationError(fieldName);
|
|
50
22
|
}
|
|
51
|
-
|
|
52
|
-
|
|
23
|
+
// Copy credentials to avoid mutating the configuration.
|
|
24
|
+
const decryptedEntries = structuredClone(entries);
|
|
25
|
+
for (const [key, encryptedEntry] of encryptedEntries) {
|
|
53
26
|
try {
|
|
54
|
-
|
|
27
|
+
decryptedEntries[key] = (await (0, integrationsPlatform_2.decryptData)(configurationName, encryptedEntry)).decryptedData;
|
|
55
28
|
}
|
|
56
29
|
catch (err) {
|
|
57
|
-
throw new errors_1.EntryDecryptionError(key,
|
|
30
|
+
throw new errors_1.EntryDecryptionError(key, encryptedEntry, environment);
|
|
58
31
|
}
|
|
59
32
|
}
|
|
60
|
-
return
|
|
33
|
+
return { decryptedKeys: encryptedEntries.map(([key]) => key), entries: decryptedEntries };
|
|
61
34
|
}
|
|
62
|
-
exports.
|
|
35
|
+
exports.decryptEntries = decryptEntries;
|
|
@@ -27,7 +27,7 @@ export declare function reencryptData(integrationName: string, encryptedData: st
|
|
|
27
27
|
encryptedData: string;
|
|
28
28
|
}>;
|
|
29
29
|
export declare function getIntegration(integrationId: number): Promise<Integration>;
|
|
30
|
-
export declare function getIntegrationByName(integrationName: string): Promise<Integration
|
|
30
|
+
export declare function getIntegrationByName(integrationName: string): Promise<Integration>;
|
|
31
31
|
export declare function getIntegrations(): Promise<IntegrationSummary[]>;
|
|
32
32
|
export declare function publishIntegration(archivePath: string): Promise<Integration>;
|
|
33
33
|
export declare function createIntegration(configuration: Configuration): Promise<Integration>;
|
|
@@ -62,14 +62,7 @@ async function getIntegration(integrationId) {
|
|
|
62
62
|
}
|
|
63
63
|
exports.getIntegration = getIntegration;
|
|
64
64
|
async function getIntegrationByName(integrationName) {
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
integration = await integrations_platform_client_1.default.getIntegrationByName(integrationName);
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
return integration;
|
|
65
|
+
return integrations_platform_client_1.default.getIntegrationByName(integrationName);
|
|
73
66
|
}
|
|
74
67
|
exports.getIntegrationByName = getIntegrationByName;
|
|
75
68
|
async function getIntegrations() {
|
|
@@ -53,7 +53,9 @@ describe('activity', () => {
|
|
|
53
53
|
});
|
|
54
54
|
test_1.test
|
|
55
55
|
.stdout()
|
|
56
|
-
.stub(IntegrationsPlatform, 'getIntegrationByName', () =>
|
|
56
|
+
.stub(IntegrationsPlatform, 'getIntegrationByName', () => {
|
|
57
|
+
throw new Error();
|
|
58
|
+
})
|
|
57
59
|
.command(['activity'])
|
|
58
60
|
.catch(error => {
|
|
59
61
|
(0, test_1.expect)(error.message).to.equal('EEXIT: -1');
|
|
@@ -53,12 +53,12 @@ describe('encrypt', () => {
|
|
|
53
53
|
(0, test_1.expect)(ctx.stdout).to.contains('Encrypted Data:');
|
|
54
54
|
});
|
|
55
55
|
test_1.test
|
|
56
|
-
.
|
|
56
|
+
.stderr()
|
|
57
57
|
.stub(GlobalConfiguration, 'read', () => ({}))
|
|
58
58
|
.command(['encrypt'])
|
|
59
59
|
.exit(-1)
|
|
60
60
|
.it('missing api key', ctx => {
|
|
61
|
-
(0, test_1.expect)(ctx.
|
|
61
|
+
(0, test_1.expect)(ctx.stderr).to.contain('Your API key is not set!\nMake sure to run the login command first');
|
|
62
62
|
});
|
|
63
63
|
test_1.test
|
|
64
64
|
.stdout()
|
|
@@ -47,7 +47,9 @@ describe('invite', () => {
|
|
|
47
47
|
test_1.test
|
|
48
48
|
.stdout()
|
|
49
49
|
.stub(GlobalConfiguration, 'read', () => ({ email: 'foo@bar.com' }))
|
|
50
|
-
.stub(IntegrationsPlatform, 'getIntegrationByName', () =>
|
|
50
|
+
.stub(IntegrationsPlatform, 'getIntegrationByName', () => {
|
|
51
|
+
throw new Error();
|
|
52
|
+
})
|
|
51
53
|
.command(['invite'])
|
|
52
54
|
.catch(error => {
|
|
53
55
|
(0, test_1.expect)(error.message).to.equal('EEXIT: -1');
|
|
@@ -7,12 +7,13 @@ const sinon = tslib_1.__importStar(require("sinon"));
|
|
|
7
7
|
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
8
8
|
const Configuration = tslib_1.__importStar(require("../../src/resources/configuration"));
|
|
9
9
|
const oauth2Service = tslib_1.__importStar(require("../../src/services/oauth2Helper"));
|
|
10
|
+
const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/integrationsPlatform"));
|
|
11
|
+
const decryptionResource = tslib_1.__importStar(require("../../src/resources/decryption"));
|
|
10
12
|
const configurationTypes_1 = require("../../src/configurationTypes");
|
|
11
13
|
describe('oauth2', () => {
|
|
12
14
|
const INTEGRATION_NAME = 'myintegration';
|
|
13
15
|
const sandbox = sinon.createSandbox();
|
|
14
16
|
let getConfigurationsStub;
|
|
15
|
-
let writeConfigurationStub;
|
|
16
17
|
let writeTestAccountStub;
|
|
17
18
|
let performOAuth2FlowStub;
|
|
18
19
|
let updateTokenStub;
|
|
@@ -30,7 +31,7 @@ describe('oauth2', () => {
|
|
|
30
31
|
name: INTEGRATION_NAME,
|
|
31
32
|
authorizations: [
|
|
32
33
|
{
|
|
33
|
-
name: '
|
|
34
|
+
name: 'MyAuthorization',
|
|
34
35
|
method: configurationTypes_1.Method.OAUTH2,
|
|
35
36
|
oauth2: oauth2Information,
|
|
36
37
|
},
|
|
@@ -48,7 +49,6 @@ describe('oauth2', () => {
|
|
|
48
49
|
sandbox.stub(inquirer_1.default, 'prompt').resolves({
|
|
49
50
|
oauth2Information: JSON.stringify(oauth2Information),
|
|
50
51
|
});
|
|
51
|
-
writeConfigurationStub = sandbox.stub(Configuration, 'writeConfiguration');
|
|
52
52
|
writeTestAccountStub = sandbox.stub(Configuration, 'writeTestAccount');
|
|
53
53
|
performOAuth2FlowStub = sandbox.stub(oauth2Service, 'performOAuth2Flow');
|
|
54
54
|
performOAuth2FlowStub.resolves(credentials);
|
|
@@ -63,16 +63,48 @@ describe('oauth2', () => {
|
|
|
63
63
|
...baseConfiguration,
|
|
64
64
|
authorizations: [],
|
|
65
65
|
}))
|
|
66
|
-
.command(['oauth2', '--
|
|
67
|
-
.
|
|
68
|
-
(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
.command(['oauth2', '--test-account', 'development'])
|
|
67
|
+
.exit(-1)
|
|
68
|
+
.it("Errors out if no oauth2 authorization scheme is found in the integration's configuration");
|
|
69
|
+
test_1.test
|
|
70
|
+
.stdout()
|
|
71
|
+
.do(() => getConfigurationsStub.returns({
|
|
72
|
+
...baseConfiguration,
|
|
73
|
+
authorizations: [
|
|
74
|
+
...(baseConfiguration.authorizations ?? []),
|
|
75
|
+
{
|
|
76
|
+
name: 'Development Authorization',
|
|
77
|
+
method: configurationTypes_1.Method.OAUTH2,
|
|
78
|
+
oauth2: { ...oauth2Information, clientId: 'devClientID' },
|
|
79
|
+
development: true,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
}))
|
|
83
|
+
.command(['oauth2', '--test-account', 'development'])
|
|
84
|
+
.it('prioritize development authorization', () => {
|
|
85
|
+
(0, test_1.expect)(performOAuth2FlowStub.getCalls().length).to.equal(1);
|
|
86
|
+
(0, test_1.expect)(performOAuth2FlowStub.getCall(0).args).to.deep.equal([{ ...oauth2Information, clientId: 'devClientID' }]);
|
|
87
|
+
(0, test_1.expect)(updateTokenStub.getCalls().length).to.equal(0);
|
|
88
|
+
(0, test_1.expect)(writeTestAccountStub.getCall(0).args).to.deep.equal([
|
|
89
|
+
{
|
|
90
|
+
...baseConfiguration,
|
|
91
|
+
authorizations: [
|
|
92
|
+
...(baseConfiguration.authorizations ?? []),
|
|
93
|
+
{
|
|
94
|
+
name: 'Development Authorization',
|
|
95
|
+
method: configurationTypes_1.Method.OAUTH2,
|
|
96
|
+
oauth2: { ...oauth2Information, clientId: 'devClientID' },
|
|
97
|
+
development: true,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
credentials,
|
|
102
|
+
'development',
|
|
103
|
+
]);
|
|
72
104
|
});
|
|
73
105
|
test_1.test
|
|
74
106
|
.stdout()
|
|
75
|
-
.command(['oauth2', '--
|
|
107
|
+
.command(['oauth2', '--test-account', 'development'])
|
|
76
108
|
.it('performs the oauth flow when there is no test accounts and the auth information are setup', () => {
|
|
77
109
|
(0, test_1.expect)(performOAuth2FlowStub.getCalls().length).to.equal(1);
|
|
78
110
|
(0, test_1.expect)(updateTokenStub.getCalls().length).to.equal(0);
|
|
@@ -86,7 +118,53 @@ describe('oauth2', () => {
|
|
|
86
118
|
development: credentials,
|
|
87
119
|
},
|
|
88
120
|
}))
|
|
89
|
-
.command(['oauth2', '--
|
|
121
|
+
.command(['oauth2', '--test-account', 'development', '--reauth'])
|
|
122
|
+
.it('performs the oauth flow when there is a test accounts, the auth information are setup and --reauth flag is present', () => {
|
|
123
|
+
(0, test_1.expect)(performOAuth2FlowStub.getCalls().length).to.equal(1);
|
|
124
|
+
(0, test_1.expect)(updateTokenStub.getCalls().length).to.equal(0);
|
|
125
|
+
(0, test_1.expect)(writeTestAccountStub.getCall(0).args).to.deep.equal([
|
|
126
|
+
{
|
|
127
|
+
...baseConfiguration,
|
|
128
|
+
testAccounts: {
|
|
129
|
+
development: credentials,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
credentials,
|
|
133
|
+
'development',
|
|
134
|
+
]);
|
|
135
|
+
});
|
|
136
|
+
test_1.test
|
|
137
|
+
.stdout()
|
|
138
|
+
.do(() => getConfigurationsStub.returns({
|
|
139
|
+
...baseConfiguration,
|
|
140
|
+
testAccounts: {
|
|
141
|
+
development: { something: 'something' },
|
|
142
|
+
},
|
|
143
|
+
}))
|
|
144
|
+
.command(['oauth2', '--test-account', 'compliance'])
|
|
145
|
+
.it('performs the oauth flow when the requested test account is not setup', () => {
|
|
146
|
+
(0, test_1.expect)(performOAuth2FlowStub.getCalls().length).to.equal(1);
|
|
147
|
+
(0, test_1.expect)(updateTokenStub.getCalls().length).to.equal(0);
|
|
148
|
+
(0, test_1.expect)(writeTestAccountStub.getCall(0).args).to.deep.equal([
|
|
149
|
+
{
|
|
150
|
+
...baseConfiguration,
|
|
151
|
+
testAccounts: {
|
|
152
|
+
development: { something: 'something' },
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
credentials,
|
|
156
|
+
'compliance',
|
|
157
|
+
]);
|
|
158
|
+
});
|
|
159
|
+
test_1.test
|
|
160
|
+
.stdout()
|
|
161
|
+
.do(() => getConfigurationsStub.returns({
|
|
162
|
+
...baseConfiguration,
|
|
163
|
+
testAccounts: {
|
|
164
|
+
development: credentials,
|
|
165
|
+
},
|
|
166
|
+
}))
|
|
167
|
+
.command(['oauth2', '--test-account', 'development'])
|
|
90
168
|
.it('refresh the token when there is an existing test accounts and the auth information are setup', () => {
|
|
91
169
|
(0, test_1.expect)(performOAuth2FlowStub.getCalls().length).to.equal(0);
|
|
92
170
|
(0, test_1.expect)(updateTokenStub.getCalls().length).to.equal(1);
|
|
@@ -101,4 +179,70 @@ describe('oauth2', () => {
|
|
|
101
179
|
'development',
|
|
102
180
|
]);
|
|
103
181
|
});
|
|
182
|
+
test_1.test
|
|
183
|
+
.stdout()
|
|
184
|
+
.do(() => {
|
|
185
|
+
getConfigurationsStub.returns({
|
|
186
|
+
...baseConfiguration,
|
|
187
|
+
authorizations: [
|
|
188
|
+
{
|
|
189
|
+
name: 'Authorization',
|
|
190
|
+
method: configurationTypes_1.Method.OAUTH2,
|
|
191
|
+
oauth2: { ...oauth2Information, clientSecret: `${Configuration.ENCRYPTION_PREFIX}devClientID` },
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
testAccounts: {
|
|
195
|
+
development: {
|
|
196
|
+
accessToken: `${Configuration.ENCRYPTION_PREFIX}devAccessToken`,
|
|
197
|
+
refreshToken: `${Configuration.ENCRYPTION_PREFIX}devRefreshToken`,
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
sandbox
|
|
202
|
+
.stub(decryptionResource, 'decryptEntries')
|
|
203
|
+
.onFirstCall()
|
|
204
|
+
.resolves({ decryptedKeys: ['clientSecret'], entries: { ...oauth2Information, clientSecret: 'devClientID' } })
|
|
205
|
+
.onSecondCall()
|
|
206
|
+
.resolves({
|
|
207
|
+
decryptedKeys: ['accessToken', 'refreshToken'],
|
|
208
|
+
entries: {
|
|
209
|
+
accessToken: 'devAccessToken',
|
|
210
|
+
refreshToken: 'devRefreshToken',
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
sandbox
|
|
214
|
+
.stub(IntegrationsPlatform, 'encryptData')
|
|
215
|
+
.onFirstCall()
|
|
216
|
+
.resolves({ encryptedData: `${Configuration.ENCRYPTION_PREFIX}encryptedAccessToken` })
|
|
217
|
+
.onSecondCall()
|
|
218
|
+
.resolves({ encryptedData: `${Configuration.ENCRYPTION_PREFIX}encryptedRefreshToken` });
|
|
219
|
+
})
|
|
220
|
+
.command(['oauth2', '--test-account', 'development'])
|
|
221
|
+
.it('decrypt oauth2 authorization entries and test-account', () => {
|
|
222
|
+
(0, test_1.expect)(performOAuth2FlowStub.getCalls().length).to.equal(0);
|
|
223
|
+
(0, test_1.expect)(updateTokenStub.getCalls().length).to.equal(1);
|
|
224
|
+
(0, test_1.expect)(writeTestAccountStub.getCall(0).args).to.deep.equal([
|
|
225
|
+
{
|
|
226
|
+
...baseConfiguration,
|
|
227
|
+
authorizations: [
|
|
228
|
+
{
|
|
229
|
+
name: 'Authorization',
|
|
230
|
+
method: configurationTypes_1.Method.OAUTH2,
|
|
231
|
+
oauth2: { ...oauth2Information, clientSecret: `${Configuration.ENCRYPTION_PREFIX}devClientID` },
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
testAccounts: {
|
|
235
|
+
development: {
|
|
236
|
+
accessToken: `${Configuration.ENCRYPTION_PREFIX}devAccessToken`,
|
|
237
|
+
refreshToken: `${Configuration.ENCRYPTION_PREFIX}devRefreshToken`,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
accessToken: `${Configuration.ENCRYPTION_PREFIX}encryptedAccessToken`,
|
|
243
|
+
refreshToken: `${Configuration.ENCRYPTION_PREFIX}encryptedRefreshToken`,
|
|
244
|
+
},
|
|
245
|
+
'development',
|
|
246
|
+
]);
|
|
247
|
+
});
|
|
104
248
|
});
|