@unito/integration-cli 0.55.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.
Files changed (150) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +32 -0
  3. package/bin/run +11 -0
  4. package/bin/run.cmd +3 -0
  5. package/dist/.eslintrc.d.ts +10 -0
  6. package/dist/.eslintrc.js +20 -0
  7. package/dist/integrationGenerator/errors.d.ts +2 -0
  8. package/dist/integrationGenerator/errors.js +6 -0
  9. package/dist/integrationGenerator/index.d.ts +2 -0
  10. package/dist/integrationGenerator/index.js +5 -0
  11. package/dist/integrationGenerator/integrationBoilerplate/.dockerignore +3 -0
  12. package/dist/integrationGenerator/integrationBoilerplate/.eslintrc.js +74 -0
  13. package/dist/integrationGenerator/integrationBoilerplate/.nvmrc +1 -0
  14. package/dist/integrationGenerator/integrationBoilerplate/.prettierignore +1 -0
  15. package/dist/integrationGenerator/integrationBoilerplate/.prettierrc +7 -0
  16. package/dist/integrationGenerator/integrationBoilerplate/.unito.json +1 -0
  17. package/dist/integrationGenerator/integrationBoilerplate/Dockerfile +38 -0
  18. package/dist/integrationGenerator/integrationBoilerplate/README.md +21 -0
  19. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.dockerignore +3 -0
  20. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.eslintrc.js +74 -0
  21. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.nvmrc +1 -0
  22. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierignore +1 -0
  23. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierrc +7 -0
  24. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.unito.json +1 -0
  25. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/Dockerfile +38 -0
  26. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/README.md +21 -0
  27. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/package.json +43 -0
  28. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/index.ts +94 -0
  29. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/logger.ts +55 -0
  30. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +22 -0
  31. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/middlewares/correlationId.ts +13 -0
  32. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/middlewares/credentials.ts +38 -0
  33. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/request.ts +59 -0
  34. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/routes/index.ts +11 -0
  35. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/routes/me.ts +15 -0
  36. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/routes/root.ts +12 -0
  37. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/tsconfig.json +37 -0
  38. package/dist/integrationGenerator/integrationBoilerplate/package.json +43 -0
  39. package/dist/integrationGenerator/integrationBoilerplate/src/index.ts +90 -0
  40. package/dist/integrationGenerator/integrationBoilerplate/src/logger.ts +37 -0
  41. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/correlationId.ts +18 -0
  42. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/credentials.ts +38 -0
  43. package/dist/integrationGenerator/integrationBoilerplate/src/request.ts +59 -0
  44. package/dist/integrationGenerator/integrationBoilerplate/src/routes/index.ts +11 -0
  45. package/dist/integrationGenerator/integrationBoilerplate/src/routes/me.ts +15 -0
  46. package/dist/integrationGenerator/integrationBoilerplate/src/routes/root.ts +12 -0
  47. package/dist/integrationGenerator/integrationBoilerplate/tsconfig.json +37 -0
  48. package/dist/integrationGenerator/src/index.d.ts +1 -0
  49. package/dist/integrationGenerator/src/index.js +5 -0
  50. package/dist/integrationGenerator/src/resources/index.d.ts +1 -0
  51. package/dist/integrationGenerator/src/resources/index.js +5 -0
  52. package/dist/integrationGenerator/src/resources/integration.d.ts +9 -0
  53. package/dist/integrationGenerator/src/resources/integration.js +60 -0
  54. package/dist/integrationGenerator/test/resources/integration.test.d.ts +1 -0
  55. package/dist/integrationGenerator/test/resources/integration.test.js +51 -0
  56. package/dist/schemas/authorization.json +204 -0
  57. package/dist/schemas/automation.json +81 -0
  58. package/dist/schemas/configuration.json +89 -0
  59. package/dist/scripts/generateTypes.d.ts +8 -0
  60. package/dist/scripts/generateTypes.js +44 -0
  61. package/dist/src/baseCommand.d.ts +14 -0
  62. package/dist/src/baseCommand.js +39 -0
  63. package/dist/src/commands/activity.d.ts +12 -0
  64. package/dist/src/commands/activity.js +75 -0
  65. package/dist/src/commands/dev.d.ts +15 -0
  66. package/dist/src/commands/dev.js +123 -0
  67. package/dist/src/commands/encrypt.d.ts +11 -0
  68. package/dist/src/commands/encrypt.js +50 -0
  69. package/dist/src/commands/init.d.ts +10 -0
  70. package/dist/src/commands/init.js +51 -0
  71. package/dist/src/commands/invite.d.ts +11 -0
  72. package/dist/src/commands/invite.js +71 -0
  73. package/dist/src/commands/login.d.ts +11 -0
  74. package/dist/src/commands/login.js +76 -0
  75. package/dist/src/commands/oauth2.d.ts +10 -0
  76. package/dist/src/commands/oauth2.js +99 -0
  77. package/dist/src/commands/publish.d.ts +28 -0
  78. package/dist/src/commands/publish.js +302 -0
  79. package/dist/src/commands/test.d.ts +9 -0
  80. package/dist/src/commands/test.js +165 -0
  81. package/dist/src/commands/upgrade.d.ts +7 -0
  82. package/dist/src/commands/upgrade.js +88 -0
  83. package/dist/src/configurationTypes.d.ts +209 -0
  84. package/dist/src/configurationTypes.js +49 -0
  85. package/dist/src/errors.d.ts +38 -0
  86. package/dist/src/errors.js +159 -0
  87. package/dist/src/hooks/init/displayLogo.d.ts +3 -0
  88. package/dist/src/hooks/init/displayLogo.js +37 -0
  89. package/dist/src/index.d.ts +1 -0
  90. package/dist/src/index.js +5 -0
  91. package/dist/src/oauth2Helper/oauth2Helper.d.ts +63 -0
  92. package/dist/src/oauth2Helper/oauth2Helper.js +235 -0
  93. package/dist/src/oauth2Helper/types.d.ts +22 -0
  94. package/dist/src/oauth2Helper/types.js +2 -0
  95. package/dist/src/resources/configuration.d.ts +30 -0
  96. package/dist/src/resources/configuration.js +191 -0
  97. package/dist/src/resources/decryption.d.ts +5 -0
  98. package/dist/src/resources/decryption.js +62 -0
  99. package/dist/src/resources/fileSystem.d.ts +2 -0
  100. package/dist/src/resources/fileSystem.js +22 -0
  101. package/dist/src/resources/globalConfiguration.d.ts +13 -0
  102. package/dist/src/resources/globalConfiguration.js +44 -0
  103. package/dist/src/resources/integrations.d.ts +2 -0
  104. package/dist/src/resources/integrations.js +17 -0
  105. package/dist/src/resources/integrationsPlatform.d.ts +2 -0
  106. package/dist/src/resources/integrationsPlatform.js +33 -0
  107. package/dist/src/services/integrationsPlatform.d.ts +36 -0
  108. package/dist/src/services/integrationsPlatform.js +162 -0
  109. package/dist/src/services/oauth2Helper.d.ts +3 -0
  110. package/dist/src/services/oauth2Helper.js +34 -0
  111. package/dist/test/commands/activity.test.d.ts +1 -0
  112. package/dist/test/commands/activity.test.js +62 -0
  113. package/dist/test/commands/dev.test.d.ts +1 -0
  114. package/dist/test/commands/dev.test.js +139 -0
  115. package/dist/test/commands/encrypt.test.d.ts +1 -0
  116. package/dist/test/commands/encrypt.test.js +73 -0
  117. package/dist/test/commands/init.test.d.ts +1 -0
  118. package/dist/test/commands/init.test.js +45 -0
  119. package/dist/test/commands/invite.test.d.ts +1 -0
  120. package/dist/test/commands/invite.test.js +56 -0
  121. package/dist/test/commands/login.test.d.ts +1 -0
  122. package/dist/test/commands/login.test.js +90 -0
  123. package/dist/test/commands/oauth2.test.d.ts +1 -0
  124. package/dist/test/commands/oauth2.test.js +104 -0
  125. package/dist/test/commands/publish.test.d.ts +1 -0
  126. package/dist/test/commands/publish.test.js +429 -0
  127. package/dist/test/commands/test.test.d.ts +1 -0
  128. package/dist/test/commands/test.test.js +171 -0
  129. package/dist/test/commands/upgrade.test.d.ts +1 -0
  130. package/dist/test/commands/upgrade.test.js +47 -0
  131. package/dist/test/errors.test.d.ts +1 -0
  132. package/dist/test/errors.test.js +96 -0
  133. package/dist/test/helpers/init.d.ts +1 -0
  134. package/dist/test/helpers/init.js +6 -0
  135. package/dist/test/mocha.hooks.d.ts +2 -0
  136. package/dist/test/mocha.hooks.js +37 -0
  137. package/dist/test/oauth2Helper/oauth2Helper.test.d.ts +1 -0
  138. package/dist/test/oauth2Helper/oauth2Helper.test.js +150 -0
  139. package/dist/test/resources/configuration.test.d.ts +1 -0
  140. package/dist/test/resources/configuration.test.js +586 -0
  141. package/dist/test/resources/decryption.test.d.ts +1 -0
  142. package/dist/test/resources/decryption.test.js +68 -0
  143. package/dist/test/resources/globalConfiguration.test.d.ts +1 -0
  144. package/dist/test/resources/globalConfiguration.test.js +32 -0
  145. package/dist/test/services/integrationsPlatform.test.d.ts +1 -0
  146. package/dist/test/services/integrationsPlatform.test.js +168 -0
  147. package/dist/test/services/oauth2Helper.test.d.ts +1 -0
  148. package/dist/test/services/oauth2Helper.test.js +85 -0
  149. package/oclif.manifest.json +423 -0
  150. package/package.json +98 -0
