@alwaysai/device-agent 1.5.0 → 2.0.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 (305) hide show
  1. package/lib/application-control/config.d.ts.map +1 -1
  2. package/lib/application-control/config.js +8 -3
  3. package/lib/application-control/config.js.map +1 -1
  4. package/lib/application-control/environment-variables.d.ts +5 -5
  5. package/lib/application-control/environment-variables.d.ts.map +1 -1
  6. package/lib/application-control/environment-variables.js +25 -38
  7. package/lib/application-control/environment-variables.js.map +1 -1
  8. package/lib/application-control/environment-variables.test.js +27 -7
  9. package/lib/application-control/environment-variables.test.js.map +1 -1
  10. package/lib/application-control/index.d.ts +4 -4
  11. package/lib/application-control/index.d.ts.map +1 -1
  12. package/lib/application-control/index.js +1 -4
  13. package/lib/application-control/index.js.map +1 -1
  14. package/lib/application-control/install.d.ts +4 -1
  15. package/lib/application-control/install.d.ts.map +1 -1
  16. package/lib/application-control/install.js +24 -8
  17. package/lib/application-control/install.js.map +1 -1
  18. package/lib/application-control/models.d.ts +0 -11
  19. package/lib/application-control/models.d.ts.map +1 -1
  20. package/lib/application-control/models.js +5 -54
  21. package/lib/application-control/models.js.map +1 -1
  22. package/lib/application-control/utils.d.ts +0 -4
  23. package/lib/application-control/utils.d.ts.map +1 -1
  24. package/lib/application-control/utils.js +12 -22
  25. package/lib/application-control/utils.js.map +1 -1
  26. package/lib/cloud-connection/base-message-handler.d.ts +27 -0
  27. package/lib/cloud-connection/base-message-handler.d.ts.map +1 -0
  28. package/lib/cloud-connection/base-message-handler.js +72 -0
  29. package/lib/cloud-connection/base-message-handler.js.map +1 -0
  30. package/lib/cloud-connection/bootstrap-provision.js +3 -2
  31. package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
  32. package/lib/cloud-connection/connection-manager.d.ts +21 -0
  33. package/lib/cloud-connection/connection-manager.d.ts.map +1 -0
  34. package/lib/cloud-connection/connection-manager.js +158 -0
  35. package/lib/cloud-connection/connection-manager.js.map +1 -0
  36. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +9 -30
  37. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  38. package/lib/cloud-connection/device-agent-cloud-connection.js +69 -508
  39. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  40. package/lib/cloud-connection/device-agent-message-handler.d.ts +22 -0
  41. package/lib/cloud-connection/device-agent-message-handler.d.ts.map +1 -0
  42. package/lib/cloud-connection/device-agent-message-handler.js +357 -0
  43. package/lib/cloud-connection/device-agent-message-handler.js.map +1 -0
  44. package/lib/cloud-connection/device-agent.d.ts.map +1 -1
  45. package/lib/cloud-connection/device-agent.js +11 -9
  46. package/lib/cloud-connection/device-agent.js.map +1 -1
  47. package/lib/cloud-connection/live-updates-handler.d.ts +19 -28
  48. package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
  49. package/lib/cloud-connection/live-updates-handler.js +60 -172
  50. package/lib/cloud-connection/live-updates-handler.js.map +1 -1
  51. package/lib/cloud-connection/live-updates-handler.test.js +71 -165
  52. package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
  53. package/lib/cloud-connection/message-dispatcher.d.ts +10 -0
  54. package/lib/cloud-connection/message-dispatcher.d.ts.map +1 -0
  55. package/lib/cloud-connection/message-dispatcher.js +27 -0
  56. package/lib/cloud-connection/message-dispatcher.js.map +1 -0
  57. package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
  58. package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
  59. package/lib/cloud-connection/passthrough-handler.js +30 -11
  60. package/lib/cloud-connection/passthrough-handler.js.map +1 -1
  61. package/lib/cloud-connection/shadow-handler.d.ts +11 -3
  62. package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
  63. package/lib/cloud-connection/shadow-handler.js +133 -28
  64. package/lib/cloud-connection/shadow-handler.js.map +1 -1
  65. package/lib/cloud-connection/shadow-handler.test.js +45 -57
  66. package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
  67. package/lib/cloud-connection/shadow.d.ts.map +1 -1
  68. package/lib/cloud-connection/shadow.js +2 -1
  69. package/lib/cloud-connection/shadow.js.map +1 -1
  70. package/lib/cloud-connection/transaction-manager.d.ts +12 -3
  71. package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
  72. package/lib/cloud-connection/transaction-manager.js +29 -28
  73. package/lib/cloud-connection/transaction-manager.js.map +1 -1
  74. package/lib/cloud-connection/transaction-manager.test.js +46 -5
  75. package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
  76. package/lib/device-control/device-control.d.ts +8 -8
  77. package/lib/device-control/device-control.d.ts.map +1 -1
  78. package/lib/device-control/device-control.js +95 -71
  79. package/lib/device-control/device-control.js.map +1 -1
  80. package/lib/docker/docker-compose.d.ts.map +1 -1
  81. package/lib/docker/docker-compose.js +2 -1
  82. package/lib/docker/docker-compose.js.map +1 -1
  83. package/lib/infrastructure/agent-config.d.ts +2 -1
  84. package/lib/infrastructure/agent-config.d.ts.map +1 -1
  85. package/lib/infrastructure/agent-config.js +7 -7
  86. package/lib/infrastructure/agent-config.js.map +1 -1
  87. package/lib/infrastructure/agent-config.test.js +3 -1
  88. package/lib/infrastructure/agent-config.test.js.map +1 -1
  89. package/lib/infrastructure/config-check-utility.d.ts +6 -0
  90. package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
  91. package/lib/infrastructure/config-check-utility.js +67 -0
  92. package/lib/infrastructure/config-check-utility.js.map +1 -0
  93. package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
  94. package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
  95. package/lib/infrastructure/config-check-utility.test.js +109 -0
  96. package/lib/infrastructure/config-check-utility.test.js.map +1 -0
  97. package/lib/infrastructure/device-certificate.d.ts +10 -0
  98. package/lib/infrastructure/device-certificate.d.ts.map +1 -0
  99. package/lib/infrastructure/device-certificate.js +47 -0
  100. package/lib/infrastructure/device-certificate.js.map +1 -0
  101. package/lib/infrastructure/device-certificate.test.d.ts +2 -0
  102. package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
  103. package/lib/infrastructure/device-certificate.test.js +24 -0
  104. package/lib/infrastructure/device-certificate.test.js.map +1 -0
  105. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
  106. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
  107. package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
  108. package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
  109. package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
  110. package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
  111. package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
  112. package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
  113. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
  114. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
  115. package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
  116. package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
  117. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
  118. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
  119. package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
  120. package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
  121. package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
  122. package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
  123. package/lib/infrastructure/require-files-present-ready.test.js +44 -0
  124. package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
  125. package/lib/infrastructure/required-config-checks.d.ts +2 -0
  126. package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
  127. package/lib/infrastructure/required-config-checks.js +30 -0
  128. package/lib/infrastructure/required-config-checks.js.map +1 -0
  129. package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
  130. package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
  131. package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
  132. package/lib/jobs/job-handler.d.ts +23 -0
  133. package/lib/jobs/job-handler.d.ts.map +1 -0
  134. package/lib/jobs/job-handler.js +131 -0
  135. package/lib/jobs/job-handler.js.map +1 -0
  136. package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
  137. package/lib/local-connection/rabbitmq-connection.js +14 -14
  138. package/lib/local-connection/rabbitmq-connection.js.map +1 -1
  139. package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts +8 -0
  140. package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts.map +1 -0
  141. package/lib/secure-tunneling/secure-tunnel-message-handler.js +42 -0
  142. package/lib/secure-tunneling/secure-tunnel-message-handler.js.map +1 -0
  143. package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
  144. package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
  145. package/lib/secure-tunneling/secure-tunneling.js +21 -16
  146. package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
  147. package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
  148. package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
  149. package/lib/subcommands/app/analytics.d.ts.map +1 -1
  150. package/lib/subcommands/app/analytics.js +1 -2
  151. package/lib/subcommands/app/analytics.js.map +1 -1
  152. package/lib/subcommands/app/env-vars.d.ts +4 -0
  153. package/lib/subcommands/app/env-vars.d.ts.map +1 -1
  154. package/lib/subcommands/app/env-vars.js +52 -6
  155. package/lib/subcommands/app/env-vars.js.map +1 -1
  156. package/lib/subcommands/app/index.d.ts.map +1 -1
  157. package/lib/subcommands/app/index.js +1 -3
  158. package/lib/subcommands/app/index.js.map +1 -1
  159. package/lib/subcommands/app/models.d.ts +0 -11
  160. package/lib/subcommands/app/models.d.ts.map +1 -1
  161. package/lib/subcommands/app/models.js +2 -58
  162. package/lib/subcommands/app/models.js.map +1 -1
  163. package/lib/subcommands/app/shadow.d.ts.map +1 -1
  164. package/lib/subcommands/app/shadow.js +6 -5
  165. package/lib/subcommands/app/shadow.js.map +1 -1
  166. package/lib/subcommands/app/version.d.ts +2 -0
  167. package/lib/subcommands/app/version.d.ts.map +1 -1
  168. package/lib/subcommands/app/version.js +16 -6
  169. package/lib/subcommands/app/version.js.map +1 -1
  170. package/lib/subcommands/config.d.ts +2 -0
  171. package/lib/subcommands/config.d.ts.map +1 -0
  172. package/lib/subcommands/config.js +39 -0
  173. package/lib/subcommands/config.js.map +1 -0
  174. package/lib/subcommands/device/clean.d.ts +1 -1
  175. package/lib/subcommands/device/clean.d.ts.map +1 -1
  176. package/lib/subcommands/device/clean.js +23 -13
  177. package/lib/subcommands/device/clean.js.map +1 -1
  178. package/lib/subcommands/device/index.d.ts.map +1 -1
  179. package/lib/subcommands/device/index.js +3 -1
  180. package/lib/subcommands/device/index.js.map +1 -1
  181. package/lib/subcommands/device/init.js +8 -8
  182. package/lib/subcommands/device/init.js.map +1 -1
  183. package/lib/subcommands/device/migrate.d.ts +2 -0
  184. package/lib/subcommands/device/migrate.d.ts.map +1 -0
  185. package/lib/subcommands/device/migrate.js +24 -0
  186. package/lib/subcommands/device/migrate.js.map +1 -0
  187. package/lib/subcommands/device/refresh.d.ts.map +1 -1
  188. package/lib/subcommands/device/refresh.js +1 -0
  189. package/lib/subcommands/device/refresh.js.map +1 -1
  190. package/lib/subcommands/index.d.ts +1 -1
  191. package/lib/subcommands/index.d.ts.map +1 -1
  192. package/lib/subcommands/index.js +3 -1
  193. package/lib/subcommands/index.js.map +1 -1
  194. package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
  195. package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
  196. package/lib/util/aai-error.d.ts +12 -0
  197. package/lib/util/aai-error.d.ts.map +1 -0
  198. package/lib/util/aai-error.js +11 -0
  199. package/lib/util/aai-error.js.map +1 -0
  200. package/lib/util/aws-regions.d.ts +2 -0
  201. package/lib/util/aws-regions.d.ts.map +1 -0
  202. package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
  203. package/lib/util/aws-regions.js.map +1 -0
  204. package/lib/util/check-for-updates.d.ts.map +1 -1
  205. package/lib/util/check-for-updates.js +5 -28
  206. package/lib/util/check-for-updates.js.map +1 -1
  207. package/lib/util/clean-certs.d.ts.map +1 -1
  208. package/lib/util/clean-certs.js +5 -4
  209. package/lib/util/clean-certs.js.map +1 -1
  210. package/lib/util/directories.d.ts +4 -18
  211. package/lib/util/directories.d.ts.map +1 -1
  212. package/lib/util/directories.js +18 -32
  213. package/lib/util/directories.js.map +1 -1
  214. package/lib/util/file.d.ts +4 -0
  215. package/lib/util/file.d.ts.map +1 -1
  216. package/lib/util/file.js +65 -4
  217. package/lib/util/file.js.map +1 -1
  218. package/lib/util/get-device-id.d.ts.map +1 -1
  219. package/lib/util/get-device-id.js +7 -1
  220. package/lib/util/get-device-id.js.map +1 -1
  221. package/lib/util/http-client.js +3 -3
  222. package/lib/util/http-client.js.map +1 -1
  223. package/package.json +19 -17
  224. package/readme.md +12 -32
  225. package/src/application-control/config.ts +9 -12
  226. package/src/application-control/environment-variables.test.ts +28 -7
  227. package/src/application-control/environment-variables.ts +42 -59
  228. package/src/application-control/index.ts +3 -16
  229. package/src/application-control/install.ts +39 -13
  230. package/src/application-control/models.ts +6 -87
  231. package/src/application-control/utils.ts +10 -25
  232. package/src/cloud-connection/base-message-handler.ts +118 -0
  233. package/src/cloud-connection/bootstrap-provision.ts +7 -7
  234. package/src/cloud-connection/connection-manager.ts +187 -0
  235. package/src/cloud-connection/device-agent-cloud-connection.ts +130 -723
  236. package/src/cloud-connection/device-agent-message-handler.ts +642 -0
  237. package/src/cloud-connection/device-agent.ts +16 -7
  238. package/src/cloud-connection/live-updates-handler.test.ts +121 -189
  239. package/src/cloud-connection/live-updates-handler.ts +105 -232
  240. package/src/cloud-connection/message-dispatcher.ts +33 -0
  241. package/src/cloud-connection/passthrough-handler.ts +55 -18
  242. package/src/cloud-connection/shadow-handler.test.ts +45 -57
  243. package/src/cloud-connection/shadow-handler.ts +224 -54
  244. package/src/cloud-connection/shadow.ts +4 -1
  245. package/src/cloud-connection/transaction-manager.test.ts +68 -6
  246. package/src/cloud-connection/transaction-manager.ts +69 -41
  247. package/src/device-control/device-control.ts +102 -70
  248. package/src/docker/docker-compose.ts +3 -2
  249. package/src/infrastructure/agent-config.test.ts +6 -2
  250. package/src/infrastructure/agent-config.ts +8 -7
  251. package/src/infrastructure/config-check-utility.test.ts +154 -0
  252. package/src/infrastructure/config-check-utility.ts +77 -0
  253. package/src/infrastructure/device-certificate.test.ts +40 -0
  254. package/src/infrastructure/device-certificate.ts +58 -0
  255. package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
  256. package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
  257. package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
  258. package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
  259. package/src/infrastructure/require-files-present-ready.test.ts +53 -0
  260. package/src/infrastructure/required-config-checks.ts +33 -0
  261. package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
  262. package/src/jobs/job-handler.ts +146 -0
  263. package/src/local-connection/rabbitmq-connection.ts +22 -17
  264. package/src/secure-tunneling/secure-tunnel-message-handler.ts +56 -0
  265. package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
  266. package/src/secure-tunneling/secure-tunneling.ts +41 -29
  267. package/src/subcommands/app/analytics.ts +2 -4
  268. package/src/subcommands/app/env-vars.ts +72 -9
  269. package/src/subcommands/app/index.ts +3 -11
  270. package/src/subcommands/app/models.ts +5 -81
  271. package/src/subcommands/app/shadow.ts +6 -5
  272. package/src/subcommands/app/version.ts +23 -6
  273. package/src/subcommands/config.ts +42 -0
  274. package/src/subcommands/device/clean.ts +31 -17
  275. package/src/subcommands/device/index.ts +3 -1
  276. package/src/subcommands/device/init.ts +11 -11
  277. package/src/subcommands/device/migrate.ts +20 -0
  278. package/src/subcommands/device/refresh.ts +1 -0
  279. package/src/subcommands/index.ts +3 -1
  280. package/src/util/aai-error.ts +20 -0
  281. package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
  282. package/src/util/check-for-updates.ts +14 -30
  283. package/src/util/clean-certs.ts +8 -4
  284. package/src/util/directories.ts +23 -67
  285. package/src/util/file.ts +83 -3
  286. package/src/util/get-device-id.ts +7 -7
  287. package/src/util/http-client.ts +2 -2
  288. package/lib/util/cloud-mode-ready.d.ts +0 -3
  289. package/lib/util/cloud-mode-ready.d.ts.map +0 -1
  290. package/lib/util/cloud-mode-ready.js.map +0 -1
  291. package/lib/util/download-file.d.ts +0 -6
  292. package/lib/util/download-file.d.ts.map +0 -1
  293. package/lib/util/download-file.js +0 -25
  294. package/lib/util/download-file.js.map +0 -1
  295. package/lib/util/fetch-with-timeout.d.ts +0 -4
  296. package/lib/util/fetch-with-timeout.d.ts.map +0 -1
  297. package/lib/util/fetch-with-timeout.js +0 -30
  298. package/lib/util/fetch-with-timeout.js.map +0 -1
  299. package/lib/util/parsing.d.ts +0 -2
  300. package/lib/util/parsing.d.ts.map +0 -1
  301. package/lib/util/parsing.js +0 -17
  302. package/lib/util/parsing.js.map +0 -1
  303. package/src/util/download-file.ts +0 -25
  304. package/src/util/fetch-with-timeout.ts +0 -35
  305. package/src/util/parsing.ts +0 -11
