@itentialopensource/adapter-microsoft_graph 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. package/.eslintignore +6 -0
  2. package/.eslintrc.js +18 -0
  3. package/.gitlab/.gitkeep +0 -0
  4. package/.gitlab/issue_templates/.gitkeep +0 -0
  5. package/.gitlab/issue_templates/Default.md +17 -0
  6. package/.gitlab/issue_templates/bugReportTemplate.md +42 -0
  7. package/.gitlab/issue_templates/featureRequestTemplate.md +14 -0
  8. package/.jshintrc +0 -0
  9. package/AUTH.md +39 -0
  10. package/BROKER.md +199 -0
  11. package/CALLS.md +170 -0
  12. package/CHANGELOG.md +9 -0
  13. package/CODE_OF_CONDUCT.md +43 -0
  14. package/CONTRIBUTING.md +172 -0
  15. package/ENHANCE.md +69 -0
  16. package/LICENSE +201 -0
  17. package/PROPERTIES.md +641 -0
  18. package/README.md +337 -0
  19. package/SUMMARY.md +9 -0
  20. package/SYSTEMINFO.md +11 -0
  21. package/TROUBLESHOOT.md +47 -0
  22. package/adapter.js +18798 -0
  23. package/adapterBase.js +1787 -0
  24. package/entities/.generic/action.json +214 -0
  25. package/entities/.generic/schema.json +28 -0
  26. package/entities/.system/action.json +50 -0
  27. package/entities/.system/mockdatafiles/getToken-default.json +3 -0
  28. package/entities/.system/mockdatafiles/healthcheck-default.json +3 -0
  29. package/entities/.system/schema.json +19 -0
  30. package/entities/.system/schemaTokenReq.json +53 -0
  31. package/entities/.system/schemaTokenResp.json +53 -0
  32. package/entities/Applications/action.json +127 -0
  33. package/entities/Applications/schema.json +35 -0
  34. package/entities/AzureADDevice/action.json +106 -0
  35. package/entities/AzureADDevice/schema.json +45 -0
  36. package/entities/Batch/action.json +24 -0
  37. package/entities/Batch/schema.json +19 -0
  38. package/entities/CaseCreation/action.json +249 -0
  39. package/entities/CaseCreation/schema.json +30 -0
  40. package/entities/Catalog/action.json +25 -0
  41. package/entities/Catalog/schema.json +19 -0
  42. package/entities/ConnectionSetup/action.json +148 -0
  43. package/entities/ConnectionSetup/schema.json +25 -0
  44. package/entities/ContentSync/action.json +65 -0
  45. package/entities/ContentSync/schema.json +21 -0
  46. package/entities/CreateDSR/action.json +45 -0
  47. package/entities/CreateDSR/schema.json +20 -0
  48. package/entities/Deployment/action.json +106 -0
  49. package/entities/Deployment/schema.json +34 -0
  50. package/entities/DeploymentAudience/action.json +66 -0
  51. package/entities/DeploymentAudience/schema.json +32 -0
  52. package/entities/Events/action.json +108 -0
  53. package/entities/Events/schema.json +34 -0
  54. package/entities/Files/action.json +108 -0
  55. package/entities/Files/schema.json +23 -0
  56. package/entities/Groups/action.json +25 -0
  57. package/entities/Groups/schema.json +19 -0
  58. package/entities/IdentitySync/action.json +105 -0
  59. package/entities/IdentitySync/schema.json +23 -0
  60. package/entities/Insights/action.json +46 -0
  61. package/entities/Insights/schema.json +20 -0
  62. package/entities/LabelManagement/action.json +106 -0
  63. package/entities/LabelManagement/schema.json +23 -0
  64. package/entities/Mail/action.json +212 -0
  65. package/entities/Mail/schema.json +72 -0
  66. package/entities/Memberships/action.json +167 -0
  67. package/entities/Memberships/schema.json +70 -0
  68. package/entities/Misc/action.json +66 -0
  69. package/entities/Misc/schema.json +21 -0
  70. package/entities/Notebooks/action.json +107 -0
  71. package/entities/Notebooks/schema.json +34 -0
  72. package/entities/OpenExtensions/action.json +65 -0
  73. package/entities/OpenExtensions/schema.json +54 -0
  74. package/entities/People/action.json +46 -0
  75. package/entities/People/schema.json +31 -0
  76. package/entities/SchemaExtensions/action.json +65 -0
  77. package/entities/SchemaExtensions/schema.json +32 -0
  78. package/entities/Search/action.json +24 -0
  79. package/entities/Search/schema.json +19 -0
  80. package/entities/Security/action.json +151 -0
  81. package/entities/Security/schema.json +58 -0
  82. package/entities/SharePoint/action.json +214 -0
  83. package/entities/SharePoint/schema.json +39 -0
  84. package/entities/Subscriptions/action.json +65 -0
  85. package/entities/Subscriptions/schema.json +32 -0
  86. package/entities/TasksPlanner/action.json +272 -0
  87. package/entities/TasksPlanner/schema.json +86 -0
  88. package/entities/TasksTodo/action.json +187 -0
  89. package/entities/TasksTodo/schema.json +49 -0
  90. package/entities/Teams/action.json +519 -0
  91. package/entities/Teams/schema.json +120 -0
  92. package/entities/TrackDSRStatus/action.json +108 -0
  93. package/entities/TrackDSRStatus/schema.json +23 -0
  94. package/entities/TriggerEventForExistingLabel/action.json +108 -0
  95. package/entities/TriggerEventForExistingLabel/schema.json +23 -0
  96. package/entities/Users/action.json +213 -0
  97. package/entities/Users/schema.json +50 -0
  98. package/entities/WorkflowAutomation/action.json +249 -0
  99. package/entities/WorkflowAutomation/schema.json +30 -0
  100. package/error.json +190 -0
  101. package/package.json +87 -0
  102. package/pronghorn.json +8654 -0
  103. package/propertiesDecorators.json +14 -0
  104. package/propertiesSchema.json +1248 -0
  105. package/refs?service=git-upload-pack +0 -0
  106. package/report/creationReport.json +1715 -0
  107. package/report/graph.json +14709 -0
  108. package/sampleProperties.json +195 -0
  109. package/test/integration/adapterTestBasicGet.js +83 -0
  110. package/test/integration/adapterTestConnectivity.js +93 -0
  111. package/test/integration/adapterTestIntegration.js +6059 -0
  112. package/test/unit/adapterBaseTestUnit.js +949 -0
  113. package/test/unit/adapterTestUnit.js +7492 -0
  114. package/utils/adapterInfo.js +206 -0
  115. package/utils/addAuth.js +94 -0
  116. package/utils/artifactize.js +146 -0
  117. package/utils/basicGet.js +50 -0
  118. package/utils/checkMigrate.js +63 -0
  119. package/utils/entitiesToDB.js +178 -0
  120. package/utils/findPath.js +74 -0
  121. package/utils/methodDocumentor.js +225 -0
  122. package/utils/modify.js +154 -0
  123. package/utils/packModificationScript.js +35 -0
  124. package/utils/patches2bundledDeps.js +90 -0
  125. package/utils/pre-commit.sh +32 -0
  126. package/utils/removeHooks.js +20 -0
  127. package/utils/setup.js +33 -0
  128. package/utils/tbScript.js +246 -0
  129. package/utils/tbUtils.js +490 -0
  130. package/utils/testRunner.js +298 -0
  131. package/utils/troubleshootingAdapter.js +195 -0
  132. package/workflows/README.md +3 -0
