node-server-engine 1.4.9 → 1.5.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 (277) hide show
  1. package/.commitlintrc.js +27 -0
  2. package/.releaserc.js +56 -0
  3. package/README.md +154 -2
  4. package/dist/const/tokenIssuer.js +1 -0
  5. package/dist/const/tokenIssuer.js.map +1 -1
  6. package/dist/db/models/SequelizeMeta.js +3 -1
  7. package/dist/db/models/SequelizeMeta.js.map +1 -1
  8. package/dist/entities/ElasticSearch/ElasticSearch.js +1 -2
  9. package/dist/entities/ElasticSearch/ElasticSearch.js.map +1 -1
  10. package/dist/entities/Sequelize/Sequelize.js +4 -1
  11. package/dist/entities/Sequelize/Sequelize.js.map +1 -1
  12. package/dist/entities/Server/Server.js +8 -11
  13. package/dist/entities/Server/Server.js.map +1 -1
  14. package/dist/entities/SocketClient/SocketClient.d.ts +4 -1
  15. package/dist/entities/SocketClient/SocketClient.js +5 -1
  16. package/dist/entities/SocketClient/SocketClient.js.map +1 -1
  17. package/dist/index.js +1 -2
  18. package/dist/index.js.map +1 -1
  19. package/dist/middleware/checkPermission/checkPermission.d.ts +1 -1
  20. package/dist/middleware/checkPermission/checkPermission.js +4 -2
  21. package/dist/middleware/checkPermission/checkPermission.js.map +1 -1
  22. package/dist/utils/createSortedObject/createSortedObject.d.ts +5 -1
  23. package/dist/utils/createSortedObject/createSortedObject.js +13 -4
  24. package/dist/utils/createSortedObject/createSortedObject.js.map +1 -1
  25. package/dist/utils/dbMigration/dbMigration.js +34 -15
  26. package/dist/utils/dbMigration/dbMigration.js.map +1 -1
  27. package/dist/utils/geminiFileUpload/geminiFileUpload.js +2 -1
  28. package/dist/utils/geminiFileUpload/geminiFileUpload.js.map +1 -1
  29. package/dist/utils/jwt/jwt.js +1 -1
  30. package/dist/utils/jwt/jwt.js.map +1 -1
  31. package/dist/utils/report/report.d.ts +9 -3
  32. package/dist/utils/report/report.js +29 -12
  33. package/dist/utils/report/report.js.map +1 -1
  34. package/dist/utils/secretManager/secretLoader.js +5 -1
  35. package/dist/utils/secretManager/secretLoader.js.map +1 -1
  36. package/dist/utils/semverCompare/semverCompare.d.ts +4 -4
  37. package/dist/utils/semverCompare/semverCompare.js +16 -18
  38. package/dist/utils/semverCompare/semverCompare.js.map +1 -1
  39. package/package.json +30 -19
  40. package/.env.example +0 -186
  41. package/.github/workflows/publish.yml +0 -41
  42. package/.prettierrc +0 -7
  43. package/Dockerfile +0 -31
  44. package/babel.config.json +0 -34
  45. package/eslint.config.mjs +0 -11
  46. package/src/const/DebeziumEvent.ts +0 -6
  47. package/src/const/LogSeverity.ts +0 -7
  48. package/src/const/index.ts +0 -5
  49. package/src/const/metrics.ts +0 -6
  50. package/src/const/mime.ts +0 -37
  51. package/src/const/tokenIssuer.ts +0 -7
  52. package/src/db/migrations/20241030121500-create-sequelize-meta-table.ts +0 -29
  53. package/src/db/models/SequelizeMeta.ts +0 -16
  54. package/src/db/models/index.ts +0 -2
  55. package/src/entities/ElasticSearch/ElasticSearch.ts +0 -103
  56. package/src/entities/ElasticSearch/ElasticSearch.types.ts +0 -7
  57. package/src/entities/ElasticSearch/index.ts +0 -2
  58. package/src/entities/Endpoint/Endpoint.test.ts +0 -248
  59. package/src/entities/Endpoint/Endpoint.ts +0 -221
  60. package/src/entities/Endpoint/Endpoint.types.ts +0 -181
  61. package/src/entities/Endpoint/index.ts +0 -2
  62. package/src/entities/EngineError/EngineError.ts +0 -28
  63. package/src/entities/EngineError/EngineError.types.ts +0 -15
  64. package/src/entities/EngineError/index.ts +0 -2
  65. package/src/entities/KeySet/KeySet.test.ts +0 -126
  66. package/src/entities/KeySet/KeySet.ts +0 -172
  67. package/src/entities/KeySet/KeySet.types.ts +0 -28
  68. package/src/entities/KeySet/index.ts +0 -2
  69. package/src/entities/LifecycleController/LifecycleController.test.ts +0 -48
  70. package/src/entities/LifecycleController/LifecycleController.ts +0 -24
  71. package/src/entities/LifecycleController/LifecycleController.types.ts +0 -5
  72. package/src/entities/LifecycleController/index.ts +0 -2
  73. package/src/entities/Localizator/Localizator.ts +0 -139
  74. package/src/entities/Localizator/Localizator.types.ts +0 -52
  75. package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.test.ts +0 -165
  76. package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.ts +0 -58
  77. package/src/entities/Localizator/guessNamingConvention/index.ts +0 -1
  78. package/src/entities/Localizator/index.ts +0 -2
  79. package/src/entities/MessageHandler/MessageHandler.test.ts +0 -130
  80. package/src/entities/MessageHandler/MessageHandler.ts +0 -72
  81. package/src/entities/MessageHandler/MessageHandler.types.ts +0 -15
  82. package/src/entities/MessageHandler/index.ts +0 -2
  83. package/src/entities/PubSub/PubSub.test.ts +0 -297
  84. package/src/entities/PubSub/PubSub.ts +0 -202
  85. package/src/entities/PubSub/PubSub.types.ts +0 -76
  86. package/src/entities/PubSub/handleMessage/handleMessage.test.ts +0 -102
  87. package/src/entities/PubSub/handleMessage/handleMessage.ts +0 -65
  88. package/src/entities/PubSub/handleMessage/index.ts +0 -1
  89. package/src/entities/PubSub/index.ts +0 -2
  90. package/src/entities/PushNotification/PushNotification.test.ts +0 -35
  91. package/src/entities/PushNotification/PushNotification.ts +0 -44
  92. package/src/entities/PushNotification/PushNotification.types.ts +0 -25
  93. package/src/entities/PushNotification/index.ts +0 -2
  94. package/src/entities/Redis/Redis.ts +0 -71
  95. package/src/entities/Redis/Redis.types.ts +0 -19
  96. package/src/entities/Redis/Redis.validate.ts +0 -17
  97. package/src/entities/Redis/index.ts +0 -2
  98. package/src/entities/Sequelize/Sequelize.config.ts +0 -59
  99. package/src/entities/Sequelize/Sequelize.test.ts +0 -21
  100. package/src/entities/Sequelize/Sequelize.ts +0 -75
  101. package/src/entities/Sequelize/Sequelize.types.ts +0 -10
  102. package/src/entities/Sequelize/Sequelize.validate.ts +0 -15
  103. package/src/entities/Sequelize/index.ts +0 -2
  104. package/src/entities/Server/Server.const.ts +0 -56
  105. package/src/entities/Server/Server.test.ts +0 -272
  106. package/src/entities/Server/Server.ts +0 -471
  107. package/src/entities/Server/Server.types.ts +0 -88
  108. package/src/entities/Server/index.ts +0 -2
  109. package/src/entities/SocketClient/SocketClient.test.ts +0 -392
  110. package/src/entities/SocketClient/SocketClient.ts +0 -401
  111. package/src/entities/SocketClient/SocketClient.types.ts +0 -62
  112. package/src/entities/SocketClient/index.ts +0 -2
  113. package/src/entities/SocketClient/parseMessage/index.ts +0 -1
  114. package/src/entities/SocketClient/parseMessage/parseMessage.test.ts +0 -20
  115. package/src/entities/SocketClient/parseMessage/parseMessage.ts +0 -26
  116. package/src/entities/Storage/Storage.test.ts +0 -58
  117. package/src/entities/Storage/Storage.ts +0 -219
  118. package/src/entities/Storage/Storage.types.ts +0 -57
  119. package/src/entities/Storage/index.ts +0 -2
  120. package/src/entities/ValidationError/ValidationError.ts +0 -34
  121. package/src/entities/ValidationError/index.ts +0 -1
  122. package/src/entities/WebError/WebError.test.ts +0 -18
  123. package/src/entities/WebError/WebError.ts +0 -23
  124. package/src/entities/WebError/WebError.types.ts +0 -9
  125. package/src/entities/WebError/index.ts +0 -2
  126. package/src/entities/index.ts +0 -16
  127. package/src/index.ts +0 -6
  128. package/src/metrics/debug.ts +0 -10
  129. package/src/metrics/index.ts +0 -2
  130. package/src/metrics/request.ts +0 -17
  131. package/src/middleware/authHmac/authHmac.test.ts +0 -86
  132. package/src/middleware/authHmac/authHmac.ts +0 -56
  133. package/src/middleware/authHmac/authHmac.types.ts +0 -7
  134. package/src/middleware/authHmac/index.ts +0 -2
  135. package/src/middleware/authJwt/authJwt.test.ts +0 -54
  136. package/src/middleware/authJwt/authJwt.ts +0 -55
  137. package/src/middleware/authJwt/authJwt.types.ts +0 -14
  138. package/src/middleware/authJwt/index.ts +0 -2
  139. package/src/middleware/authStatic/authStatic.test.ts +0 -36
  140. package/src/middleware/authStatic/authStatic.ts +0 -45
  141. package/src/middleware/authStatic/index.ts +0 -1
  142. package/src/middleware/authTls/authTls.test.ts +0 -138
  143. package/src/middleware/authTls/authTls.ts +0 -119
  144. package/src/middleware/authTls/authTls.types.ts +0 -13
  145. package/src/middleware/authTls/index.ts +0 -2
  146. package/src/middleware/checkPermission/checkPermission.ts +0 -33
  147. package/src/middleware/checkPermission/index.ts +0 -1
  148. package/src/middleware/error/error.test.ts +0 -60
  149. package/src/middleware/error/error.ts +0 -25
  150. package/src/middleware/error/index.ts +0 -1
  151. package/src/middleware/fileUploader/fileUploader.ts +0 -154
  152. package/src/middleware/fileUploader/fileUploader.types.ts +0 -35
  153. package/src/middleware/fileUploader/index.ts +0 -2
  154. package/src/middleware/fileUploader/isMultiPart/index.ts +0 -1
  155. package/src/middleware/fileUploader/isMultiPart/isMultipart.ts +0 -9
  156. package/src/middleware/fileUploader/validate/index.ts +0 -1
  157. package/src/middleware/fileUploader/validate/validate.ts +0 -27
  158. package/src/middleware/fourOhFour/fourOhFour.test.ts +0 -14
  159. package/src/middleware/fourOhFour/fourOhFour.ts +0 -13
  160. package/src/middleware/fourOhFour/index.ts +0 -1
  161. package/src/middleware/geminiFileUploader/geminiFileUploader.ts +0 -68
  162. package/src/middleware/geminiFileUploader/index.ts +0 -1
  163. package/src/middleware/healthCheck/healthCheck.test.ts +0 -12
  164. package/src/middleware/healthCheck/healthCheck.ts +0 -14
  165. package/src/middleware/healthCheck/index.ts +0 -1
  166. package/src/middleware/index.ts +0 -17
  167. package/src/middleware/metrics/index.ts +0 -1
  168. package/src/middleware/metrics/metrics.test.ts +0 -46
  169. package/src/middleware/metrics/metrics.ts +0 -24
  170. package/src/middleware/multiPartFileUploader/index.ts +0 -2
  171. package/src/middleware/multiPartFileUploader/multiPartFileUploader.ts +0 -249
  172. package/src/middleware/multiPartFileUploader/multiPartFileUploader.types.ts +0 -23
  173. package/src/middleware/multiPartFileUploader/validate/index.ts +0 -1
  174. package/src/middleware/multiPartFileUploader/validate/validate.ts +0 -27
  175. package/src/middleware/requestMetrics/index.ts +0 -1
  176. package/src/middleware/requestMetrics/requestMetrics.test.ts +0 -77
  177. package/src/middleware/requestMetrics/requestMetrics.ts +0 -20
  178. package/src/middleware/swaggerDocs/index.ts +0 -2
  179. package/src/middleware/swaggerDocs/swaggerDocs.ts +0 -114
  180. package/src/middleware/swaggerDocs/swaggerDocs.types.ts +0 -41
  181. package/src/middleware/userResolver/index.ts +0 -1
  182. package/src/middleware/userResolver/userResolver.ts +0 -53
  183. package/src/middleware/validate/index.ts +0 -1
  184. package/src/middleware/validate/validate.test.ts +0 -43
  185. package/src/middleware/validate/validate.ts +0 -25
  186. package/src/middleware/version/index.ts +0 -1
  187. package/src/middleware/version/version.test.ts +0 -23
  188. package/src/middleware/version/version.ts +0 -12
  189. package/src/utils/checkEnvironment/index.ts +0 -49
  190. package/src/utils/createHttpServer/createHttpServer.test.ts +0 -24
  191. package/src/utils/createHttpServer/createHttpServer.ts +0 -34
  192. package/src/utils/createHttpServer/createHttpServer.validate.ts +0 -17
  193. package/src/utils/createHttpServer/index.ts +0 -1
  194. package/src/utils/createSortedObject/createSortedObject.ts +0 -20
  195. package/src/utils/createSortedObject/createSortedObjet.test.ts +0 -47
  196. package/src/utils/createSortedObject/index.ts +0 -1
  197. package/src/utils/dbMigration/dbMigration.test.ts +0 -209
  198. package/src/utils/dbMigration/dbMigration.ts +0 -199
  199. package/src/utils/dbMigration/dbMigration.types.ts +0 -11
  200. package/src/utils/dbMigration/index.ts +0 -2
  201. package/src/utils/dbMigration/migrateMetadataTable/index.ts +0 -1
  202. package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.test.ts +0 -59
  203. package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.ts +0 -102
  204. package/src/utils/envAssert/envAssert.ts +0 -31
  205. package/src/utils/envAssert/index.ts +0 -1
  206. package/src/utils/envAssert/validators/hostList.ts +0 -17
  207. package/src/utils/envAssert/validators/index.ts +0 -5
  208. package/src/utils/envAssert/validators/ipList.ts +0 -13
  209. package/src/utils/envAssert/validators/path.ts +0 -13
  210. package/src/utils/envAssert/validators/string.ts +0 -9
  211. package/src/utils/envAssert/validators/stringList.ts +0 -13
  212. package/src/utils/filter/filter.ts +0 -17
  213. package/src/utils/filter/index.ts +0 -1
  214. package/src/utils/geminiFileUpload/geminiFileUpload.ts +0 -93
  215. package/src/utils/geminiFileUpload/index.ts +0 -1
  216. package/src/utils/hmac/checkEnv/checkEnv.test.ts +0 -18
  217. package/src/utils/hmac/checkEnv/checkEnv.ts +0 -9
  218. package/src/utils/hmac/checkEnv/index.ts +0 -1
  219. package/src/utils/hmac/createHmac/createHmac.ts +0 -33
  220. package/src/utils/hmac/createHmac/index.ts +0 -1
  221. package/src/utils/hmac/index.ts +0 -4
  222. package/src/utils/hmac/index.types.ts +0 -13
  223. package/src/utils/hmac/signPayload/index.ts +0 -1
  224. package/src/utils/hmac/signPayload/signPayload.ts +0 -16
  225. package/src/utils/hmac/verifySignature/index.ts +0 -1
  226. package/src/utils/hmac/verifySignature/verifySignature.ts +0 -24
  227. package/src/utils/index.ts +0 -29
  228. package/src/utils/jwt/index.ts +0 -2
  229. package/src/utils/jwt/jwt.test.ts +0 -28
  230. package/src/utils/jwt/jwt.ts +0 -182
  231. package/src/utils/jwt/jwt.types.ts +0 -21
  232. package/src/utils/report/index.ts +0 -3
  233. package/src/utils/report/output.ts +0 -45
  234. package/src/utils/report/output.types.ts +0 -70
  235. package/src/utils/report/report.test.ts +0 -133
  236. package/src/utils/report/report.ts +0 -133
  237. package/src/utils/report/report.types.ts +0 -13
  238. package/src/utils/request/index.ts +0 -1
  239. package/src/utils/request/request.test.ts +0 -26
  240. package/src/utils/request/request.ts +0 -48
  241. package/src/utils/secretManager/index.ts +0 -2
  242. package/src/utils/secretManager/secretLoader.ts +0 -62
  243. package/src/utils/secretManager/secretResolver.ts +0 -35
  244. package/src/utils/semverCompare/index.ts +0 -1
  245. package/src/utils/semverCompare/semverCompare.test.ts +0 -49
  246. package/src/utils/semverCompare/semverCompare.ts +0 -60
  247. package/src/utils/sendEmail/index.ts +0 -2
  248. package/src/utils/sendEmail/sendEmail.ts +0 -61
  249. package/src/utils/sendEmail/sendEmail.types.ts +0 -61
  250. package/src/utils/sendPush/index.ts +0 -2
  251. package/src/utils/sendPush/sendPush.ts +0 -20
  252. package/src/utils/sendPush/sendPush.types.ts +0 -25
  253. package/src/utils/tlsConfig/index.ts +0 -2
  254. package/src/utils/tlsConfig/tlsConfig.test.ts +0 -32
  255. package/src/utils/tlsConfig/tlsConfig.ts +0 -47
  256. package/src/utils/tlsConfig/tlsConfig.types.ts +0 -11
  257. package/src/utils/tlsConfig/tlsConfig.validate.ts +0 -25
  258. package/src/utils/tlsRequest/index.ts +0 -1
  259. package/src/utils/tlsRequest/tlsRequest.test.ts +0 -63
  260. package/src/utils/tlsRequest/tlsRequest.ts +0 -12
  261. package/src/utils/trimPathSlash/index.ts +0 -1
  262. package/src/utils/trimPathSlash/trimPathSlash.test.ts +0 -26
  263. package/src/utils/trimPathSlash/trimPathSlash.ts +0 -8
  264. package/test/env.ts +0 -53
  265. package/test/factory/index.ts +0 -8
  266. package/test/factory/sequelizeMeta.ts +0 -12
  267. package/test/hooks.ts +0 -35
  268. package/test/index.ts +0 -3
  269. package/test/stub/index.ts +0 -3
  270. package/test/stub/stubLocales.ts +0 -68
  271. package/test/stub/stubPubSub.ts +0 -7
  272. package/test/stub/stubStorage.ts +0 -77
  273. package/test/stub/stubStorage.types.ts +0 -11
  274. package/test/utils/app.ts +0 -31
  275. package/test/utils/index.ts +0 -1
  276. package/tsconfig.build.json +0 -5
  277. package/tsconfig.json +0 -32
