@creator.co/wapi 1.2.1-beta6 → 1.2.2

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 (127) hide show
  1. package/.github/workflows/npmpublish.yml +11 -19
  2. package/.github/workflows/prs.yml +13 -0
  3. package/jest.config.ts +39 -0
  4. package/package.json +15 -4
  5. package/src/API/Request.ts +120 -10
  6. package/src/API/Response.ts +236 -8
  7. package/src/API/Utils.ts +56 -1
  8. package/src/BaseEvent/EventProcessor.ts +84 -11
  9. package/src/BaseEvent/Process.ts +62 -1
  10. package/src/BaseEvent/Transaction.ts +5 -8
  11. package/src/Config/Configuration.ts +111 -5
  12. package/src/Config/EnvironmentVar.ts +90 -1
  13. package/src/Crypto/Crypto.ts +77 -18
  14. package/src/Crypto/JWT.ts +49 -3
  15. package/src/Globals.ts +141 -3
  16. package/src/Logger/Logger.ts +173 -19
  17. package/src/Mailer/Mailer.ts +95 -0
  18. package/src/Publisher/Publisher.ts +50 -4
  19. package/src/Server/RouteResolver.ts +142 -0
  20. package/src/Server/Router.ts +77 -0
  21. package/src/Server/lib/ContainerServer.ts +48 -1
  22. package/src/Server/lib/Server.ts +78 -38
  23. package/src/Server/lib/container/GenericHandler.ts +7 -5
  24. package/src/Server/lib/container/GenericHandlerEvent.ts +59 -17
  25. package/src/Server/lib/container/HealthHandler.ts +1 -1
  26. package/src/Server/lib/container/Proxy.ts +92 -11
  27. package/src/Server/lib/container/Utils.ts +16 -25
  28. package/src/Validation/Validator.ts +18 -2
  29. package/tests/API/Request.test.ts +263 -0
  30. package/tests/API/Response.test.ts +372 -0
  31. package/tests/API/Utils.test.ts +157 -0
  32. package/tests/BaseEvent/EventProcessor.test.ts +278 -0
  33. package/tests/BaseEvent/Process.test.ts +49 -0
  34. package/tests/BaseEvent/Transaction.test.ts +231 -0
  35. package/tests/Config/Config.test.ts +193 -0
  36. package/tests/Config/EnvironmentVar.test.ts +223 -0
  37. package/tests/Crypto/Crypto.test.ts +90 -0
  38. package/tests/Crypto/JWT.test.ts +92 -0
  39. package/tests/Logger/Logger.test.ts +108 -0
  40. package/tests/Mailer/Mailer.test.ts +67 -0
  41. package/tests/Publisher/Publisher.test.ts +60 -0
  42. package/tests/Server/RouteResolver.test.ts +106 -0
  43. package/tests/Server/Router.test.ts +38 -0
  44. package/tests/Server/lib/ContainerServer.test.ts +329 -0
  45. package/tests/Server/lib/Server.test.ts +12 -0
  46. package/tests/Server/lib/container/GenericHandler.test.ts +141 -0
  47. package/tests/Server/lib/container/GenericHandlerEvent.test.ts +103 -0
  48. package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
  49. package/tests/Server/lib/container/Proxy.test.ts +278 -0
  50. package/tests/Server/lib/container/Utils.test.ts +48 -0
  51. package/tests/Test.utils.ts +95 -0
  52. package/tests/Validation/Validator.test.ts +88 -0
  53. package/tests/main.test.ts +15 -0
  54. package/tsconfig.json +1 -0
  55. package/dist/index.d.ts +0 -11
  56. package/dist/index.js +0 -24
  57. package/dist/index.js.map +0 -1
  58. package/dist/package.json +0 -53
  59. package/dist/src/API/Request.d.ts +0 -21
  60. package/dist/src/API/Request.js +0 -86
  61. package/dist/src/API/Request.js.map +0 -1
  62. package/dist/src/API/Response.d.ts +0 -39
  63. package/dist/src/API/Response.js +0 -232
  64. package/dist/src/API/Response.js.map +0 -1
  65. package/dist/src/API/Utils.d.ts +0 -8
  66. package/dist/src/API/Utils.js +0 -49
  67. package/dist/src/API/Utils.js.map +0 -1
  68. package/dist/src/BaseEvent/EventProcessor.d.ts +0 -13
  69. package/dist/src/BaseEvent/EventProcessor.js +0 -151
  70. package/dist/src/BaseEvent/EventProcessor.js.map +0 -1
  71. package/dist/src/BaseEvent/Process.d.ts +0 -12
  72. package/dist/src/BaseEvent/Process.js +0 -114
  73. package/dist/src/BaseEvent/Process.js.map +0 -1
  74. package/dist/src/BaseEvent/Transaction.d.ts +0 -29
  75. package/dist/src/BaseEvent/Transaction.js +0 -248
  76. package/dist/src/BaseEvent/Transaction.js.map +0 -1
  77. package/dist/src/Config/Configuration.d.ts +0 -34
  78. package/dist/src/Config/Configuration.js +0 -93
  79. package/dist/src/Config/Configuration.js.map +0 -1
  80. package/dist/src/Config/EnvironmentVar.d.ts +0 -17
  81. package/dist/src/Config/EnvironmentVar.js +0 -152
  82. package/dist/src/Config/EnvironmentVar.js.map +0 -1
  83. package/dist/src/Crypto/Crypto.d.ts +0 -8
  84. package/dist/src/Crypto/Crypto.js +0 -84
  85. package/dist/src/Crypto/Crypto.js.map +0 -1
  86. package/dist/src/Crypto/JWT.d.ts +0 -16
  87. package/dist/src/Crypto/JWT.js +0 -49
  88. package/dist/src/Crypto/JWT.js.map +0 -1
  89. package/dist/src/Globals.d.ts +0 -21
  90. package/dist/src/Globals.js +0 -35
  91. package/dist/src/Globals.js.map +0 -1
  92. package/dist/src/Logger/Logger.d.ts +0 -34
  93. package/dist/src/Logger/Logger.js +0 -345
  94. package/dist/src/Logger/Logger.js.map +0 -1
  95. package/dist/src/Mailer/Mailer.d.ts +0 -12
  96. package/dist/src/Mailer/Mailer.js +0 -234
  97. package/dist/src/Mailer/Mailer.js.map +0 -1
  98. package/dist/src/Publisher/Publisher.d.ts +0 -10
  99. package/dist/src/Publisher/Publisher.js +0 -109
  100. package/dist/src/Publisher/Publisher.js.map +0 -1
  101. package/dist/src/Server/Router.d.ts +0 -27
  102. package/dist/src/Server/Router.js +0 -22
  103. package/dist/src/Server/Router.js.map +0 -1
  104. package/dist/src/Server/lib/ContainerServer.d.ts +0 -11
  105. package/dist/src/Server/lib/ContainerServer.js +0 -103
  106. package/dist/src/Server/lib/ContainerServer.js.map +0 -1
  107. package/dist/src/Server/lib/Server.d.ts +0 -9
  108. package/dist/src/Server/lib/Server.js +0 -141
  109. package/dist/src/Server/lib/Server.js.map +0 -1
  110. package/dist/src/Server/lib/container/GenericHandler.d.ts +0 -4
  111. package/dist/src/Server/lib/container/GenericHandler.js +0 -136
  112. package/dist/src/Server/lib/container/GenericHandler.js.map +0 -1
  113. package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +0 -14
  114. package/dist/src/Server/lib/container/GenericHandlerEvent.js +0 -164
  115. package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +0 -1
  116. package/dist/src/Server/lib/container/HealthHandler.d.ts +0 -3
  117. package/dist/src/Server/lib/container/HealthHandler.js +0 -44
  118. package/dist/src/Server/lib/container/HealthHandler.js.map +0 -1
  119. package/dist/src/Server/lib/container/Proxy.d.ts +0 -15
  120. package/dist/src/Server/lib/container/Proxy.js +0 -157
  121. package/dist/src/Server/lib/container/Proxy.js.map +0 -1
  122. package/dist/src/Server/lib/container/Utils.d.ts +0 -6
  123. package/dist/src/Server/lib/container/Utils.js +0 -109
  124. package/dist/src/Server/lib/container/Utils.js.map +0 -1
  125. package/dist/src/Validation/Validator.d.ts +0 -5
  126. package/dist/src/Validation/Validator.js +0 -31
  127. package/dist/src/Validation/Validator.js.map +0 -1