@@ -3,7 +3,8 @@ import {
3
3
  ConfigFileSchemaReturnType
4
4
  } from '@alwaysai/config-nodejs';
5
5
  import Ajv, { JSONSchemaType } from 'ajv';
6
- import { homedir } from 'os';
6
+ import { getDeviceConfigPath } from 'alwaysai/lib/infrastructure';
7
+ import { LOCAL_AAI_CFG_DIR } from 'alwaysai/lib/paths';
7
8
  import { join } from 'path';
8
9
 
9
10
  export interface AppBackupConfig {
@@ -54,16 +55,16 @@ const schema: JSONSchemaType<AgentConfig> = {
54
55
  const ajv = new Ajv();
55
56
  const validateFunction = ajv.compile(schema);
56
57
 
57
- const ALWAYSAI_CONFIG_DIR = join(homedir(), '.config', 'alwaysai');
58
+ export const AGENT_CONFIG_FILE_NAME = 'alwaysai.agent.json';
58
59
 
59
- const AGENT_CONFIG_FILE_NAME = 'alwaysai.agent.json';
60
-
61
- export function AgentConfigFile(dir = ALWAYSAI_CONFIG_DIR) {
62
- const path = join(dir, AGENT_CONFIG_FILE_NAME);
60
+ export function AgentConfigFile(filePath?: string) {
61
+ const path =
62
+ filePath ??
63
+ join(LOCAL_AAI_CFG_DIR, getDeviceConfigPath(), AGENT_CONFIG_FILE_NAME);
63
64
  const initialValue: AgentConfig = {
64
65
  applications: []
65
66
  };
66
- const configFile = ConfigFileSchema({
67
+ const configFile = ConfigFileSchema<AgentConfig>({
67
68
  path,
68
69
  validateFunction,
69
70
  initialValue
@@ -0,0 +1,154 @@
1
+ import { DeviceConfig, DeviceConfigFile } from 'alwaysai/lib/core/device';
2
+ import {
3
+ DEVICE_CONFIG_FILE_NAME,
4
+ DeviceCertificates,
5
+ getDeviceConfigPath
6
+ } from 'alwaysai/lib/infrastructure';
7
+ import { JsSpawner } from 'alwaysai/lib/util';
8
+ import { join } from 'path';
9
+ import { rimraf } from 'rimraf';
10
+ import * as tempy from 'tempy';
11
+ import {
12
+ checkAllFilesArePresent,
13
+ checkCertificatesPresent,
14
+ checkDeviceConfigPresent
15
+ } from './config-check-utility';
16
+ import { LegacyFiles } from './legacy-migration/legacy-files';
17
+
18
+ class TestDeviceCertificates extends DeviceCertificates {
19
+ constructor(baseDir) {
20
+ super(baseDir);
21
+ }
22
+ }
23
+
24
+ describe('test requiredConfigFilesPresentAndValid', () => {
25
+ let tmpDir;
26
+
27
+ beforeEach(async () => {
28
+ tmpDir = tempy.directory();
29
+ });
30
+
31
+ afterEach(async () => {
32
+ await rimraf(tmpDir);
33
+ jest.clearAllMocks();
34
+ });
35
+
36
+ it('test checkAllFilesArePresent returns false in empty directory', async () => {
37
+ const legacyFiles = LegacyFiles(tmpDir);
38
+ const filesPresent = await checkAllFilesArePresent(
39
+ Object.values(legacyFiles.getLegacyFileMigrationPaths())
40
+ );
41
+ expect(filesPresent).toBe(false);
42
+ });
43
+
44
+ it('test device config present and valid, checkDeviceConfigPresent returns true', async () => {
45
+ // write device credentials data
46
+ const deviceCredentialsData: DeviceConfig = {
47
+ systemId: 'production',
48
+ deviceUuid: '123456-78-901-2345',
49
+ refreshToken: 'refresh',
50
+ accessToken: 'access',
51
+ idToken: 'id'
52
+ };
53
+ const spawner = JsSpawner({ path: tmpDir });
54
+ await spawner.mkdirp(join(tmpDir, getDeviceConfigPath()));
55
+ const filePath = join(
56
+ tmpDir,
57
+ getDeviceConfigPath(),
58
+ DEVICE_CONFIG_FILE_NAME
59
+ );
60
+ await spawner.writeFile(filePath, JSON.stringify(deviceCredentialsData));
61
+ const newConfigsPresent = await checkDeviceConfigPresent(tmpDir);
62
+ expect(newConfigsPresent).toBe(true);
63
+ });
64
+
65
+ it.each([
66
+ {
67
+ // invalid systemId
68
+ systemId: 'blah',
69
+ deviceUuid: '123456-78-901-2345',
70
+ refreshToken: 'refresh',
71
+ accessToken: 'access',
72
+ idToken: 'id'
73
+ },
74
+ {
75
+ // missing refreshToken
76
+ systemId: 'production',
77
+ deviceUuid: '123456-78-901-2345',
78
+ accessToken: 'access',
79
+ idToken: 'id'
80
+ },
81
+ {
82
+ // missing accessToken
83
+ systemId: 'development',
84
+ deviceUuid: '123456-78-901-2345',
85
+ refreshToken: 'refresh',
86
+ idToken: 'id'
87
+ },
88
+ {
89
+ // missing idToken
90
+ systemId: 'development',
91
+ deviceUuid: '123456-78-901-2345',
92
+ refreshToken: 'refresh'
93
+ }
94
+ ])(
95
+ 'test device config has validation errors, checkDeviceConfigPresent returns false',
96
+ async (deviceCredentialsData) => {
97
+ const spawner = JsSpawner({ path: tmpDir });
98
+ await spawner.mkdirp(join(tmpDir, getDeviceConfigPath()));
99
+ const filePath = join(
100
+ tmpDir,
101
+ getDeviceConfigPath(),
102
+ DEVICE_CONFIG_FILE_NAME
103
+ );
104
+ await spawner.writeFile(filePath, JSON.stringify(deviceCredentialsData));
105
+ const deviceConfig = DeviceConfigFile(
106
+ join(tmpDir, getDeviceConfigPath(), DEVICE_CONFIG_FILE_NAME)
107
+ );
108
+ expect(deviceConfig.exists()).toBe(true);
109
+ const newConfigsPresent = await checkDeviceConfigPresent(tmpDir);
110
+ expect(newConfigsPresent).toBe(false);
111
+ }
112
+ );
113
+
114
+ it('test device config is missing, checkDeviceConfigPresent returns false', async () => {
115
+ const deviceConfig = DeviceConfigFile(
116
+ join(tmpDir, getDeviceConfigPath(), DEVICE_CONFIG_FILE_NAME)
117
+ );
118
+ expect(deviceConfig.exists()).toBe(false);
119
+ const newConfigsPresent = await checkDeviceConfigPresent(tmpDir);
120
+ expect(newConfigsPresent).toBe(false);
121
+ });
122
+
123
+ it('test empty certificates folder, checkCertificatesPresent returns false', async () => {
124
+ const certsPresent = await checkCertificatesPresent(tmpDir);
125
+ expect(certsPresent).toBe(false);
126
+ });
127
+
128
+ test('test full certificates folder, checkCertificatesPresent returns true', async () => {
129
+ // write certificates
130
+ const testCerts = new TestDeviceCertificates(tmpDir);
131
+ const spawner = JsSpawner({ path: tmpDir });
132
+ const certFilePath = testCerts.getCertificateDirectoryName();
133
+ await spawner.mkdirp(join(tmpDir, certFilePath));
134
+ await spawner.writeFile(
135
+ join(tmpDir, certFilePath, testCerts.getCertificateFileName()),
136
+ 'certificate data'
137
+ );
138
+ console.log(
139
+ 'join(tmpDir, certFilePath, testCerts.getCertificateFileName())',
140
+ join(tmpDir, certFilePath, testCerts.getCertificateFileName())
141
+ );
142
+ await spawner.writeFile(
143
+ join(tmpDir, certFilePath, testCerts.getPrivateKeyFileName()),
144
+ 'private key data'
145
+ );
146
+ await spawner.writeFile(
147
+ join(tmpDir, certFilePath, testCerts.getRootCertificateFileName()),
148
+ 'root cert data'
149
+ );
150
+
151
+ const certsPresent = await checkCertificatesPresent(tmpDir);
152
+ expect(certsPresent).toBe(true);
153
+ });
154
+ });
@@ -0,0 +1,77 @@
1
+ import { DeviceConfigFile } from 'alwaysai/lib/core/device';
2
+ import {
3
+ DEVICE_CONFIG_FILE_NAME,
4
+ LocalAaiCfg,
5
+ LocalDeviceCertificates,
6
+ getDeviceConfigPath
7
+ } from 'alwaysai/lib/infrastructure';
8
+ import { exists, stringifyError } from 'alwaysai/lib/util';
9
+ import { join } from 'path';
10
+ import { logger } from '../util/logger';
11
+
12
+ export const validConfigMessage = 'Device config is present and valid.';
13
+
14
+ export async function checkDeviceConfigPresent(
15
+ baseDir?: string
16
+ ): Promise<boolean> {
17
+ logger.debug('Checking for required device configuraton file.');
18
+ const deviceConfig = DeviceConfigFile(
19
+ baseDir
20
+ ? join(baseDir, getDeviceConfigPath(), DEVICE_CONFIG_FILE_NAME)
21
+ : undefined
22
+ );
23
+ if (deviceConfig.exists()) {
24
+ try {
25
+ deviceConfig.read();
26
+ logger.debug(validConfigMessage);
27
+ return true;
28
+ } catch (e) {
29
+ logger.debug(stringifyError(e));
30
+ logger.debug(`${JSON.stringify(deviceConfig.getErrors(), null, 2)}`);
31
+ }
32
+ }
33
+ return false;
34
+ }
35
+
36
+ export async function checkCertificatesPresent(baseDir?: string) {
37
+ logger.debug('Checking for required certificates.');
38
+ const deviceCertificates = new LocalDeviceCertificates(baseDir);
39
+
40
+ const certificateFilesPresent = await checkAllFilesArePresent([
41
+ deviceCertificates.getCertificateFilePath(),
42
+ deviceCertificates.getPrivateKeyFilePath(),
43
+ deviceCertificates.getRootCertificateFilePath()
44
+ ]);
45
+ return certificateFilesPresent;
46
+ }
47
+
48
+ export async function checkAaiConfigPresent(
49
+ baseDir?: string
50
+ ): Promise<boolean> {
51
+ logger.debug('Checking for required alwaysai configuraton file.');
52
+ const localAaiCfg = new LocalAaiCfg(baseDir);
53
+
54
+ try {
55
+ await localAaiCfg.readAaiCfgFile();
56
+ logger.debug(validConfigMessage);
57
+ return true;
58
+ } catch (e) {
59
+ logger.debug(stringifyError(e));
60
+ logger.debug(
61
+ `${JSON.stringify(localAaiCfg.getValidationErrors(), null, 2)}`
62
+ );
63
+ }
64
+ return false;
65
+ }
66
+
67
+ export async function checkAllFilesArePresent(requiredFiles: string[]) {
68
+ for (const path of requiredFiles) {
69
+ logger.debug(`Checking if file ${path} is present`);
70
+ if (!(await exists(path))) {
71
+ logger.debug(`${path} not present.`);
72
+ return false;
73
+ }
74
+ }
75
+ logger.debug('All files are present');
76
+ return true;
77
+ }
@@ -0,0 +1,40 @@
1
+ import {
2
+ LocalDeviceCertificates,
3
+ getDeviceConfigPath,
4
+ getLocalDeviceConfigDirectoryPath
5
+ } from 'alwaysai/lib/infrastructure';
6
+ import { LOCAL_AAI_CFG_DIR } from 'alwaysai/lib/paths';
7
+ import { join } from 'path';
8
+ import {
9
+ getBootstrapCertificateDirectoryPath,
10
+ getBootstrapCertificateFileName,
11
+ getBootstrapIDFileName,
12
+ getBootstrapPrivateKeyFileName
13
+ } from './device-certificate';
14
+
15
+ describe('test different bootstrap certificate file paths', () => {
16
+ it('test bootstrap certificate directory paths and filenames', async () => {
17
+ const boostrapDir = getBootstrapCertificateDirectoryPath();
18
+ const mainConfigDir = getLocalDeviceConfigDirectoryPath();
19
+ const certificates = new LocalDeviceCertificates();
20
+ const mainCertDir = certificates.getCertificateDirectoryPath();
21
+ expect(mainConfigDir).toEqual(
22
+ join(LOCAL_AAI_CFG_DIR, getDeviceConfigPath())
23
+ );
24
+ expect(mainCertDir).toEqual(
25
+ join(LOCAL_AAI_CFG_DIR, getDeviceConfigPath(), 'certificates')
26
+ );
27
+ expect(boostrapDir).toEqual(join(mainCertDir, 'bootstrap-certificates'));
28
+
29
+ const boostrapCertFileName = getBootstrapCertificateFileName();
30
+ expect(boostrapCertFileName).toEqual('aai-claim-cert_prod.pem.crt');
31
+
32
+ const boostrapIDFileName = getBootstrapIDFileName();
33
+ expect(boostrapIDFileName).toEqual('aai-claim-cert-id_prod.txt');
34
+
35
+ const boostrapPrivateKeyFileName = getBootstrapPrivateKeyFileName();
36
+ expect(boostrapPrivateKeyFileName).toEqual(
37
+ 'aai-claim-private-key_prod.pem.key'
38
+ );
39
+ });
40
+ });
@@ -0,0 +1,58 @@
1
+ import {
2
+ DEVICE_CERTIFICATES_DIRECTORY_NAME,
3
+ getDeviceConfigPath,
4
+ getLocalDeviceConfigDirectoryPath
5
+ } from 'alwaysai/lib/infrastructure';
6
+ import { join } from 'path';
7
+ import { shortenSystemId } from '../util/directories';
8
+
9
+ /*===================================================================
10
+ Bootstrap Certificates
11
+ ===================================================================*/
12
+
13
+ export const BOOTSTRAP_DIR_NAME = 'bootstrap-certificates';
14
+
15
+ export function getBootstrapPrivateKeyFileName() {
16
+ return `aai-claim-private-key_${shortenSystemId()}.pem.key`;
17
+ }
18
+
19
+ export function getBootstrapCertificateFileName() {
20
+ return `aai-claim-cert_${shortenSystemId()}.pem.crt`;
21
+ }
22
+
23
+ export function getBootstrapIDFileName() {
24
+ return `aai-claim-cert-id_${shortenSystemId()}.txt`;
25
+ }
26
+
27
+ export const CERTIFICATE_OWNERSHIP_TOKEN_FILE_NAME =
28
+ 'certificate-ownership-token.txt';
29
+
30
+ export function getBootstrapCertificateDirectoryPath(baseDir?) {
31
+ const LOCAL_DEVICE_DIRECTORY_PATH = baseDir
32
+ ? join(baseDir, getDeviceConfigPath())
33
+ : getLocalDeviceConfigDirectoryPath();
34
+ const bootstrapCertificateDirectoryPath = join(
35
+ LOCAL_DEVICE_DIRECTORY_PATH, // {homedir}/.config/alwaysai/device{systemId},
36
+ DEVICE_CERTIFICATES_DIRECTORY_NAME, // certificates
37
+ BOOTSTRAP_DIR_NAME // bootstrap-certificates
38
+ );
39
+ return bootstrapCertificateDirectoryPath;
40
+ }
41
+
42
+ export function getBootstrapPrivateKeyFilePath() {
43
+ return join(
44
+ getBootstrapCertificateDirectoryPath(),
45
+ getBootstrapPrivateKeyFileName()
46
+ );
47
+ }
48
+
49
+ export function getBootstrapCertificateFilePath() {
50
+ return join(
51
+ getBootstrapCertificateDirectoryPath(),
52
+ getBootstrapCertificateFileName()
53
+ );
54
+ }
55
+
56
+ export function getBootstrapIDFilePath() {
57
+ return join(getBootstrapCertificateDirectoryPath(), getBootstrapIDFileName());
58
+ }
@@ -0,0 +1,88 @@
1
+ import { ConfigFileSchemaReturnType } from '@alwaysai/config-nodejs/lib/config-file-schema';
2
+ import {
3
+ AaiConfig,
4
+ DEVICE_CERTIFICATES_DIRECTORY_NAME
5
+ } from 'alwaysai/lib/infrastructure';
6
+ import {
7
+ ALWAYSAI_CONFIG_FILE_NAME,
8
+ DEVICE_TOKEN_FILE_NAME
9
+ } from 'alwaysai/lib/paths';
10
+ import { JsSpawner } from 'alwaysai/lib/util';
11
+ import { join } from 'path';
12
+ import { rimraf } from 'rimraf';
13
+ import * as tempy from 'tempy';
14
+ import { AGENT_CONFIG_FILE_NAME } from '../agent-config';
15
+ import {
16
+ LegacyAaiConfig,
17
+ LegacyAaiConfigFile,
18
+ LegacyFiles
19
+ } from './legacy-files';
20
+
21
+ describe('test LegacyFiles function', () => {
22
+ let tmpDir;
23
+ tmpDir = tempy.directory();
24
+
25
+ beforeAll(async () => {
26
+ jest.resetModules();
27
+ jest.clearAllMocks();
28
+ tmpDir = tempy.directory();
29
+ });
30
+ afterAll(async () => {
31
+ await rimraf(tmpDir);
32
+ });
33
+
34
+ test('test LegacyAaiConfigFile', async () => {
35
+ const deviceId = '123-4567-8910-1234';
36
+ const systemId = 'production';
37
+ const aaiConfig: LegacyAaiConfig = {
38
+ systemId: systemId,
39
+ deviceUuid: deviceId
40
+ };
41
+ const spawner = JsSpawner({ path: tmpDir });
42
+ await spawner.writeFile(
43
+ join(tmpDir, ALWAYSAI_CONFIG_FILE_NAME),
44
+ JSON.stringify(aaiConfig)
45
+ );
46
+ const legacyAaiConfig = LegacyAaiConfigFile(tmpDir);
47
+ const parsedAaiConfig = legacyAaiConfig.read();
48
+ expect(parsedAaiConfig.deviceUuid).toEqual(deviceId);
49
+ expect(parsedAaiConfig.systemId).toEqual(systemId);
50
+ });
51
+
52
+ test('test invalid LegacyAaiConfigFile', async () => {
53
+ const deviceId = '123-4567-8910-1234';
54
+ const invalidAaiConfig = {
55
+ deviceUuid: deviceId
56
+ };
57
+ const spawner = JsSpawner({ path: tmpDir });
58
+ await spawner.writeFile(
59
+ join(tmpDir, ALWAYSAI_CONFIG_FILE_NAME),
60
+ JSON.stringify(invalidAaiConfig)
61
+ );
62
+ const legacyAaiConfig = LegacyAaiConfigFile(tmpDir);
63
+ expect(() => {
64
+ legacyAaiConfig.read();
65
+ }).toThrowError();
66
+ });
67
+
68
+ test('test LegacyFiles with baseDir return values', async () => {
69
+ const legacyFiles = LegacyFiles(tmpDir);
70
+ const filePath = legacyFiles.getFilePath();
71
+ expect(filePath).toBe(tmpDir);
72
+ const legacyCerts = legacyFiles.getLegacyCertificates();
73
+ expect(legacyCerts.getBaseCertificateDirectoryPath()).toBe(tmpDir);
74
+ const legacyMigrationFiles = legacyFiles.getLegacyFileMigrationPaths();
75
+ expect(legacyMigrationFiles.agentConfig).toEqual(
76
+ join(tmpDir, AGENT_CONFIG_FILE_NAME)
77
+ );
78
+ expect(legacyMigrationFiles.aaiConfig).toEqual(
79
+ join(tmpDir, ALWAYSAI_CONFIG_FILE_NAME)
80
+ );
81
+ expect(legacyMigrationFiles.credentialsConfig).toEqual(
82
+ join(tmpDir, DEVICE_TOKEN_FILE_NAME)
83
+ );
84
+ expect(legacyMigrationFiles.deviceCerts).toEqual(
85
+ join(tmpDir, DEVICE_CERTIFICATES_DIRECTORY_NAME)
86
+ );
87
+ });
88
+ });
@@ -0,0 +1,101 @@
1
+ import {
2
+ ConfigFileSchema,
3
+ ConfigFileSchemaReturnType
4
+ } from '@alwaysai/config-nodejs';
5
+ import Ajv, { JSONSchemaType } from 'ajv';
6
+ import { SYSTEM_IDS, SystemId } from 'alwaysai/lib/constants';
7
+ import { LocalLegacyDeviceCertificates } from 'alwaysai/lib/infrastructure';
8
+ import {
9
+ ALWAYSAI_CONFIG_FILE_NAME,
10
+ DEVICE_TOKEN_FILE_NAME,
11
+ LOCAL_AAI_CFG_DIR
12
+ } from 'alwaysai/lib/paths';
13
+ import { join } from 'path';
14
+ import { DEVICE_AGENT_CFG_DIR } from '../../util/directories';
15
+ import { AGENT_CONFIG_FILE_NAME, AgentConfigFile } from '../agent-config';
16
+
17
+ // alwaysai.config.json
18
+ export const LEGACY_AAI_CONFIG_FILE_DIR = join(
19
+ LOCAL_AAI_CFG_DIR,
20
+ ALWAYSAI_CONFIG_FILE_NAME
21
+ );
22
+
23
+ export interface LegacyAaiConfig {
24
+ systemId: SystemId;
25
+ deviceUuid: string;
26
+ }
27
+
28
+ export const legacyAaiConfigSchema: JSONSchemaType<LegacyAaiConfig> = {
29
+ type: 'object',
30
+ properties: {
31
+ systemId: {
32
+ type: 'string',
33
+ enum: SYSTEM_IDS
34
+ },
35
+ deviceUuid: {
36
+ type: 'string'
37
+ }
38
+ },
39
+ required: ['systemId', 'deviceUuid']
40
+ };
41
+
42
+ const ajv = new Ajv();
43
+
44
+ export const validateLegacyAaiConfig = ajv.compile(legacyAaiConfigSchema);
45
+
46
+ export function LegacyAaiConfigFile(
47
+ baseDir?: string
48
+ ): ConfigFileSchemaReturnType<LegacyAaiConfig> {
49
+ const filePath = baseDir
50
+ ? join(baseDir, ALWAYSAI_CONFIG_FILE_NAME)
51
+ : LEGACY_AAI_CONFIG_FILE_DIR;
52
+ const configFile = ConfigFileSchema({
53
+ path: filePath,
54
+ validateFunction: validateLegacyAaiConfig
55
+ });
56
+
57
+ return configFile;
58
+ }
59
+
60
+ export function LegacyFiles(baseDir?: string) {
61
+ const filePath = baseDir ?? LOCAL_AAI_CFG_DIR;
62
+ const legacyCertificates = new LocalLegacyDeviceCertificates(filePath);
63
+ const legacyCredentialsFileDirPath = join(filePath, DEVICE_TOKEN_FILE_NAME);
64
+ const legacyCertificateDirPath =
65
+ legacyCertificates.getCertificateDirectoryPath();
66
+ const legacyAgentConfigFile = AgentConfigFile(
67
+ join(filePath, AGENT_CONFIG_FILE_NAME)
68
+ );
69
+ const legacyAaiCfgFileDirPath = join(filePath, ALWAYSAI_CONFIG_FILE_NAME);
70
+ const legacyAgentCfgFileDirPath = join(filePath, AGENT_CONFIG_FILE_NAME);
71
+ const legacyDeviceAgentCfgPath = join(filePath, DEVICE_AGENT_CFG_DIR);
72
+
73
+ return {
74
+ getFilePath() {
75
+ return filePath;
76
+ },
77
+ getLegacyAgentConfigFile() {
78
+ return legacyAgentConfigFile;
79
+ },
80
+ getLegacyCertificates() {
81
+ return legacyCertificates;
82
+ },
83
+ getLegacyDeviceAgentConfigDirPath() {
84
+ return legacyDeviceAgentCfgPath;
85
+ },
86
+ getLegacyFileMigrationPaths() {
87
+ return {
88
+ deviceCerts: legacyCertificateDirPath,
89
+ credentialsConfig: legacyCredentialsFileDirPath,
90
+ aaiConfig: legacyAaiCfgFileDirPath,
91
+ agentConfig: legacyAgentCfgFileDirPath
92
+ };
93
+ }
94
+ };
95
+ }
96
+
97
+ // alwaysai.credentials.json
98
+ export const LEGACY_CREDENTIALS_FILE_DIR = join(
99
+ LOCAL_AAI_CFG_DIR,
100
+ DEVICE_TOKEN_FILE_NAME
101
+ );