@@ -1,219 +0,0 @@
1
- import { randomUUID } from 'crypto';
2
- import { Readable } from 'stream';
3
- import {
4
- Storage as CloudStorage,
5
- CreateWriteStreamOptions,
6
- File
7
- } from '@google-cloud/storage';
8
- import fileSizeParser from 'filesize-parser';
9
- import mimeTypes from 'mime-types';
10
- import {
11
- UploadDestinationOptions,
12
- StorageUploadedFile,
13
- UploaderOptions,
14
- StorageGetResponse,
15
- StorageDownloadResponse
16
- } from './Storage.types';
17
- import { WebError } from 'entities/WebError';
18
- import { reportDebug } from 'utils/report';
19
- import { trimPathSlash } from 'utils/trimPathSlash';
20
-
21
- const namespace = 'engine:storage';
22
-
23
- export const Storage = {
24
- cloudStorage: new CloudStorage({
25
- projectId: process.env.GC_PROJECT,
26
- keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS
27
- }),
28
-
29
- /**
30
- * Upload a file to the cloud storage
31
- * @param readStream - Stream of the file content
32
- * @param bucket - Bucket in which the file should be stored
33
- * @param destinationOptions - Options for the destination generator [see: generateFileDestination(options)]
34
- * @param storageOptions - Storage library options
35
- * @param uploaderOptions - Options for this service's specific behavior
36
- * @return {Promise<Object>} - Details regarding the uploaded file's metadata
37
- */
38
- async upload(
39
- readStream: Readable,
40
- bucket: string,
41
- destinationOptions: UploadDestinationOptions = {},
42
- storageOptions: CreateWriteStreamOptions = {},
43
- uploaderOptions: UploaderOptions = {}
44
- ): Promise<StorageUploadedFile> {
45
- const { maxSize } = uploaderOptions;
46
-
47
- let file: File;
48
- reportDebug({
49
- namespace,
50
- message: 'Uploading file to storage',
51
- data: { bucket, destinationOptions, storageOptions, uploaderOptions }
52
- });
53
-
54
- // Generate the file path
55
- // We either use a given file name, or we generate a random file name
56
- const { fileName, directory } = destinationOptions;
57
-
58
- // Upload file with given file name
59
- if (fileName) {
60
- // Only keep required slashes in full path
61
- const trimmedDirectory = trimPathSlash(directory ?? '/');
62
- const path = `${trimmedDirectory}/${fileName}`;
63
- file = this.cloudStorage.bucket(bucket).file(path);
64
- }
65
- // Generate random destination for file and check that it is not already occupied
66
- else {
67
- do {
68
- const path = this.generateFileDestination(destinationOptions);
69
- file = this.cloudStorage.bucket(bucket).file(path);
70
- } while ((await file.exists())[0]);
71
- }
72
-
73
- // Pipe user's file stream to the storage
74
- return new Promise((resolve, reject) => {
75
- let receivedSize = 0;
76
- const writeStream = file.createWriteStream(storageOptions);
77
- const intMaxSize = maxSize && fileSizeParser(maxSize);
78
- // Calculate transferred size and write to storage stream
79
- readStream.on('data', function (data: Buffer) {
80
- receivedSize += data.length;
81
- // Fail if transferred data over max size
82
- if (intMaxSize && receivedSize > intMaxSize) {
83
- reject(
84
- new WebError({
85
- statusCode: 413,
86
- errorCode: 'file-too-large',
87
- message: 'Request contains a file that is over the maximum size',
88
- hint: { maxSize },
89
- data: {
90
- bucket,
91
- destinationOptions,
92
- storageOptions,
93
- receivedSize,
94
- maxSize
95
- }
96
- })
97
- );
98
- return;
99
- }
100
- writeStream.write(data);
101
- });
102
- // Error handling
103
- readStream.on('error', (err) => {
104
- reject(err);
105
- });
106
- writeStream.on('error', (err) => {
107
- reject(err);
108
- });
109
- // Graceful termination of the read
110
- readStream.on('end', () => {
111
- writeStream.end();
112
- });
113
- // Graceful termination of the write
114
- writeStream.on('finish', () => {
115
- (async (): Promise<void> => {
116
- const [metadata] = (await file.getMetadata()) as [
117
- StorageUploadedFile,
118
- unknown
119
- ];
120
- reportDebug({
121
- namespace,
122
- message: 'File uploaded to storage',
123
- data: metadata
124
- });
125
- resolve(metadata);
126
- })().catch((error) => {
127
- reject(error);
128
- });
129
- });
130
- });
131
- },
132
-
133
- /**
134
- * Return the read stream for a given file and bucket
135
- */
136
- async get(bucket: string, path: string): Promise<StorageGetResponse> {
137
- const file = this.cloudStorage.bucket(bucket).file(path);
138
- const [[metadata], [data]] = (await Promise.all([
139
- file.getMetadata(),
140
- file.download()
141
- ])) as [[StorageUploadedFile, unknown], [Buffer]];
142
- reportDebug({
143
- namespace,
144
- message: 'Downloaded file from storage',
145
- data: { bucket, path, metadata }
146
- });
147
- return {
148
- data,
149
- metadata
150
- };
151
- },
152
-
153
- /**
154
- * Return the read stream for a given file and bucket
155
- */
156
- async download(
157
- bucket: string,
158
- path: string
159
- ): Promise<StorageDownloadResponse> {
160
- const file = this.cloudStorage.bucket(bucket).file(path);
161
- const [metadata] = (await file.getMetadata()) as [
162
- StorageUploadedFile,
163
- unknown
164
- ];
165
- reportDebug({
166
- namespace,
167
- message: 'Fetched file stream from storage',
168
- data: { bucket, path, metadata }
169
- });
170
- return {
171
- stream: file.createReadStream(),
172
- metadata
173
- };
174
- },
175
-
176
- /**
177
- * Return the read stream for a given file path and bucket
178
- * @param {String} bucket
179
- * @param {String} path
180
- */
181
- getFileStream(bucket: string, path: string): Readable {
182
- const file = this.cloudStorage.bucket(bucket).file(path);
183
- reportDebug({
184
- namespace,
185
- message: "Fetched file stream from storage's bucket",
186
- data: { bucket, path }
187
- });
188
- return file.createReadStream();
189
- },
190
-
191
- /**
192
- * Delete a file from the cloud storage
193
- */
194
- async delete(bucket: string, path: string): Promise<void> {
195
- reportDebug({
196
- namespace,
197
- message: 'Deleting file from storage',
198
- data: { bucket, path }
199
- });
200
- await this.cloudStorage.bucket(bucket).file(path).delete();
201
- },
202
-
203
- /**
204
- * Builds the full file path on the cloud and generates it a random name
205
- */
206
- generateFileDestination(options: UploadDestinationOptions = {}): string {
207
- const { directory = '/', mime, noExtension = false } = options;
208
-
209
- // use provided mime type default otherwise
210
- const extension =
211
- mime && mimeTypes.extension(mime) ? mimeTypes.extension(mime) : undefined;
212
- // Build the full name
213
- const fullName =
214
- extension && !noExtension ? `${randomUUID()}.${extension}` : randomUUID();
215
- // Only keep required slashes in full path
216
- const trimmedDirectory = trimPathSlash(directory);
217
- return `${trimmedDirectory ? `${trimmedDirectory}/` : ''}${fullName}`;
218
- }
219
- };
@@ -1,57 +0,0 @@
1
- import { Readable } from 'stream';
2
-
3
- /** Options to set where an uploaded file is stored in the bucket */
4
- export interface UploadDestinationOptions {
5
- /** Directory of the bucket in which the file is stored. Defaults to the root directory */
6
- directory?: string;
7
- /** Name under which the file is stored. If specified, the file is stored with that name. Otherwise random name generation is done */
8
- fileName?: string;
9
- /** When using random file name generation (ie: fileName is undefined). We use the MIME type to determine which is the best extension to apply to the file */
10
- mime?: string;
11
- /** When using random file name generation (ie: fileName is undefined), use this parameter to skip adding an extension to the file */
12
- noExtension?: boolean;
13
- }
14
-
15
- /** Options of the file uploader */
16
- export interface UploaderOptions {
17
- /** Maximum size of the file (ex: 2MB) */
18
- maxSize?: string;
19
- }
20
-
21
- /** Object representing a file that has been uploaded */
22
- export interface StorageUploadedFile {
23
- /** Bucket in which the file has been uploaded */
24
- bucket: string;
25
- /** Name of the stored object with path */
26
- name: string;
27
- /** Content-type of the file */
28
- contentType: string;
29
- /** Byte size of the file */
30
- size: string;
31
- /** ISO string of the creation date */
32
- timeCreated: string;
33
- /** ISO string of the update date */
34
- updated: string;
35
- /** MD5 hash of the content */
36
- md5Hash: string;
37
- /** CRC32C hash of the content */
38
- crc32c: string;
39
- /** Storage class applied */
40
- storageClass: string;
41
- }
42
-
43
- /** Return type for a file download */
44
- export interface StorageGetResponse {
45
- /** The file raw binary content */
46
- data: Buffer;
47
- /** The file's metadata */
48
- metadata: StorageUploadedFile;
49
- }
50
-
51
- /** Return time for a file streaming fetching */
52
- export interface StorageDownloadResponse {
53
- /** A readable stream with the file's content */
54
- stream: Readable;
55
- /** The file's metadata */
56
- metadata: StorageUploadedFile;
57
- }
@@ -1,2 +0,0 @@
1
- export * from './Storage';
2
- export * from './Storage.types';
@@ -1,34 +0,0 @@
1
- import {
2
- ValidationError as ExpressValidationError,
3
- Result
4
- } from 'express-validator';
5
- import { LogSeverity } from 'const';
6
- import { EngineError } from 'entities/EngineError';
7
- import { WebError } from 'entities/WebError';
8
-
9
- /** Error class for request/message validation errors */
10
- export class ValidationError extends WebError {
11
- /** Create an ValidationError this represents errors in parsing incoming messages/requests */
12
- public constructor(validationResult: Result<ExpressValidationError>) {
13
- if (validationResult.isEmpty())
14
- throw new EngineError({
15
- message:
16
- 'Attempted to create a validation error while validation was successful'
17
- });
18
-
19
- const errors = validationResult.array();
20
- // Hint that is sent to the client as logged as data
21
- const hint = errors.reduce(
22
- (hint, error) => ({ ...hint, [error.type]: error.msg as string }),
23
- {}
24
- );
25
- super({
26
- message: 'Request did not pass validation',
27
- errorCode: 'invalid-request',
28
- statusCode: 400,
29
- severity: LogSeverity.WARNING,
30
- data: hint,
31
- hint
32
- });
33
- }
34
- }
@@ -1 +0,0 @@
1
- export * from './ValidationError';
@@ -1,18 +0,0 @@
1
- import { expect } from 'chai';
2
- import { WebError } from './WebError';
3
-
4
- describe('Entity - WebError', () => {
5
- it('should set the error code and message', () => {
6
- const statusCode = 401;
7
- const errorCode = 'example-errorCode';
8
- const message = 'this is an example message';
9
- const error = new WebError({
10
- message,
11
- errorCode,
12
- statusCode
13
- });
14
- expect(error.message).to.equal(message);
15
- expect(error.errorCode).to.equal(errorCode);
16
- expect(error.statusCode).to.equal(statusCode);
17
- });
18
- });
@@ -1,23 +0,0 @@
1
- import { WebErrorOptions } from './WebError.types';
2
- import { LogSeverity } from 'const';
3
- import { EngineError } from 'entities/EngineError';
4
-
5
- /**
6
- * Error class used when errors should be reported to the client
7
- */
8
- export class WebError extends EngineError {
9
- /** Machine readable error code that will be sent to the client */
10
- public errorCode: string;
11
- /** HTTP status code associated with this error */
12
- public statusCode: number;
13
-
14
- /**
15
- * Create a WebError, these errors are best suited for runtime errors
16
- */
17
- public constructor(config: WebErrorOptions) {
18
- super({ ...config, severity: config.severity ?? LogSeverity.WARNING });
19
-
20
- this.statusCode = config.statusCode ?? 400;
21
- this.errorCode = config.errorCode;
22
- }
23
- }
@@ -1,9 +0,0 @@
1
- import { EngineErrorOptions } from 'entities/EngineError';
2
-
3
- /** Options to create a Web Error */
4
- export interface WebErrorOptions extends EngineErrorOptions {
5
- /** Machine readable error code that will be sent to the client */
6
- errorCode: string;
7
- /** HTTP status code associated with this error (default: 400) */
8
- statusCode?: number;
9
- }
@@ -1,2 +0,0 @@
1
- export * from './WebError';
2
- export * from './WebError.types';
@@ -1,16 +0,0 @@
1
- export * from './EngineError';
2
- export * from './WebError';
3
- export * from './ValidationError';
4
- export * from './KeySet';
5
- export * from './Endpoint';
6
- export * from './MessageHandler';
7
- export * from './SocketClient';
8
- export * from './Server';
9
- export * from './Redis';
10
- export * from './Localizator';
11
- export * from './Storage';
12
- export * from './Sequelize';
13
- export * from './ElasticSearch';
14
- export * from './LifecycleController';
15
- export * from './PubSub';
16
- export * from './PushNotification';
package/src/index.ts DELETED
@@ -1,6 +0,0 @@
1
- // src/index.ts
2
- export * from './const';
3
- export * from './entities';
4
- export * from './utils';
5
- export * from './utils/tlsRequest';
6
- export * as middleware from './middleware';
@@ -1,10 +0,0 @@
1
- import { Gauge } from 'prom-client';
2
- import { instanceRegistry } from 'const';
3
-
4
- export const debugActivated = new Gauge({
5
- name: 'debug_activated',
6
- help: 'Debug is activated',
7
- registers: [instanceRegistry]
8
- });
9
-
10
- debugActivated.set(process.env.DEBUG?.length ? 1 : 0);
@@ -1,2 +0,0 @@
1
- export * from './request';
2
- export * from './debug';
@@ -1,17 +0,0 @@
1
- import { Counter, Histogram } from 'prom-client';
2
- import { instanceRegistry } from 'const';
3
-
4
- export const httpRequestCount = new Counter({
5
- name: 'http_requests_total',
6
- help: 'Total count of request received',
7
- registers: [instanceRegistry],
8
- labelNames: ['service', 'path', 'method', 'status']
9
- });
10
-
11
- export const httpRequestDuration = new Histogram({
12
- name: 'http_requests_duration',
13
- help: 'Duration of the request received',
14
- registers: [instanceRegistry],
15
- labelNames: ['service', 'path', 'method', 'status'],
16
- buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 0.5, 1, 2.5, 5, 10]
17
- });
@@ -1,86 +0,0 @@
1
- import crypto from 'crypto';
2
- import express, { json, Request, Response, Application } from 'express';
3
- import { faker } from '@faker-js/faker';
4
- import request from 'supertest';
5
- import {
6
- Endpoint,
7
- EndpointAuthType,
8
- EndpointMethod,
9
- EndpointOptions
10
- } from 'entities/Endpoint';
11
- import { signPayload } from 'utils/hmac';
12
-
13
- describe('Middleware - authHmac', () => {
14
- let app: Application;
15
-
16
- const PATH = '/test';
17
- const config: EndpointOptions<EndpointAuthType.HMAC> = {
18
- path: PATH,
19
- method: EndpointMethod.POST,
20
- handler: (req: Request, res: Response) => {
21
- res.sendStatus(200);
22
- },
23
- authType: EndpointAuthType.HMAC,
24
- validator: {}
25
- };
26
-
27
- beforeEach(() => {
28
- app = express();
29
- app.use(json());
30
- process.env.PAYLOAD_SIGNATURE_SECRET = faker.lorem.slug();
31
- });
32
-
33
- it('should allow properly signed requests', async () => {
34
- const payload = signPayload({ test: 'test' });
35
- const endpoint = new Endpoint({
36
- ...config,
37
- authType: EndpointAuthType.HMAC
38
- });
39
- endpoint.register(app);
40
- await request(app).post(PATH).send(payload).expect(200);
41
- });
42
-
43
- it('should allow properly signed requests with a custom secret', async () => {
44
- const secret = faker.lorem.word();
45
- const payload = signPayload({ test: 'test' }, { secret });
46
- const endpoint = new Endpoint({
47
- ...config,
48
- authType: EndpointAuthType.HMAC,
49
- authParams: { secret }
50
- });
51
- endpoint.register(app);
52
- await request(app).post(PATH).send(payload);
53
- });
54
-
55
- it('should not allow wrongly signed requests', async () => {
56
- const payload = signPayload({ test: 'test' }, { secret: 'hacker' });
57
- const endpoint = new Endpoint({
58
- ...config,
59
- authType: EndpointAuthType.HMAC
60
- });
61
- endpoint.register(app);
62
- await request(app).post(PATH).send(payload).expect(401);
63
- });
64
-
65
- it('should allow signed requests from Github', async () => {
66
- const payload = {
67
- z: faker.lorem.word(),
68
- a: { z: faker.lorem.word(), a: faker.lorem.word() }
69
- };
70
- const signature = crypto
71
- .createHmac('sha1', process.env.PAYLOAD_SIGNATURE_SECRET as string)
72
- .update(JSON.stringify(payload))
73
- .digest('hex');
74
- const endpoint = new Endpoint({
75
- ...config,
76
- authType: EndpointAuthType.HMAC,
77
- authParams: { isGithub: true }
78
- });
79
- endpoint.register(app);
80
- await request(app)
81
- .post(PATH)
82
- .send(payload)
83
- .set({ 'X-Hub-Signature': `sha1=${signature}` })
84
- .expect(200);
85
- });
86
- });
@@ -1,56 +0,0 @@
1
- import { BinaryToTextEncoding } from 'crypto';
2
- import { Request, Response, NextFunction } from 'express';
3
- import { HmacPayload } from './authHmac.types';
4
- import { EndpointAuthParams, EndpointAuthType } from 'entities/Endpoint';
5
- import { WebError } from 'entities/WebError';
6
- import { verifySignature } from 'utils/hmac';
7
- import { reportDebug } from 'utils/report';
8
-
9
- const namespace = 'engine:middleware:authHmac';
10
-
11
- /** Generate an HMAC authentication middleware */
12
- export function authHmac(
13
- options: EndpointAuthParams<EndpointAuthType.HMAC> = {}
14
- ): (req: Request, res: Response, next: NextFunction) => void {
15
- return (req: Request, res: Response, next: NextFunction): void => {
16
- const payload = (
17
- req.method === 'GET' ? req.query : req.body
18
- ) as HmacPayload;
19
- let signature: string | undefined;
20
- let signatureSettings;
21
- if (options.isGithub) {
22
- // For GitHub, the signature is in the header and is has specific settings
23
- signature =
24
- req.headers['x-hub-signature'] &&
25
- (req.headers['x-hub-signature'] as string).substr(5);
26
- signatureSettings = {
27
- algorithm: 'sha1',
28
- sort: false,
29
- encode: 'hex' as BinaryToTextEncoding
30
- };
31
- } else {
32
- // In our standard authentication, the signature is included in the payload
33
- signature = payload.signature;
34
- delete payload.signature;
35
- }
36
- const settings = { secret: options.secret, ...signatureSettings };
37
- if (!signature)
38
- throw new WebError({
39
- message: 'No signature was provided',
40
- errorCode: 'unauthorized',
41
- statusCode: 401
42
- });
43
- reportDebug({
44
- namespace,
45
- message: 'Performing HMAC authentication',
46
- data: { payload, signature, settings }
47
- });
48
- if (!verifySignature(payload, signature, settings))
49
- throw new WebError({
50
- message: 'Signature does not match hmac of payload',
51
- errorCode: 'unauthorized',
52
- statusCode: 401
53
- });
54
- next();
55
- };
56
- }
@@ -1,7 +0,0 @@
1
- /** Options for HMAC auth */
2
- export interface HmacPayload {
3
- /** Generic object payload */
4
- [key: string]: unknown;
5
- /** HMAC signature of the whole payload */
6
- signature?: string;
7
- }
@@ -1,2 +0,0 @@
1
- export * from './authHmac';
2
- export * from './authHmac.types';
@@ -1,54 +0,0 @@
1
- import { factory, getBearer } from 'backend-test-tools';
2
- import { expect } from 'chai';
3
- import { Request, Response } from 'express';
4
- import { faker } from '@faker-js/faker';
5
- import { fake } from 'sinon';
6
- import { authJwt } from './authJwt';
7
-
8
- describe('Middleware - Auth JWT', () => {
9
- it('should authenticate with a JWT (auth-service)', async () => {
10
- const user = factory.build('user');
11
- const request = { headers: { authorization: getBearer(user.id) } };
12
- const next = fake();
13
-
14
- await authJwt()(request as Request, undefined as unknown as Response, next);
15
-
16
- expect(next).to.have.been.calledOnceWithExactly();
17
- });
18
-
19
- it('should populate the user object in the request (auth-service)', async () => {
20
- const user = factory.build('user');
21
- const request = {
22
- headers: { authorization: getBearer(user.id) }
23
- } as Request;
24
- const next = fake();
25
-
26
- await authJwt()(request, undefined as unknown as Response, next);
27
-
28
- expect(request.user).to.not.be.undefined;
29
- expect(request.user?.id).to.equal(user.id);
30
- });
31
-
32
- it('should throw an error if there is no token', async () => {
33
- const request = { headers: {} };
34
- const next = fake();
35
-
36
- await expect(
37
- authJwt()(request as Request, undefined as unknown as Response, next)
38
- ).to.eventually.rejected;
39
- });
40
-
41
- it('should throw an error if the audience is not valid', async () => {
42
- const user = factory.build('user');
43
- const request = {
44
- headers: {
45
- authorization: getBearer(user.id, { audience: faker.internet.url() })
46
- }
47
- };
48
- const next = fake();
49
-
50
- await expect(
51
- authJwt()(request as Request, undefined as unknown as Response, next)
52
- ).to.eventually.rejected;
53
- });
54
- });