@@ -0,0 +1,193 @@
1
+ import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"
2
+ import { mockClient } from "aws-sdk-client-mock"
3
+ import { expect } from "chai"
4
+
5
+ import Configuration from "../../src/Config/Configuration"
6
+ import { SampleConfig, SampleConfigSchema } from "../Test.utils"
7
+
8
+ const SSMMock = mockClient(SSMClient)
9
+ const config = new Configuration<SampleConfigSchema>(SampleConfig, "my-prefix")
10
+ describe(`Optional remote environment`, () => {
11
+ // reset mock
12
+ beforeEach(() => {
13
+ SSMMock.reset()
14
+ config["resetCache"]()
15
+ })
16
+
17
+ test("Does not accept sync get", async () => {
18
+ let err = null
19
+ try {
20
+ // @ts-ignore
21
+ config.get("TOKEN_SECRET")
22
+ } catch (e) {
23
+ err = e
24
+ }
25
+ expect(err).is.not.null
26
+ expect(err?.["message"]).is.not.null
27
+ })
28
+
29
+ test("Optional value with null value", async () => {
30
+ SSMMock.on(GetParameterCommand).resolves({
31
+ Parameter: {
32
+ Value: undefined,
33
+ },
34
+ })
35
+ const token = await config.asyncGet("TOKEN_SECRET_FALSY")
36
+ expect(token).is.undefined
37
+ })
38
+
39
+ test("Optional value with empty response", async () => {
40
+ SSMMock.on(GetParameterCommand).resolves({})
41
+ const token = await config.asyncGet("TOKEN_SECRET_FALSY")
42
+ expect(token).is.undefined
43
+ })
44
+
45
+ test("Optional value with valid response", async () => {
46
+ const value = "abc"
47
+ SSMMock.on(GetParameterCommand).resolves({
48
+ Parameter: {
49
+ Value: value,
50
+ },
51
+ })
52
+ const token = await config.asyncGet("TOKEN_SECRET_FALSY")
53
+ expect(token).is.not.undefined
54
+ expect(token).to.be.equals(value)
55
+ })
56
+
57
+ test("Optional value rejection", async () => {
58
+ SSMMock.on(GetParameterCommand).rejects(new Error("failed!"))
59
+ const token = await config.asyncGet("TOKEN_SECRET_FALSY")
60
+ expect(token).is.undefined
61
+ })
62
+ })
63
+
64
+ describe(`Required remote environment`, () => {
65
+ // reset mock
66
+ beforeEach(() => {
67
+ SSMMock.reset()
68
+ config["resetCache"]()
69
+ })
70
+
71
+ test("Does not accept sync get", async () => {
72
+ let err = null
73
+ try {
74
+ // @ts-ignore
75
+ config.get("TOKEN_SECRET")
76
+ } catch (e) {
77
+ err = e
78
+ }
79
+ expect(err).is.not.null
80
+ expect(err?.["message"]).is.not.null
81
+ })
82
+
83
+ test("Required value with null value", async () => {
84
+ SSMMock.on(GetParameterCommand).resolves({
85
+ Parameter: {
86
+ Value: undefined,
87
+ },
88
+ })
89
+ let err = null
90
+ try {
91
+ await config.asyncGet("TOKEN_SECRET")
92
+ } catch (e) {
93
+ err = e
94
+ }
95
+ expect(err).is.not.null
96
+ expect(err?.["message"]).is.not.null
97
+ })
98
+
99
+ test("Required value with empty response", async () => {
100
+ SSMMock.on(GetParameterCommand).resolves({})
101
+ let err = null
102
+ try {
103
+ await config.asyncGet("TOKEN_SECRET")
104
+ } catch (e) {
105
+ err = e
106
+ }
107
+ expect(err).is.not.null
108
+ expect(err?.["message"]).is.not.null
109
+ })
110
+
111
+ test("Required value with valid response", async () => {
112
+ const value = "abc"
113
+ SSMMock.on(GetParameterCommand).resolves({
114
+ Parameter: {
115
+ Value: value,
116
+ },
117
+ })
118
+ const token = await config.asyncGet("TOKEN_SECRET")
119
+ expect(token).is.not.undefined
120
+ expect(token).to.be.equals(value)
121
+ })
122
+
123
+ test("Required value rejection", async () => {
124
+ SSMMock.on(GetParameterCommand).rejects(new Error("failed!"))
125
+ let err = null
126
+ try {
127
+ await config.asyncGet("TOKEN_SECRET")
128
+ } catch (e) {
129
+ err = e
130
+ }
131
+ expect(err).is.not.null
132
+ expect(err?.["message"]).is.not.null
133
+ })
134
+ })
135
+
136
+ describe(`Optional local environment`, () => {
137
+ beforeEach(() => {
138
+ config["resetCache"]()
139
+ })
140
+
141
+ test("Optional value with null value", async () => {
142
+ const token = config.get("PATH123")
143
+ expect(token).is.undefined
144
+ })
145
+ })
146
+
147
+ describe(`Required local environment`, () => {
148
+ beforeEach(() => {
149
+ config["resetCache"]()
150
+ })
151
+
152
+ test("Required value with null value", async () => {
153
+ let err = null
154
+ try {
155
+ config.get("PATH_FALSY")
156
+ } catch (e) {
157
+ err = e
158
+ }
159
+ expect(err).is.not.null
160
+ expect(err?.["message"]).is.not.null
161
+ })
162
+
163
+ test("Required value with valid response", async () => {
164
+ const key = "PATH"
165
+ const v = config.get(key)
166
+ expect(v).is.not.null
167
+ expect(v).to.be.equals(process.env[key])
168
+ })
169
+ })
170
+
171
+ describe(`Caching test`, () => {
172
+ test("Does cache previous fetched value", async () => {
173
+ const value = "123"
174
+ const key = "TOKEN_SECRET"
175
+ // initial fetch
176
+ SSMMock.on(GetParameterCommand).resolves({
177
+ Parameter: {
178
+ Value: value,
179
+ },
180
+ })
181
+ const v = await config.asyncGet(key)
182
+ expect(v).is.not.null
183
+ expect(v).to.be.equals(value)
184
+ // subsequent fetch
185
+ SSMMock.reset()
186
+ SSMMock.on(GetParameterCommand).rejects(new Error("failed!"))
187
+ const v2 = await config.asyncGet(key)
188
+ expect(v2).is.not.null
189
+ expect(v2).to.be.equals(value)
190
+ })
191
+ })
192
+
193
+ export {}
@@ -0,0 +1,223 @@
1
+ import {
2
+ SecretsManagerClient,
3
+ GetSecretValueCommand,
4
+ } from "@aws-sdk/client-secrets-manager"
5
+ import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"
6
+ import { mockClient } from "aws-sdk-client-mock"
7
+ import { expect } from "chai"
8
+
9
+ import EnvironmentVar, {
10
+ EnvironmentType,
11
+ } from "../../src/Config/EnvironmentVar"
12
+
13
+ const SSMMock = mockClient(SSMClient)
14
+ const SecretsManagerMock = mockClient(SecretsManagerClient)
15
+
16
+ function testRemoteEnv(mock, type, command) {
17
+ describe(`Optional ${type} environment`, () => {
18
+ // reset mock
19
+ beforeEach(() => {
20
+ mock.reset()
21
+ })
22
+
23
+ test("Does not accept sync resolve", async () => {
24
+ mock.on(command).resolves({
25
+ Parameter: {
26
+ Value: undefined,
27
+ },
28
+ })
29
+ let err = null
30
+ try {
31
+ const env = new EnvironmentVar("abc", type, true)
32
+ env.syncResolve()
33
+ } catch (e) {
34
+ err = e
35
+ }
36
+ expect(err).is.not.null
37
+ expect(err?.["message"]).is.not.null
38
+ })
39
+
40
+ test("Optional value with null value", async () => {
41
+ mock.on(command).resolves({
42
+ Parameter: {
43
+ Value: undefined,
44
+ },
45
+ })
46
+ const env = new EnvironmentVar("abc", type, true)
47
+ const token = await env.resolve()
48
+ expect(token).is.undefined
49
+ })
50
+
51
+ test("Optional value with empty response", async () => {
52
+ mock.on(command).resolves({})
53
+ const env = new EnvironmentVar("abc", type, true)
54
+ const token = await env.resolve()
55
+ expect(token).is.undefined
56
+ })
57
+
58
+ test("Optional value with valid response", async () => {
59
+ const value = "abc"
60
+ mock.on(command).resolves({
61
+ Parameter: {
62
+ Value: value,
63
+ },
64
+ })
65
+ const env = new EnvironmentVar(value, type, true)
66
+ const token = await env.resolve()
67
+ expect(token).is.not.undefined
68
+ expect(token).to.be.equals(value)
69
+ })
70
+
71
+ test("Optional value rejection", async () => {
72
+ const value = "abc"
73
+ mock.on(command).rejects(new Error("failed!"))
74
+ const env = new EnvironmentVar(value, type, true)
75
+ const token = await env.resolve()
76
+ expect(token).is.undefined
77
+ })
78
+ })
79
+
80
+ describe(`Required ${type} environment`, () => {
81
+ // reset mock
82
+ beforeEach(() => {
83
+ mock.reset()
84
+ })
85
+
86
+ test("Does not accept sync resolve", async () => {
87
+ mock.on(command).resolves({
88
+ Parameter: {
89
+ Value: undefined,
90
+ },
91
+ })
92
+ let err = null
93
+ try {
94
+ const env = new EnvironmentVar("abc", type)
95
+ env.syncResolve()
96
+ } catch (e) {
97
+ err = e
98
+ }
99
+ expect(err).is.not.null
100
+ expect(err?.["message"]).is.not.null
101
+ })
102
+
103
+ test("Required fails when null", async () => {
104
+ mock.on(command).resolves({
105
+ Parameter: {
106
+ Value: undefined,
107
+ },
108
+ })
109
+ let err = null
110
+ try {
111
+ const env = new EnvironmentVar("abc", type)
112
+ await env.resolve()
113
+ } catch (e) {
114
+ err = e
115
+ }
116
+ console.log(err)
117
+ expect(err).is.not.null
118
+ expect(err?.["message"]).is.not.null
119
+ })
120
+
121
+ test("Required fails when empty response", async () => {
122
+ mock.on(command).resolves({})
123
+ let err = null
124
+ try {
125
+ const env = new EnvironmentVar("abc", type)
126
+ await env.resolve()
127
+ } catch (e) {
128
+ err = e
129
+ }
130
+ expect(err).is.not.null
131
+ expect(err?.["message"]).is.not.null
132
+ })
133
+
134
+ test("Required value with valid response", async () => {
135
+ const value = "abc"
136
+ mock.on(command).resolves({
137
+ Parameter: {
138
+ Value: value,
139
+ },
140
+ })
141
+ const env = new EnvironmentVar(value, type)
142
+ const token = await env.resolve()
143
+ expect(token).is.not.undefined
144
+ expect(token).to.be.equals(value)
145
+ })
146
+
147
+ test("Required value rejection", async () => {
148
+ mock.on(command).rejects(new Error("failed!"))
149
+ let err = null
150
+ try {
151
+ const env = new EnvironmentVar("abc", type)
152
+ await env.resolve()
153
+ } catch (e) {
154
+ err = e
155
+ }
156
+ expect(err).is.not.null
157
+ expect(err?.["message"]).is.not.null
158
+ })
159
+ })
160
+ }
161
+
162
+ /* Remote envs test */
163
+ testRemoteEnv(SSMMock, EnvironmentType.PlainRemote, GetParameterCommand)
164
+ testRemoteEnv(
165
+ SecretsManagerMock,
166
+ EnvironmentType.SecureRemote,
167
+ GetSecretValueCommand,
168
+ )
169
+
170
+ describe("Optional Local environment", () => {
171
+ test("Does accept async resolve", async () => {
172
+ const env = new EnvironmentVar("PATH123", EnvironmentType.Local, true)
173
+ const v = await env.resolve()
174
+ expect(v).is.undefined
175
+ })
176
+
177
+ test("Optional value with null value", async () => {
178
+ const env = new EnvironmentVar("PATH123", EnvironmentType.Local, true)
179
+ const token = env.syncResolve()
180
+ expect(token).is.undefined
181
+ })
182
+
183
+ test("Optional value with valid value", async () => {
184
+ const key = "PATH"
185
+ const env = new EnvironmentVar(key, EnvironmentType.Local, true)
186
+ const token = env.syncResolve()
187
+ expect(token).is.not.undefined
188
+ expect(token).to.be.equals(process.env[key])
189
+ })
190
+ })
191
+
192
+ describe("Required local environment", () => {
193
+ test("Does accept async resolve", async () => {
194
+ const key = "PATH"
195
+ const env = new EnvironmentVar(key, EnvironmentType.Local)
196
+ const v = await env.resolve()
197
+ expect(v).is.not.null
198
+ expect(v).to.be.equals(process.env[key])
199
+ })
200
+
201
+ test("Required fails when null", async () => {
202
+ let err = null
203
+ try {
204
+ const env = new EnvironmentVar("PATH123", EnvironmentType.Local)
205
+ env.syncResolve()
206
+ } catch (e) {
207
+ err = e
208
+ }
209
+ console.log(err)
210
+ expect(err).is.not.null
211
+ expect(err?.["message"]).is.not.null
212
+ })
213
+
214
+ test("Required value with valid value", async () => {
215
+ const key = "PATH"
216
+ const env = new EnvironmentVar(key, EnvironmentType.Local)
217
+ const v = env.syncResolve()
218
+ expect(v).is.not.null
219
+ expect(v).to.be.equals(process.env[key])
220
+ })
221
+ })
222
+
223
+ export {}
@@ -0,0 +1,90 @@
1
+ import { DecryptCommand, EncryptCommand, KMSClient } from "@aws-sdk/client-kms"
2
+ import { mockClient } from "aws-sdk-client-mock"
3
+ import { expect } from "chai"
4
+
5
+ import Crypto from "../../src/Crypto/Crypto"
6
+
7
+ const KMSMock = mockClient(KMSClient)
8
+
9
+ function fakeEncryption(v) {
10
+ const f = new TextEncoder().encode(v)
11
+ return Buffer.from(f as any, "utf8").toString("hex")
12
+ }
13
+ function fakeDecryption(v) {
14
+ return new TextEncoder().encode(v)
15
+ }
16
+
17
+ describe("Encryption", () => {
18
+ // reset mock
19
+ beforeEach(() => {
20
+ KMSMock.reset()
21
+ })
22
+
23
+ const provider = new Crypto("ca-central-1", "abc123")
24
+ test("Encrypts json object", async () => {
25
+ const encryptionObj = { userID: 123 }
26
+ KMSMock.on(EncryptCommand).resolves({
27
+ CiphertextBlob: new TextEncoder().encode(JSON.stringify(encryptionObj)),
28
+ })
29
+ const token = await provider.encryptData(encryptionObj)
30
+ expect(token).is.not.null
31
+ expect(token).to.be.equals(fakeEncryption(JSON.stringify(encryptionObj)))
32
+ })
33
+
34
+ test("Encrypts string", async () => {
35
+ const encryptionText = "Hello encryption!"
36
+ KMSMock.on(EncryptCommand).resolves({
37
+ CiphertextBlob: new TextEncoder().encode(encryptionText),
38
+ })
39
+ const token = await provider.encryptData(encryptionText)
40
+ expect(token).is.not.null
41
+ expect(token).to.be.equals(fakeEncryption(encryptionText))
42
+ })
43
+
44
+ test("Fails to encrypt a number", async () => {
45
+ const encryptionText = 123
46
+ KMSMock.on(EncryptCommand).rejects(new Error("failed"))
47
+ const token = await provider.encryptData(encryptionText)
48
+ expect(token).is.null
49
+ })
50
+ })
51
+
52
+ describe("Decryption", () => {
53
+ // reset mock
54
+ beforeEach(() => {
55
+ KMSMock.reset()
56
+ })
57
+
58
+ const provider = new Crypto("ca-central-1", "abc123")
59
+ test("Decrypts json object", async () => {
60
+ const encryptionObj = { userID: 123 }
61
+ KMSMock.on(DecryptCommand).resolves({
62
+ Plaintext: fakeDecryption(JSON.stringify(encryptionObj)),
63
+ })
64
+ const token = await provider.decryptData(
65
+ fakeEncryption(JSON.stringify(encryptionObj)),
66
+ )
67
+ expect(token).is.not.null
68
+ expect(token).to.be.equals(JSON.stringify(encryptionObj))
69
+ })
70
+
71
+ test("Decrypts string", async () => {
72
+ const encryptionText = "abc123"
73
+ KMSMock.on(DecryptCommand).resolves({
74
+ Plaintext: fakeDecryption(encryptionText),
75
+ })
76
+ const token = await provider.decryptData(fakeEncryption(encryptionText))
77
+ expect(token).is.not.null
78
+ expect(token).to.be.equals(encryptionText)
79
+ })
80
+
81
+ test("Fails to decrypt a number", async () => {
82
+ const encryptionText = 123
83
+ KMSMock.on(DecryptCommand).rejects(new Error("failed"))
84
+ // @ts-ignore
85
+ const token = await provider.decryptData(encryptionText)
86
+ expect(token).is.null
87
+ })
88
+ })
89
+
90
+ export {}
@@ -0,0 +1,92 @@
1
+ import { expect } from "chai"
2
+
3
+ import JWT from "../../src/Crypto/JWT"
4
+ import { foreignToken, privateKey } from "../Test.utils"
5
+
6
+ describe("Creates token", () => {
7
+ const provider = new JWT(privateKey, "7d")
8
+ test("Creates token without explicity expiration", () => {
9
+ const token = provider.createToken({ userID: 123 })
10
+ expect(token).to.be.a("string")
11
+ expect(token).is.not.null
12
+ })
13
+
14
+ test("Creates token with explicity expiration", () => {
15
+ const token = provider.createToken({ userID: 123 }, "7d")
16
+ expect(token).to.be.a("string")
17
+ expect(token).is.not.null
18
+ })
19
+
20
+ test("Creates token with explicity token override", () => {
21
+ const token = provider.createToken({ userID: 123 }, "7d", privateKey)
22
+ expect(token).to.be.a("string")
23
+ expect(token).is.not.null
24
+ })
25
+
26
+ test("Creates token with explicity token options", () => {
27
+ const token = provider.createToken({ userID: 123 }, undefined, undefined, {
28
+ expiresIn: "7d",
29
+ })
30
+ expect(token).to.be.a("string")
31
+ expect(token).is.not.null
32
+ })
33
+
34
+ test("Creates token with no expiration", () => {
35
+ const localProvider = new JWT(privateKey)
36
+ const token = localProvider.createToken({ userID: 123 })
37
+ expect(token).to.be.a("string")
38
+ expect(token).is.not.null
39
+ })
40
+ })
41
+
42
+ describe("Validates token", () => {
43
+ const provider = new JWT(privateKey, "7d")
44
+ test("Succeed to validate just created token", () => {
45
+ // Creates token
46
+ const token = provider.createToken({ userID: 123 }, "7d", privateKey)
47
+ expect(token).to.be.a("string")
48
+ expect(token).is.not.null
49
+ // Validates token
50
+ const validationResp = provider.validateToken(token)
51
+ expect(validationResp).is.not.null
52
+ expect(validationResp.isValid).is.true
53
+ expect(validationResp["isExpired"]).is.undefined
54
+ expect(validationResp["decodedToken"]).is.not.null
55
+ expect(validationResp["decodedToken"].userID).to.be.equals(123)
56
+ expect(validationResp["decodedToken"].exp).to.be.a("number")
57
+ expect(validationResp["decodedToken"].exp).to.be.above(Date.now() / 1000)
58
+ })
59
+
60
+ test("Fails to validate invalid token", () => {
61
+ // Creates token
62
+ const token = provider.createToken({ userID: 123 }, "7d", privateKey)
63
+ // Validates token
64
+ const validationResp = provider.validateToken(token + "123")
65
+ expect(validationResp).is.not.null
66
+ expect(validationResp.isValid).is.false
67
+ expect(validationResp["isExpired"]).is.undefined
68
+ expect(validationResp["decodedToken"]).to.undefined
69
+ })
70
+
71
+ test("Fails to validate expired token", () => {
72
+ // Creates token
73
+ const token = provider.createToken({ userID: 123 }, "-7d", privateKey)
74
+ // Validates token
75
+ const validationResp = provider.validateToken(token)
76
+ expect(validationResp).is.not.null
77
+ expect(validationResp.isValid).is.false
78
+ expect(validationResp["isExpired"]).is.true
79
+ expect(validationResp["decodedToken"]).to.undefined
80
+ })
81
+
82
+ test("Fails to validate foreign token", () => {
83
+ // Validates token
84
+ const validationResp = provider.validateToken(foreignToken)
85
+ expect(validationResp).is.not.null
86
+ expect(validationResp.isValid).is.false
87
+ expect(validationResp["isExpired"]).is.undefined
88
+ expect(validationResp["decodedToken"]).to.undefined
89
+ })
90
+ })
91
+
92
+ export {}
@@ -0,0 +1,108 @@
1
+ // get console ref and mock before logger import
2
+ const consoleProxy = console
3
+ const mock = jest.spyOn(consoleProxy, "log")
4
+ // import logger after first ref
5
+ import Logger from "../../src/Logger/Logger"
6
+ // get console reference after logger import
7
+ const transactionID = "123-456"
8
+
9
+ function setContainerFlag(isContainer: boolean) {
10
+ if (isContainer) {
11
+ process.env["HYBRIDLESS_RUNTIME"] = "true"
12
+ } else {
13
+ process.env["HYBRIDLESS_RUNTIME"] = undefined
14
+ }
15
+ }
16
+
17
+ function fixLogTypePrefix(logType: string) {
18
+ if (logType == "exception") return "error"
19
+ if (logType == "warning") return "warn"
20
+ if (logType == "log") return "info"
21
+ return logType
22
+ }
23
+
24
+ function testLogs(isContainer: boolean, provider?: Logger) {
25
+ const type = isContainer ? "container" : "serverless"
26
+ const loggerType = !provider ? "Console" : "Logger"
27
+ const localProvider = provider || console
28
+
29
+ test(`${type} - ${loggerType} Log - Suppress sensitive info`, async () => {
30
+ setContainerFlag(isContainer)
31
+ localProvider.log("TEST", { password: "123" })
32
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
33
+ 1,
34
+ expect.stringContaining(
35
+ (isContainer ? `${transactionID} ` : "") + "[INFO] [Logger.test.ts:",
36
+ ),
37
+ )
38
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
39
+ 1,
40
+ expect.stringContaining("] TEST **SUPPRESSED_SENSITIVE_DATA**"),
41
+ )
42
+ })
43
+
44
+ test(`${type} - ${loggerType} Log - Suppress sensitive info (array)`, async () => {
45
+ setContainerFlag(isContainer)
46
+ localProvider.log("TEST2", [{ password: "123" }])
47
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
48
+ 1,
49
+ expect.stringContaining(
50
+ (isContainer ? `${transactionID} ` : "") + "[INFO] [Logger.test.ts:",
51
+ ),
52
+ )
53
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
54
+ 1,
55
+ expect.stringContaining("] TEST2 **SUPPRESSED_SENSITIVE_DATA**"),
56
+ )
57
+ })
58
+
59
+ for (const logType of [
60
+ "log",
61
+ "debug",
62
+ "info",
63
+ "warn",
64
+ "warning",
65
+ "error",
66
+ "exception",
67
+ ]) {
68
+ test(`${type} - ${loggerType} ${logType}`, async () => {
69
+ setContainerFlag(isContainer)
70
+ localProvider[logType](logType.toUpperCase())
71
+ // alias
72
+ const logTypePrefix = fixLogTypePrefix(logType)
73
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
74
+ 1,
75
+ expect.stringContaining(
76
+ (isContainer ? `${transactionID} ` : "") +
77
+ `[${logTypePrefix.toUpperCase()}] [Logger.test.ts:`,
78
+ ),
79
+ )
80
+ expect(consoleProxy.log).toHaveBeenNthCalledWith(
81
+ 1,
82
+ expect.stringContaining(`] ${logType.toUpperCase()}`),
83
+ )
84
+ })
85
+ }
86
+ }
87
+
88
+ describe("Logger", () => {
89
+ beforeEach(() => {
90
+ mock.mockClear()
91
+ })
92
+ const provider = new Logger(
93
+ {
94
+ logLevel: "DEBUG",
95
+ sensitiveFilteringKeywords: true,
96
+ },
97
+ transactionID,
98
+ )
99
+ provider.notGlobalLogger()
100
+ // Test serverless logs
101
+ testLogs(false, provider)
102
+ testLogs(false)
103
+ // Test container logs
104
+ testLogs(true, provider)
105
+ testLogs(true)
106
+ })
107
+
108
+ export {}