@@ -0,0 +1,90 @@
1
+ const fs = require('fs');
2
+ const semverSatisfies = require('semver/functions/satisfies');
3
+ const packageJson = require('../package.json');
4
+
5
+ try {
6
+ // pattern supplied by semver.org via https://regex101.com/r/vkijKf/1/ but removed gm from end to only match a single semver
7
+ // const semverPat = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
8
+ // pattern supplied by semver.org via https://regex101.com/r/Ly7O1x/3/ with following changes
9
+ // removed P's from before capturing group names and
10
+ // removed gm from end to only match a single semver
11
+ // const semverPat = /^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
12
+
13
+ const patches = (fs.existsSync('./patches')) ? fs.readdirSync('./patches', { withFileTypes: true }) : [];
14
+ if (!patches.length) {
15
+ console.error('\nno patches - nothing to do\n');
16
+ process.exitCode = 1;
17
+ }
18
+
19
+ const dependencies = packageJson.dependencies || {};
20
+ if (!Object.keys(dependencies).length) {
21
+ console.error('\nno dependencies - nothing to do\n');
22
+ process.exitCode = 1;
23
+ }
24
+
25
+ let changed = false;
26
+ console.error('\nprocessing patches');
27
+ const bundledDependencies = packageJson.bundledDependencies || packageJson.bundleDependencies || [];
28
+
29
+ patches.forEach((patch) => {
30
+ if (!patch.isFile()) {
31
+ console.error(`${patch.name} skipped, is not a regular file`);
32
+ return;
33
+ }
34
+ if (!patch.name.endsWith('.patch')) {
35
+ console.error(`${patch.name} skipped, does not end with .patch`);
36
+ return;
37
+ }
38
+ const splits = patch.name.slice(0, -6).split('+');
39
+ if (splits.length > 4) {
40
+ console.error(`${patch.name} skipped, does not follow the naming convention (cannot use '+' other than to separate scope/package/semver and at most once within semver)`);
41
+ return;
42
+ }
43
+ const scope = splits[0][0] === '@' ? splits.shift() : null;
44
+ const packageName = splits.shift();
45
+ const semver = splits.join('+');
46
+ // const { groups } = semver.match(semverPat);
47
+ const file = scope ? `${scope}/${packageName}` : packageName;
48
+ if (dependencies[file] && semverSatisfies(semver, dependencies[file])) {
49
+ if (!bundledDependencies.includes(file)) {
50
+ bundledDependencies.push(file);
51
+ console.error(`added ${file} to bundledDependencies`);
52
+ changed = true;
53
+ } else {
54
+ console.error(`bundledDependencies already has ${file}`);
55
+ }
56
+ } else {
57
+ const depmsg = dependencies[file] ? `version mismatch (${dependencies[file]}) in dependencies` : 'not found in dependencies';
58
+ console.error(`patch ${patch.name} ${depmsg}`);
59
+ }
60
+ });
61
+
62
+ if (!packageJson.bundledDependencies && bundledDependencies.length) {
63
+ delete packageJson.bundleDependencies;
64
+ packageJson.bundledDependencies = bundledDependencies;
65
+ console.error('renaming bundleDependencies to bundledDependencies');
66
+ changed = true;
67
+ }
68
+ if (changed) {
69
+ fs.writeFileSync('./package.json.new', JSON.stringify(packageJson, null, 2));
70
+ console.error('wrote package.json.new');
71
+ fs.renameSync('./package.json', './package.json.old');
72
+ console.error('moved package.json to package.json.old');
73
+ fs.renameSync('./package.json.new', './package.json');
74
+ console.error('moved package.json.new to package.json');
75
+ } else {
76
+ console.error('no changes\n');
77
+ process.exitCode = 1;
78
+ }
79
+ } catch (e) {
80
+ if (e) {
81
+ // caught error, exit with status 2 to signify abject failure
82
+ console.error(`\ncaught exception - ${e}\n`);
83
+ process.exitCode = 2;
84
+ } else {
85
+ // caught false, exit with status 1 to signify nothing done
86
+ process.exitCode = 1;
87
+ }
88
+ } finally {
89
+ console.error('done\n');
90
+ }
@@ -0,0 +1,32 @@
1
+ #!/bin/sh
2
+ # @copyright Itential, LLC 2019
3
+
4
+ #exit on any failure in the pipeline
5
+ set -e
6
+
7
+ # --------------------------------------------------
8
+ # pre-commit
9
+ # --------------------------------------------------
10
+ # Contains the standard set of tasks to runbefore
11
+ # committing changes to the repo. If any tasks fail
12
+ # then the commit will be aborted.
13
+ # --------------------------------------------------
14
+
15
+ printf "%b" "Running pre-commit hooks...\\n"
16
+
17
+ # verify testing script is stubbed and no credentials
18
+ node utils/testRunner.js -r
19
+
20
+ # update the adapter information file
21
+ node utils/adapterInfo.js
22
+ node utils/methodDocumentor.js
23
+ git add CALLS.md report/adapterInfo.json
24
+
25
+ # security audit on the code
26
+ npm audit --registry=https://registry.npmjs.org --audit-level=moderate
27
+
28
+ # lint the code
29
+ npm run lint
30
+
31
+ # test the code
32
+ npm run test
@@ -0,0 +1,20 @@
1
+ const fs = require('fs');
2
+
3
+ /**
4
+ * This script will uninstall pre-commit or pre-push hooks in case there's ever a need to
5
+ * commit/push something that has issues
6
+ */
7
+
8
+ const precommitPath = '.git/hooks/pre-commit';
9
+ const prepushPath = '.git/hooks/pre-push';
10
+ fs.unlink(precommitPath, (err) => {
11
+ if (err && err.code !== 'ENOENT') {
12
+ console.log(`${err.message}`);
13
+ }
14
+ });
15
+
16
+ fs.unlink(prepushPath, (err) => {
17
+ if (err && err.code !== 'ENOENT') {
18
+ console.log(`${err.message}`);
19
+ }
20
+ });
package/utils/setup.js ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ /* @copyright Itential, LLC 2019 */
3
+
4
+ const fs = require('fs');
5
+
6
+ /**
7
+ * This script will execute before an npm install command. The purpose is to
8
+ * write out some standard git hooks that will enable folks working on this
9
+ * project to benefit from the protections that the hooks provide.
10
+ */
11
+
12
+ const precommit = fs.readFileSync('utils/pre-commit.sh', 'utf8');
13
+
14
+ fs.stat('.git', (err) => {
15
+ if (err == null) {
16
+ // git repo, not an npm repo.
17
+ // add pre-commit hook if it doesn't exist
18
+ fs.stat('.git/hooks/pre-commit', (statErr) => {
19
+ if (statErr == null || statErr.code === 'ENOENT') {
20
+ fs.writeFile('.git/hooks/pre-commit', precommit, {
21
+ mode: 0o755
22
+ }, (writeErr) => {
23
+ if (writeErr) {
24
+ return console.log(writeErr.message);
25
+ }
26
+ return null;
27
+ });
28
+ } else {
29
+ console.log(statErr.message);
30
+ }
31
+ });
32
+ }
33
+ });
@@ -0,0 +1,246 @@
1
+ /* eslint-disable no-console */
2
+ /* eslint import/no-unresolved: warn */
3
+ /* eslint global-require: warn */
4
+
5
+ // suppress eslint rule in adapter
6
+ /* eslint arrow-parens: warn */
7
+ /* eslint import/no-extraneous-dependencies: warn */
8
+ /* eslint import/no-dynamic-require: warn */
9
+
10
+ const program = require('commander');
11
+ const rls = require('readline-sync');
12
+ const prompts = require('prompts');
13
+ const utils = require('./tbUtils');
14
+ const basicGet = require('./basicGet');
15
+ const { name } = require('../package.json');
16
+ const sampleProperties = require('../sampleProperties.json');
17
+ const adapterPronghorn = require('../pronghorn.json');
18
+ const { addAuthInfo } = require('./addAuth');
19
+
20
+ const { troubleshoot, offline } = require('./troubleshootingAdapter');
21
+
22
+ const executeInStandaloneMode = async (command) => {
23
+ console.info('\n> Executing the script outside of IAP installation directory');
24
+ console.info('> Using sampleProperties.json configuration');
25
+ switch (command) {
26
+ case 'install': {
27
+ console.error('Not currently in IAP directory - installation not possible');
28
+ break;
29
+ }
30
+ case 'connectivity': {
31
+ const { host } = sampleProperties.properties;
32
+ console.log(`perform networking diagnositics to ${host}`);
33
+ utils.runConnectivity(host);
34
+ break;
35
+ }
36
+ case 'healthcheck': {
37
+ const a = basicGet.getAdapterInstance({ properties: sampleProperties });
38
+ await utils.healthCheck(a);
39
+ break;
40
+ }
41
+ case 'basicget': {
42
+ utils.runBasicGet();
43
+ break;
44
+ }
45
+ default: {
46
+ if (rls.keyInYN('Troubleshooting without IAP?')) {
47
+ await offline();
48
+ }
49
+ }
50
+ }
51
+ process.exit(0);
52
+ };
53
+
54
+ const getAdapterInstanceConfig = async (command) => {
55
+ const instances = await utils.getAllAdapterInstances();
56
+ if (!instances || instances.length === 0) {
57
+ return console.log('None adapter instances found!');
58
+ }
59
+
60
+ let instance;
61
+ if (instances.length === 1) {
62
+ [instance] = instances;
63
+ } else {
64
+ const choices = instances.map((item) => ({ title: item.name }));
65
+ const menu = {
66
+ type: 'select',
67
+ name: 'index',
68
+ message: `Pick an adapter for ${command} check`,
69
+ choices
70
+ };
71
+
72
+ console.log('\n');
73
+ const selected = await prompts(menu);
74
+ console.log('\n');
75
+ instance = instances[selected.index];
76
+ }
77
+
78
+ if (!instance) {
79
+ console.error('No adapter instance selected');
80
+ return null;
81
+ }
82
+
83
+ const { serviceItem: adapterConfig } = await utils.getAdapterConfig(instance._id); /* eslint-disable-line no-underscore-dangle */
84
+
85
+ console.log('\nAdapter instance configuration =>');
86
+ console.log('======================================');
87
+ console.log(adapterConfig);
88
+ console.log('======================================');
89
+
90
+ return adapterConfig;
91
+ };
92
+
93
+ const executeCommandOnInstance = async (command) => {
94
+ const adapterConfig = await getAdapterInstanceConfig(command);
95
+ if (!adapterConfig) {
96
+ process.exit(0);
97
+ }
98
+
99
+ switch (command) {
100
+ case 'connectivity': {
101
+ const { host } = adapterConfig.properties.properties;
102
+ console.log(`perform networking diagnositics to ${host}`);
103
+ utils.runConnectivity(host, true);
104
+ break;
105
+ }
106
+ case 'healthcheck': {
107
+ const adapterInstance = basicGet.getAdapterInstance(adapterConfig);
108
+ await utils.healthCheck(adapterInstance);
109
+ break;
110
+ }
111
+ case 'basicget': {
112
+ utils.runBasicGet(true);
113
+ break;
114
+ }
115
+ case 'troubleshoot': {
116
+ const adapter = { properties: adapterConfig };
117
+ await troubleshoot({}, true, true, adapter);
118
+ break;
119
+ }
120
+ default: {
121
+ console.error(`Unknown command: ${command}`);
122
+ }
123
+ }
124
+ return process.exit(0);
125
+ };
126
+
127
+ const executeUnderIAPInstallationDirectory = async (command) => {
128
+ if (command === 'install') {
129
+ const { database, serviceItem, pronghornProps } = await utils.getAdapterConfig();
130
+ const filter = { id: pronghornProps.id };
131
+ const profileItem = await database.collection(utils.IAP_PROFILES_COLLECTION).findOne(filter);
132
+ if (!profileItem) {
133
+ console.log(`Could not find IAP profile for id ${pronghornProps.id}`);
134
+ process.exit(0);
135
+ }
136
+ if (serviceItem) {
137
+ console.log(`A service by the name ${name} already exits!`);
138
+ if (rls.keyInYN(`Do you want to completely remove ${name}?`)) {
139
+ console.log(`Removing ${name} from db...`);
140
+ await database.collection(utils.SERVICE_CONFIGS_COLLECTION).deleteOne({ model: name });
141
+ console.log(`${name} removed from db.`);
142
+ if (profileItem.services.includes(serviceItem.name)) {
143
+ const serviceIndex = profileItem.services.indexOf(serviceItem.name);
144
+ profileItem.services.splice(serviceIndex, 1);
145
+ const update = { $set: { services: profileItem.services } };
146
+ await database.collection(utils.IAP_PROFILES_COLLECTION).updateOne(
147
+ { id: pronghornProps.id }, update
148
+ );
149
+ console.log(`${serviceItem.name} removed from profileItem.services.`);
150
+ console.log(`Rerun the script to reinstall ${serviceItem.name}.`);
151
+ process.exit(0);
152
+ } else {
153
+ process.exit(0);
154
+ }
155
+ } else {
156
+ console.log('Exiting...');
157
+ process.exit(0);
158
+ }
159
+ } else {
160
+ const dirname = utils.getCurrentExecutionPath();
161
+ utils.verifyInstallationDir(dirname, name);
162
+ utils.runTest();
163
+ if (rls.keyInYN(`Do you want to install ${name} to IAP?`)) {
164
+ console.log('Creating database entries...');
165
+ const adapter = utils.createAdapter(
166
+ pronghornProps, profileItem, sampleProperties, adapterPronghorn
167
+ );
168
+
169
+ adapter.properties.properties = await addAuthInfo(adapter.properties.properties);
170
+
171
+ await database.collection(utils.SERVICE_CONFIGS_COLLECTION).insertOne(adapter);
172
+ profileItem.services.push(adapter.name);
173
+ const update = { $set: { services: profileItem.services } };
174
+ await database.collection(utils.IAP_PROFILES_COLLECTION).updateOne(
175
+ { id: pronghornProps.id }, update
176
+ );
177
+ console.log('Database entry creation complete.');
178
+ }
179
+ console.log('Exiting...');
180
+ process.exit(0);
181
+ }
182
+ } else if (['healthcheck', 'basicget', 'connectivity', 'troubleshoot'].includes(command)) {
183
+ await executeCommandOnInstance(command);
184
+ }
185
+ };
186
+
187
+ const main = async (command) => {
188
+ if (!utils.areWeUnderIAPinstallationDirectory()) {
189
+ executeInStandaloneMode(command); // configuration from sampleproperties.json
190
+ } else {
191
+ executeUnderIAPInstallationDirectory(command); // configuration from $IAP_HOME/properties.json
192
+ }
193
+ };
194
+
195
+ program
196
+ .command('connectivity')
197
+ .alias('c')
198
+ .description('networking diagnostics')
199
+ .action(() => {
200
+ main('connectivity');
201
+ });
202
+
203
+ program
204
+ .command('install')
205
+ .alias('i')
206
+ .description('install current adapter')
207
+ .action(() => {
208
+ main('install');
209
+ });
210
+
211
+ program
212
+ .command('healthcheck')
213
+ .alias('hc')
214
+ .description('perfom none interative healthcheck with current setting')
215
+ .action(() => {
216
+ main('healthcheck');
217
+ });
218
+
219
+ program
220
+ .command('basicget')
221
+ .alias('bg')
222
+ .description('perfom basicget')
223
+ .action(() => {
224
+ main('basicget');
225
+ });
226
+
227
+ program
228
+ .command('troubleshoot')
229
+ .alias('tb')
230
+ .description('perfom troubleshooting')
231
+ .action(() => {
232
+ main('troubleshoot');
233
+ });
234
+
235
+ // Allow commander to parse `process.argv`
236
+ program.parse(process.argv);
237
+
238
+ if (process.argv.length < 3) {
239
+ main();
240
+ }
241
+ const allowedParams = ['install', 'healthcheck', 'basicget', 'connectivity', 'troubleshoot'];
242
+ if (process.argv.length === 3 && !allowedParams.includes(process.argv[2])) {
243
+ console.log(`unknown parameter ${process.argv[2]}`);
244
+ console.log('try `node troubleshootingAdapter.js -h` to see allowed parameters. Exiting...');
245
+ process.exit(0);
246
+ }