@@ -0,0 +1,586 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const chai_1 = require("chai");
5
+ const tmp_1 = tslib_1.__importDefault(require("tmp"));
6
+ const fs_1 = tslib_1.__importDefault(require("fs"));
7
+ const sinon = tslib_1.__importStar(require("sinon"));
8
+ const errors_1 = require("../../src/errors");
9
+ const Configuration = tslib_1.__importStar(require("../../src/resources/configuration"));
10
+ const configurationTypes_1 = require("../../src/configurationTypes");
11
+ const errors_2 = require("../../src/errors");
12
+ const globalConfiguration_1 = require("../../src/resources/globalConfiguration");
13
+ describe('configuration', () => {
14
+ let originalConfiguration;
15
+ let tempDir;
16
+ beforeEach(async () => {
17
+ originalConfiguration = {
18
+ name: 'my-integration',
19
+ testAccounts: {
20
+ development: {
21
+ accessToken: 'foo',
22
+ },
23
+ },
24
+ };
25
+ // Create a temporary directory
26
+ tempDir = tmp_1.default.dirSync({ unsafeCleanup: true });
27
+ sinon.stub(process, 'cwd').returns(tempDir.name);
28
+ // Create the configuration file.
29
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify(originalConfiguration, null, 2));
30
+ });
31
+ afterEach(() => {
32
+ // Remove the temporary file
33
+ tempDir.removeCallback();
34
+ sinon.restore();
35
+ });
36
+ describe('getConfiguration', () => {
37
+ it('handles an error', async () => {
38
+ sinon.stub(fs_1.default.promises, 'readFile').throws();
39
+ try {
40
+ await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
41
+ throw Error('Should have thrown NoConfigurationFileError');
42
+ }
43
+ catch (error) {
44
+ (0, chai_1.expect)(error).to.be.instanceOf(errors_2.NoConfigurationFileError);
45
+ }
46
+ });
47
+ it('handles missing specific environment file', async () => {
48
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging);
49
+ (0, chai_1.expect)(configuration.name).to.equal(originalConfiguration.name);
50
+ });
51
+ it('returns existing specific environment file', async () => {
52
+ await fs_1.default.promises.writeFile(`${process.cwd()}/.unito.${globalConfiguration_1.Environment.Staging}.json`, JSON.stringify({
53
+ name: 'foo',
54
+ }, null, 2));
55
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging);
56
+ (0, chai_1.expect)(configuration.name).to.equal('foo');
57
+ });
58
+ it('throws on missing custom configuration file', async () => {
59
+ try {
60
+ await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging, '/mising-config.json');
61
+ throw Error('Should have thrown NoConfigurationFileError');
62
+ }
63
+ catch (error) {
64
+ (0, chai_1.expect)(error).to.be.instanceOf(errors_2.NoConfigurationFileError);
65
+ }
66
+ });
67
+ it('returns existing specific environment file', async () => {
68
+ await fs_1.default.promises.writeFile(`${process.cwd()}/custom-config.json`, JSON.stringify({
69
+ name: 'foo',
70
+ }, null, 2));
71
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging, '/custom-config.json');
72
+ (0, chai_1.expect)(configuration.name).to.equal('foo');
73
+ });
74
+ it('sets default values for "oauth2"', async () => {
75
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
76
+ name: 'foo',
77
+ authorizations: [
78
+ {
79
+ name: 'bar',
80
+ method: 'oauth2',
81
+ oauth2: {
82
+ clientSecret: 'a',
83
+ clientId: 'b',
84
+ authorizationUrl: 'http://c.com',
85
+ tokenUrl: 'http://d.com',
86
+ scopes: [],
87
+ },
88
+ },
89
+ ],
90
+ }, null, 2));
91
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
92
+ const oauth2 = configuration.authorizations?.at(0)?.oauth2;
93
+ (0, chai_1.expect)(oauth2?.requestContentType).to.equal(configurationTypes_1.RequestContentType.URL_ENCODED);
94
+ (0, chai_1.expect)(oauth2?.responseContentType).to.equal(configurationTypes_1.RequestContentType.JSON);
95
+ (0, chai_1.expect)(oauth2?.grantType).to.equal(configurationTypes_1.GrantType.AUTHORIZATION_CODE);
96
+ });
97
+ it('accepts password grant for "oauth2"', async () => {
98
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
99
+ name: 'foo',
100
+ authorizations: [
101
+ {
102
+ name: 'bar',
103
+ method: 'oauth2',
104
+ oauth2: {
105
+ clientSecret: 'a',
106
+ clientId: 'b',
107
+ authorizationUrl: 'http://c.com',
108
+ tokenUrl: 'http://d.com',
109
+ scopes: [],
110
+ grantType: configurationTypes_1.GrantType.PASSWORD,
111
+ },
112
+ },
113
+ ],
114
+ }, null, 2));
115
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
116
+ const oauth2 = configuration.authorizations?.at(0)?.oauth2;
117
+ (0, chai_1.expect)(oauth2?.grantType).to.equal(configurationTypes_1.GrantType.PASSWORD);
118
+ });
119
+ it('accepts request parameters for "oauth2"', async () => {
120
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
121
+ name: 'foo',
122
+ authorizations: [
123
+ {
124
+ name: 'bar',
125
+ method: 'oauth2',
126
+ oauth2: {
127
+ clientSecret: 'a',
128
+ clientId: 'b',
129
+ authorizationUrl: 'http://c.com',
130
+ tokenUrl: 'http://d.com',
131
+ scopes: [],
132
+ grantType: configurationTypes_1.GrantType.PASSWORD,
133
+ tokenRequestParameters: {
134
+ header: {
135
+ a: 'yo',
136
+ },
137
+ body: {
138
+ b: false,
139
+ },
140
+ },
141
+ refreshRequestParameters: {
142
+ body: {
143
+ c: 1,
144
+ },
145
+ },
146
+ },
147
+ },
148
+ ],
149
+ }, null, 2));
150
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
151
+ const oauth2 = configuration.authorizations?.at(0)?.oauth2;
152
+ (0, chai_1.expect)(oauth2?.tokenRequestParameters).to.deep.equal({
153
+ header: {
154
+ a: 'yo',
155
+ },
156
+ body: {
157
+ b: false,
158
+ },
159
+ });
160
+ (0, chai_1.expect)(oauth2?.refreshRequestParameters).to.deep.equal({
161
+ body: {
162
+ c: 1,
163
+ },
164
+ });
165
+ });
166
+ describe('validates secrets', () => {
167
+ it('valid secret', async () => {
168
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
169
+ name: 'foo',
170
+ secrets: {
171
+ foo: 'unito-secret-v1://bar',
172
+ },
173
+ }, null, 2));
174
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
175
+ (0, chai_1.expect)(configuration.secrets).to.deep.equal({ foo: 'unito-secret-v1://bar' });
176
+ });
177
+ it('invalid secret - type', async () => {
178
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
179
+ name: 'foo',
180
+ secrets: {
181
+ foo: 123,
182
+ },
183
+ }, null, 2));
184
+ await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
185
+ });
186
+ it('invalid secret - pattern', async () => {
187
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
188
+ name: 'foo',
189
+ secrets: {
190
+ foo: 'nope',
191
+ },
192
+ }, null, 2));
193
+ await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
194
+ });
195
+ });
196
+ describe('validates test accounts - custom', () => {
197
+ it('valid test accounts', async () => {
198
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
199
+ name: 'foo',
200
+ authorizations: [
201
+ {
202
+ name: 'apiKey',
203
+ method: 'custom',
204
+ variables: {
205
+ apiKey: {
206
+ type: 'password',
207
+ required: true,
208
+ label: 'Insert your Secret Key here',
209
+ },
210
+ displayName: {
211
+ type: 'string',
212
+ required: false,
213
+ label: 'Display Name (optional)',
214
+ },
215
+ email: {
216
+ type: 'string',
217
+ required: true,
218
+ label: 'Your Atlassian/Confluence email address',
219
+ placeholder: 'myemail@company.com',
220
+ },
221
+ domain: {
222
+ type: 'string',
223
+ required: true,
224
+ label: 'Your Confluence URL',
225
+ format: 'uri',
226
+ placeholder: 'https://mycompany.atlassian.net',
227
+ },
228
+ },
229
+ },
230
+ ],
231
+ testAccounts: {
232
+ development: {
233
+ apiKey: 'xyz',
234
+ email: 'manualtester+staging@unito.io',
235
+ domain: 'https://unitomanualtests.atlassian.net',
236
+ },
237
+ compliance: {
238
+ apiKey: 'xyzw',
239
+ displayName: 'My Awesome Nickname from first grade',
240
+ email: 'manualtester+staging@unito.io',
241
+ domain: 'ftp://unitomanualtests.atlassian.net',
242
+ },
243
+ },
244
+ }, null, 2));
245
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
246
+ const developmentKey = configuration.testAccounts?.development?.apiKey;
247
+ const complianceKey = configuration.testAccounts?.compliance?.apiKey;
248
+ (0, chai_1.expect)(developmentKey).to.equal('xyz');
249
+ (0, chai_1.expect)(complianceKey).to.equal('xyzw');
250
+ });
251
+ it('invalid test accounts', async () => {
252
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
253
+ name: 'foo',
254
+ authorizations: [
255
+ {
256
+ name: 'apiKey',
257
+ method: 'custom',
258
+ variables: {
259
+ apiKey: {
260
+ type: 'password',
261
+ required: true,
262
+ label: 'Insert your Secret Key here',
263
+ },
264
+ displayName: {
265
+ type: 'string',
266
+ required: false,
267
+ label: 'Display Name (optional)',
268
+ },
269
+ },
270
+ },
271
+ ],
272
+ testAccounts: {
273
+ development: {
274
+ apiKey: 'xyz',
275
+ displayName: 'My Awesome Nickname from first grade',
276
+ email: 'manualtester+staging@unito.io',
277
+ domain: 'ftp://unitomanualtests.atlassian.net',
278
+ },
279
+ compliance: {
280
+ APIKEY: 'xyzw',
281
+ displayName: 'My Awesome Nickname from first grade',
282
+ email: 'manualtester+staging@unito.io',
283
+ domain: 'ftp://unitomanualtests.atlassian.net',
284
+ },
285
+ },
286
+ }, null, 2));
287
+ await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
288
+ });
289
+ });
290
+ describe('validates test accounts - oauth', () => {
291
+ it('valid test accounts', async () => {
292
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
293
+ name: 'foo',
294
+ authorizations: [
295
+ {
296
+ name: 'oauth2',
297
+ method: 'oauth2',
298
+ development: false,
299
+ oauth2: {
300
+ clientSecret: 'xxxxx',
301
+ clientId: 'xxxxx',
302
+ authorizationUrl: 'https://api.surveymonkey.com/oauth/authorize',
303
+ tokenUrl: 'https://api.surveymonkey.com/oauth/token',
304
+ grantType: 'authorization_code',
305
+ scopes: [
306
+ {
307
+ name: 'users_read',
308
+ },
309
+ {
310
+ name: 'surveys_read',
311
+ },
312
+ {
313
+ name: 'collectors_read',
314
+ },
315
+ {
316
+ name: 'responses_read',
317
+ },
318
+ {
319
+ name: 'contacts_read',
320
+ },
321
+ {
322
+ name: 'responses_read_detail',
323
+ },
324
+ ],
325
+ requestContentType: 'application/x-www-form-urlencoded',
326
+ responseContentType: 'application/json',
327
+ },
328
+ variables: {
329
+ displayName: {
330
+ type: 'string',
331
+ required: false,
332
+ label: 'Display Name (optional)',
333
+ },
334
+ email: {
335
+ type: 'string',
336
+ required: true,
337
+ label: 'Your Atlassian/Confluence email address',
338
+ placeholder: 'myemail@company.com',
339
+ },
340
+ domain: {
341
+ type: 'string',
342
+ required: true,
343
+ label: 'Your Confluence URL',
344
+ format: 'uri',
345
+ placeholder: 'https://mycompany.atlassian.net',
346
+ },
347
+ },
348
+ },
349
+ ],
350
+ testAccounts: {
351
+ development: {
352
+ accessToken: 'Super_Secret_token',
353
+ displayName: 'My Awesome Nickname from first grade',
354
+ email: 'manualtester+staging@unito.io',
355
+ domain: 'ftp://unitomanualtests.atlassian.net',
356
+ },
357
+ compliance: {
358
+ accessToken: 'Super_Secret_token_2',
359
+ email: 'manualtester+staging@unito.io',
360
+ domain: 'ftp://unitomanualtests.atlassian.net',
361
+ },
362
+ },
363
+ }, null, 2));
364
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
365
+ const developmentKey = configuration.testAccounts?.development?.accessToken;
366
+ const complianceKey = configuration.testAccounts?.compliance?.accessToken;
367
+ (0, chai_1.expect)(developmentKey).to.equal('Super_Secret_token');
368
+ (0, chai_1.expect)(complianceKey).to.equal('Super_Secret_token_2');
369
+ });
370
+ it('invalid test accounts', async () => {
371
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
372
+ name: 'foo',
373
+ authorizations: [
374
+ {
375
+ name: 'oauth2',
376
+ method: 'oauth2',
377
+ development: false,
378
+ oauth2: {
379
+ clientSecret: 'xxxxx',
380
+ clientId: 'xxxxx',
381
+ authorizationUrl: 'https://api.surveymonkey.com/oauth/authorize',
382
+ tokenUrl: 'https://api.surveymonkey.com/oauth/token',
383
+ grantType: 'authorization_code',
384
+ scopes: [
385
+ {
386
+ name: 'users_read',
387
+ },
388
+ {
389
+ name: 'surveys_read',
390
+ },
391
+ {
392
+ name: 'collectors_read',
393
+ },
394
+ {
395
+ name: 'responses_read',
396
+ },
397
+ {
398
+ name: 'contacts_read',
399
+ },
400
+ {
401
+ name: 'responses_read_detail',
402
+ },
403
+ ],
404
+ requestContentType: 'application/x-www-form-urlencoded',
405
+ responseContentType: 'application/json',
406
+ },
407
+ },
408
+ ],
409
+ testAccounts: {
410
+ development: {
411
+ apiKey: 'xyz',
412
+ },
413
+ compliance: {
414
+ apiKey: 'xyzw',
415
+ },
416
+ },
417
+ }, null, 2));
418
+ await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
419
+ });
420
+ });
421
+ describe('validates test accounts - multiple authorization methods', () => {
422
+ it('valid test accounts', async () => {
423
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
424
+ name: 'foo',
425
+ authorizations: [
426
+ {
427
+ name: 'apiKey',
428
+ method: 'custom',
429
+ variables: {
430
+ apiKey: {
431
+ type: 'password',
432
+ required: true,
433
+ label: 'Insert your Secret Key here',
434
+ },
435
+ displayName: {
436
+ type: 'string',
437
+ required: false,
438
+ label: 'Display Name (optional)',
439
+ },
440
+ },
441
+ },
442
+ {
443
+ name: 'oauth2',
444
+ method: 'oauth2',
445
+ development: false,
446
+ oauth2: {
447
+ clientSecret: 'xxxxx',
448
+ clientId: 'xxxxx',
449
+ authorizationUrl: 'https://api.surveymonkey.com/oauth/authorize',
450
+ tokenUrl: 'https://api.surveymonkey.com/oauth/token',
451
+ grantType: 'authorization_code',
452
+ scopes: [
453
+ {
454
+ name: 'users_read',
455
+ },
456
+ {
457
+ name: 'surveys_read',
458
+ },
459
+ {
460
+ name: 'collectors_read',
461
+ },
462
+ {
463
+ name: 'responses_read',
464
+ },
465
+ {
466
+ name: 'contacts_read',
467
+ },
468
+ {
469
+ name: 'responses_read_detail',
470
+ },
471
+ ],
472
+ requestContentType: 'application/x-www-form-urlencoded',
473
+ responseContentType: 'application/json',
474
+ },
475
+ variables: {
476
+ displayName: {
477
+ type: 'string',
478
+ required: false,
479
+ label: 'Display Name (optional)',
480
+ },
481
+ email: {
482
+ type: 'string',
483
+ required: true,
484
+ label: 'Your Atlassian/Confluence email address',
485
+ placeholder: 'myemail@company.com',
486
+ },
487
+ domain: {
488
+ type: 'string',
489
+ required: true,
490
+ label: 'Your Confluence URL',
491
+ format: 'uri',
492
+ placeholder: 'https://mycompany.atlassian.net',
493
+ },
494
+ },
495
+ },
496
+ ],
497
+ testAccounts: {
498
+ development: {
499
+ accessToken: 'Super_Secret_token',
500
+ displayName: 'My Awesome Nickname from first grade',
501
+ email: 'manualtester+staging@unito.io',
502
+ domain: 'ftp://unitomanualtests.atlassian.net',
503
+ },
504
+ compliance: {
505
+ apiKey: 'Super_Secret_api_key_2',
506
+ },
507
+ },
508
+ }, null, 2));
509
+ const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
510
+ const developmentKey = configuration.testAccounts?.development?.accessToken;
511
+ const complianceKey = configuration.testAccounts?.compliance?.apiKey;
512
+ (0, chai_1.expect)(developmentKey).to.equal('Super_Secret_token');
513
+ (0, chai_1.expect)(complianceKey).to.equal('Super_Secret_api_key_2');
514
+ });
515
+ it('invalid test accounts', async () => {
516
+ await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
517
+ name: 'foo',
518
+ authorizations: [
519
+ {
520
+ name: 'apiKey',
521
+ method: 'custom',
522
+ variables: {
523
+ apiKey: {
524
+ type: 'password',
525
+ required: true,
526
+ label: 'Insert your Secret Key here',
527
+ },
528
+ displayName: {
529
+ type: 'string',
530
+ required: false,
531
+ label: 'Display Name (optional)',
532
+ },
533
+ },
534
+ },
535
+ {
536
+ name: 'oauth2',
537
+ method: 'oauth2',
538
+ development: false,
539
+ oauth2: {
540
+ clientSecret: 'xxxxx',
541
+ clientId: 'xxxxx',
542
+ authorizationUrl: 'https://api.surveymonkey.com/oauth/authorize',
543
+ tokenUrl: 'https://api.surveymonkey.com/oauth/token',
544
+ grantType: 'authorization_code',
545
+ scopes: [
546
+ {
547
+ name: 'users_read',
548
+ },
549
+ {
550
+ name: 'surveys_read',
551
+ },
552
+ {
553
+ name: 'collectors_read',
554
+ },
555
+ {
556
+ name: 'responses_read',
557
+ },
558
+ {
559
+ name: 'contacts_read',
560
+ },
561
+ {
562
+ name: 'responses_read_detail',
563
+ },
564
+ ],
565
+ requestContentType: 'application/x-www-form-urlencoded',
566
+ responseContentType: 'application/json',
567
+ },
568
+ },
569
+ ],
570
+ testAccounts: {
571
+ development: {
572
+ accessTokens: 'Super_Secret_token',
573
+ displayName: 'My Awesome Nickname from first grade',
574
+ email: 'manualtester+staging@unito.io',
575
+ domain: 'ftp://unitomanualtests.atlassian.net',
576
+ },
577
+ compliance: {
578
+ apiKeys: 'Super_Secret_api_key_2',
579
+ },
580
+ },
581
+ }, null, 2));
582
+ await (0, chai_1.expect)(Configuration.getConfiguration(globalConfiguration_1.Environment.Production)).to.be.rejectedWith(errors_1.ConfigurationInvalid);
583
+ });
584
+ });
585
+ });
586
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const chai_1 = require("chai");
5
+ const sinon_1 = tslib_1.__importDefault(require("sinon"));
6
+ const IntegrationsPlatformResources = tslib_1.__importStar(require("../../src/resources/integrationsPlatform"));
7
+ const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/integrationsPlatform"));
8
+ const GlobalConfiguration = tslib_1.__importStar(require("../../src/resources/globalConfiguration"));
9
+ const configuration_1 = require("../../src/resources/configuration");
10
+ const decryptionHelper = tslib_1.__importStar(require("../../src/resources/decryption"));
11
+ describe('decryptionHelper', () => {
12
+ const configuration = {
13
+ name: 'a',
14
+ baseUrl: 'b',
15
+ secrets: {
16
+ encryptedSecret1: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
17
+ encryptedSecret2: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
18
+ },
19
+ testAccounts: {
20
+ compliance: {
21
+ accessToken: 'token',
22
+ encryptedToken: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
23
+ },
24
+ development: {
25
+ accessToken: 'developmentToken',
26
+ },
27
+ },
28
+ };
29
+ beforeEach(() => {
30
+ sinon_1.default.stub(GlobalConfiguration, 'read');
31
+ sinon_1.default.stub(IntegrationsPlatformResources, 'validateAuthenticated');
32
+ sinon_1.default.stub(IntegrationsPlatform, 'decryptData').resolves({ decryptedData: 'decrypted-me' });
33
+ });
34
+ afterEach(() => {
35
+ sinon_1.default.restore();
36
+ });
37
+ describe('decryptCredentials', () => {
38
+ it('support unencrypted credentials', async () => {
39
+ const decryptedCredentials = await decryptionHelper.decryptTestAccountCredentials(configuration, GlobalConfiguration.Environment.Local, configuration_1.CredentialScope.DEVELOPMENT, '/path/to/config');
40
+ (0, chai_1.expect)(decryptedCredentials).to.deep.equal({
41
+ accessToken: 'developmentToken',
42
+ });
43
+ });
44
+ it('support encrypted credentials', async () => {
45
+ const decryptedCredentials = await decryptionHelper.decryptTestAccountCredentials(configuration, GlobalConfiguration.Environment.Local, configuration_1.CredentialScope.COMPLIANCE, '/path/to/config');
46
+ (0, chai_1.expect)(decryptedCredentials).to.deep.equal({
47
+ accessToken: 'token',
48
+ encryptedToken: `decrypted-me`,
49
+ });
50
+ });
51
+ });
52
+ describe('decryptSecrets', () => {
53
+ it('support encrypted secrets', async () => {
54
+ const decryptedSecrets = await decryptionHelper.decryptSecrets(configuration, GlobalConfiguration.Environment.Local, '/path/to/config');
55
+ (0, chai_1.expect)(decryptedSecrets).to.deep.equal({
56
+ encryptedSecret1: 'decrypted-me',
57
+ encryptedSecret2: 'decrypted-me',
58
+ });
59
+ });
60
+ it('support empty secrets', async () => {
61
+ const decryptedSecrets = await decryptionHelper.decryptSecrets({
62
+ ...configuration,
63
+ secrets: {},
64
+ }, GlobalConfiguration.Environment.Local, '/path/to/config');
65
+ (0, chai_1.expect)(decryptedSecrets).to.deep.equal({});
66
+ });
67
+ });
68
+ });
@@ -0,0 +1 @@
1
+ export {};