@geekmidas/constructs 3.0.10 → 3.0.12
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.
- package/CHANGELOG.md +24 -0
- package/dist/{Endpoint-BoTfIVxN.d.cts → Endpoint-CE7qHX5S.d.cts} +2 -2
- package/dist/{Endpoint-BoTfIVxN.d.cts.map → Endpoint-CE7qHX5S.d.cts.map} +1 -1
- package/dist/{HonoEndpointAdaptor-DNn3-dHv.cjs → HonoEndpointAdaptor-DhphPq5r.cjs} +5 -5
- package/dist/{HonoEndpointAdaptor-DNn3-dHv.cjs.map → HonoEndpointAdaptor-DhphPq5r.cjs.map} +1 -1
- package/dist/{HonoEndpointAdaptor-cpttJfsS.mjs → HonoEndpointAdaptor-DyYv0IoU.mjs} +5 -5
- package/dist/{HonoEndpointAdaptor-cpttJfsS.mjs.map → HonoEndpointAdaptor-DyYv0IoU.mjs.map} +1 -1
- package/dist/adaptors/aws.cjs +5 -5
- package/dist/adaptors/aws.cjs.map +1 -1
- package/dist/adaptors/aws.d.cts +2 -2
- package/dist/adaptors/aws.mjs +5 -5
- package/dist/adaptors/aws.mjs.map +1 -1
- package/dist/adaptors/hono.cjs +3 -3
- package/dist/adaptors/hono.d.cts +2 -2
- package/dist/adaptors/hono.mjs +3 -3
- package/dist/adaptors/testing.cjs +5 -5
- package/dist/adaptors/testing.cjs.map +1 -1
- package/dist/adaptors/testing.d.cts +2 -2
- package/dist/adaptors/testing.mjs +6 -6
- package/dist/adaptors/testing.mjs.map +1 -1
- package/dist/crons/index.cjs +1 -1
- package/dist/crons/index.d.cts +1 -1
- package/dist/crons/index.mjs +1 -1
- package/dist/endpoints/index.cjs +2 -2
- package/dist/endpoints/index.d.cts +4 -4
- package/dist/endpoints/index.mjs +2 -2
- package/dist/functions/index.cjs +1 -1
- package/dist/functions/index.d.cts +1 -1
- package/dist/functions/index.mjs +1 -1
- package/dist/{functions-yrAtvBor.cjs → functions-DiaRAdfp.cjs} +1 -1
- package/dist/{functions-yrAtvBor.cjs.map → functions-DiaRAdfp.cjs.map} +1 -1
- package/dist/{functions-DN9d6sgj.mjs → functions-GmSHFbpr.mjs} +1 -1
- package/dist/{functions-DN9d6sgj.mjs.map → functions-GmSHFbpr.mjs.map} +1 -1
- package/dist/{index-6U4XAuUI.d.cts → index-CzIMpK-e.d.cts} +5 -5
- package/dist/{index-6U4XAuUI.d.cts.map → index-CzIMpK-e.d.cts.map} +1 -1
- package/dist/{lazyAccessors-BPPR05EA.mjs → lazyAccessors-5h-aWohM.mjs} +2 -2
- package/dist/{lazyAccessors-BPPR05EA.mjs.map → lazyAccessors-5h-aWohM.mjs.map} +1 -1
- package/dist/{lazyAccessors-BzMEdmis.cjs → lazyAccessors-Bc1u42WC.cjs} +2 -2
- package/dist/{lazyAccessors-BzMEdmis.cjs.map → lazyAccessors-Bc1u42WC.cjs.map} +1 -1
- package/package.json +94 -49
- package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +4 -4
- package/src/endpoints/HonoEndpointAdaptor.ts +2 -2
- package/src/endpoints/TestEndpointAdaptor.ts +4 -4
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +5 -7
- package/src/endpoints/__tests__/HonoEndpointAdaptor.spec.ts +9 -11
- package/src/endpoints/__tests__/MswEndpointAdaptor.spec.ts +2 -2
- package/src/endpoints/__tests__/TestEndpointAdaptor.spec.ts +1 -1
package/package.json
CHANGED
|
@@ -1,53 +1,98 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/constructs",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
"import": {
|
|
9
|
+
"types": "./dist/index.d.mts",
|
|
10
|
+
"default": "./dist/index.mjs"
|
|
11
|
+
},
|
|
12
|
+
"require": {
|
|
13
|
+
"types": "./dist/index.d.cts",
|
|
14
|
+
"default": "./dist/index.cjs"
|
|
15
|
+
}
|
|
11
16
|
},
|
|
12
17
|
"./endpoints": {
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
"import": {
|
|
19
|
+
"types": "./dist/endpoints/index.d.mts",
|
|
20
|
+
"default": "./dist/endpoints/index.mjs"
|
|
21
|
+
},
|
|
22
|
+
"require": {
|
|
23
|
+
"types": "./dist/endpoints/index.d.cts",
|
|
24
|
+
"default": "./dist/endpoints/index.cjs"
|
|
25
|
+
}
|
|
16
26
|
},
|
|
17
27
|
"./functions": {
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
"import": {
|
|
29
|
+
"types": "./dist/functions/index.d.mts",
|
|
30
|
+
"default": "./dist/functions/index.mjs"
|
|
31
|
+
},
|
|
32
|
+
"require": {
|
|
33
|
+
"types": "./dist/functions/index.d.cts",
|
|
34
|
+
"default": "./dist/functions/index.cjs"
|
|
35
|
+
}
|
|
21
36
|
},
|
|
22
37
|
"./crons": {
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
38
|
+
"import": {
|
|
39
|
+
"types": "./dist/crons/index.d.mts",
|
|
40
|
+
"default": "./dist/crons/index.mjs"
|
|
41
|
+
},
|
|
42
|
+
"require": {
|
|
43
|
+
"types": "./dist/crons/index.d.cts",
|
|
44
|
+
"default": "./dist/crons/index.cjs"
|
|
45
|
+
}
|
|
26
46
|
},
|
|
27
47
|
"./subscribers": {
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
48
|
+
"import": {
|
|
49
|
+
"types": "./dist/subscribers/index.d.mts",
|
|
50
|
+
"default": "./dist/subscribers/index.mjs"
|
|
51
|
+
},
|
|
52
|
+
"require": {
|
|
53
|
+
"types": "./dist/subscribers/index.d.cts",
|
|
54
|
+
"default": "./dist/subscribers/index.cjs"
|
|
55
|
+
}
|
|
31
56
|
},
|
|
32
57
|
"./types": {
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
58
|
+
"import": {
|
|
59
|
+
"types": "./dist/types.d.mts",
|
|
60
|
+
"default": "./dist/types.mjs"
|
|
61
|
+
},
|
|
62
|
+
"require": {
|
|
63
|
+
"types": "./dist/types.d.cts",
|
|
64
|
+
"default": "./dist/types.cjs"
|
|
65
|
+
}
|
|
36
66
|
},
|
|
37
67
|
"./hono": {
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
68
|
+
"import": {
|
|
69
|
+
"types": "./dist/adaptors/hono.d.mts",
|
|
70
|
+
"default": "./dist/adaptors/hono.mjs"
|
|
71
|
+
},
|
|
72
|
+
"require": {
|
|
73
|
+
"types": "./dist/adaptors/hono.d.cts",
|
|
74
|
+
"default": "./dist/adaptors/hono.cjs"
|
|
75
|
+
}
|
|
41
76
|
},
|
|
42
77
|
"./aws": {
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
78
|
+
"import": {
|
|
79
|
+
"types": "./dist/adaptors/aws.d.mts",
|
|
80
|
+
"default": "./dist/adaptors/aws.mjs"
|
|
81
|
+
},
|
|
82
|
+
"require": {
|
|
83
|
+
"types": "./dist/adaptors/aws.d.cts",
|
|
84
|
+
"default": "./dist/adaptors/aws.cjs"
|
|
85
|
+
}
|
|
46
86
|
},
|
|
47
87
|
"./testing": {
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
88
|
+
"import": {
|
|
89
|
+
"types": "./dist/adaptors/testing.d.mts",
|
|
90
|
+
"default": "./dist/adaptors/testing.mjs"
|
|
91
|
+
},
|
|
92
|
+
"require": {
|
|
93
|
+
"types": "./dist/adaptors/testing.d.cts",
|
|
94
|
+
"default": "./dist/adaptors/testing.cjs"
|
|
95
|
+
}
|
|
51
96
|
}
|
|
52
97
|
},
|
|
53
98
|
"repository": {
|
|
@@ -81,33 +126,33 @@
|
|
|
81
126
|
"pg": "~8.16.3",
|
|
82
127
|
"msw": "~2.10.3",
|
|
83
128
|
"zod": "~4.1.13",
|
|
84
|
-
"@geekmidas/audit": "^2.0.
|
|
85
|
-
"@geekmidas/cache": "^1.1.
|
|
86
|
-
"@geekmidas/db": "^1.0.
|
|
87
|
-
"@geekmidas/envkit": "^1.0.
|
|
88
|
-
"@geekmidas/errors": "^1.0.
|
|
89
|
-
"@geekmidas/events": "^1.1.
|
|
90
|
-
"@geekmidas/logger": "^1.0.
|
|
91
|
-
"@geekmidas/rate-limit": "^2.0.
|
|
92
|
-
"@geekmidas/schema": "^1.0.
|
|
93
|
-
"@geekmidas/services": "^1.0.
|
|
94
|
-
"@geekmidas/testkit": "^1.0.
|
|
129
|
+
"@geekmidas/audit": "^2.0.1",
|
|
130
|
+
"@geekmidas/cache": "^1.1.1",
|
|
131
|
+
"@geekmidas/db": "^1.0.2",
|
|
132
|
+
"@geekmidas/envkit": "^1.0.7",
|
|
133
|
+
"@geekmidas/errors": "^1.0.1",
|
|
134
|
+
"@geekmidas/events": "^1.1.3",
|
|
135
|
+
"@geekmidas/logger": "^1.0.2",
|
|
136
|
+
"@geekmidas/rate-limit": "^2.0.1",
|
|
137
|
+
"@geekmidas/schema": "^1.0.2",
|
|
138
|
+
"@geekmidas/services": "^1.0.2",
|
|
139
|
+
"@geekmidas/testkit": "^1.0.7"
|
|
95
140
|
},
|
|
96
141
|
"peerDependencies": {
|
|
97
142
|
"@middy/core": ">=6.3.1",
|
|
98
143
|
"@types/aws-lambda": ">=8.10.92",
|
|
99
144
|
"hono": ">=4.8.2",
|
|
100
145
|
"msw": ">=2.0.0",
|
|
101
|
-
"@geekmidas/audit": "^2.0.
|
|
102
|
-
"@geekmidas/cache": "^1.1.
|
|
103
|
-
"@geekmidas/db": "^1.0.
|
|
104
|
-
"@geekmidas/envkit": "^1.0.
|
|
105
|
-
"@geekmidas/errors": "^1.0.
|
|
106
|
-
"@geekmidas/events": "^1.1.
|
|
107
|
-
"@geekmidas/logger": "^1.0.
|
|
108
|
-
"@geekmidas/rate-limit": "^2.0.
|
|
109
|
-
"@geekmidas/schema": "^1.0.
|
|
110
|
-
"@geekmidas/services": "^1.0.
|
|
146
|
+
"@geekmidas/audit": "^2.0.1",
|
|
147
|
+
"@geekmidas/cache": "^1.1.1",
|
|
148
|
+
"@geekmidas/db": "^1.0.2",
|
|
149
|
+
"@geekmidas/envkit": "^1.0.7",
|
|
150
|
+
"@geekmidas/errors": "^1.0.1",
|
|
151
|
+
"@geekmidas/events": "^1.1.3",
|
|
152
|
+
"@geekmidas/logger": "^1.0.2",
|
|
153
|
+
"@geekmidas/rate-limit": "^2.0.1",
|
|
154
|
+
"@geekmidas/schema": "^1.0.2",
|
|
155
|
+
"@geekmidas/services": "^1.0.2"
|
|
111
156
|
},
|
|
112
157
|
"peerDependenciesMeta": {
|
|
113
158
|
"@geekmidas/audit": {
|
|
@@ -23,7 +23,7 @@ export interface TelescopeIntegration {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
import {
|
|
26
|
-
|
|
26
|
+
ForbiddenError,
|
|
27
27
|
UnprocessableEntityError,
|
|
28
28
|
wrapError,
|
|
29
29
|
} from '@geekmidas/errors';
|
|
@@ -267,9 +267,9 @@ export abstract class AmazonApiGatewayEndpoint<
|
|
|
267
267
|
} as any);
|
|
268
268
|
|
|
269
269
|
if (!isAuthorized) {
|
|
270
|
-
logger.warn('
|
|
271
|
-
throw new
|
|
272
|
-
'
|
|
270
|
+
logger.warn('Forbidden access attempt');
|
|
271
|
+
throw new ForbiddenError(
|
|
272
|
+
'Forbidden access to the endpoint',
|
|
273
273
|
'You do not have permission to access this resource.',
|
|
274
274
|
);
|
|
275
275
|
}
|
|
@@ -416,8 +416,8 @@ export class HonoEndpoint<
|
|
|
416
416
|
} as any);
|
|
417
417
|
|
|
418
418
|
if (!isAuthorized) {
|
|
419
|
-
logger.warn('
|
|
420
|
-
return c.json({ error: '
|
|
419
|
+
logger.warn('Forbidden access attempt');
|
|
420
|
+
return c.json({ error: 'Forbidden' }, 403);
|
|
421
421
|
}
|
|
422
422
|
|
|
423
423
|
// Check rate limit only if configured
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
} from '@geekmidas/audit';
|
|
6
6
|
import { DefaultAuditor } from '@geekmidas/audit';
|
|
7
7
|
import { EnvironmentParser } from '@geekmidas/envkit';
|
|
8
|
-
import {
|
|
8
|
+
import { ForbiddenError } from '@geekmidas/errors';
|
|
9
9
|
import type { EventPublisher } from '@geekmidas/events';
|
|
10
10
|
import type { Logger } from '@geekmidas/logger';
|
|
11
11
|
import type {
|
|
@@ -223,9 +223,9 @@ export class TestEndpointAdaptor<
|
|
|
223
223
|
} as any);
|
|
224
224
|
|
|
225
225
|
if (!isAuthorized) {
|
|
226
|
-
logger.warn('
|
|
227
|
-
throw new
|
|
228
|
-
'
|
|
226
|
+
logger.warn('Forbidden access attempt');
|
|
227
|
+
throw new ForbiddenError(
|
|
228
|
+
'Forbidden access to the endpoint',
|
|
229
229
|
'You do not have permission to access this resource.',
|
|
230
230
|
);
|
|
231
231
|
}
|
|
@@ -823,14 +823,12 @@ describe('AmazonApiGatewayV1Endpoint', () => {
|
|
|
823
823
|
|
|
824
824
|
const response = await handler(event, context);
|
|
825
825
|
|
|
826
|
-
expect(response.statusCode).toBe(
|
|
826
|
+
expect(response.statusCode).toBe(403);
|
|
827
827
|
const body = JSON.parse(response.body!);
|
|
828
828
|
expect(body).toMatchObject({
|
|
829
|
-
message: '
|
|
829
|
+
message: 'Forbidden access to the endpoint',
|
|
830
830
|
});
|
|
831
|
-
expect(mockLogger.warn).toHaveBeenCalledWith(
|
|
832
|
-
'Unauthorized access attempt',
|
|
833
|
-
);
|
|
831
|
+
expect(mockLogger.warn).toHaveBeenCalledWith('Forbidden access attempt');
|
|
834
832
|
});
|
|
835
833
|
|
|
836
834
|
it('should handle async authorize functions', async () => {
|
|
@@ -879,9 +877,9 @@ describe('AmazonApiGatewayV1Endpoint', () => {
|
|
|
879
877
|
});
|
|
880
878
|
const invalidResponse = await handler(invalidEvent, context);
|
|
881
879
|
const invalidResponseBody = JSON.parse(invalidResponse.body!);
|
|
882
|
-
expect(invalidResponse.statusCode).toBe(
|
|
880
|
+
expect(invalidResponse.statusCode).toBe(403);
|
|
883
881
|
expect(invalidResponseBody).toMatchObject({
|
|
884
|
-
message: '
|
|
882
|
+
message: 'Forbidden access to the endpoint',
|
|
885
883
|
});
|
|
886
884
|
});
|
|
887
885
|
});
|
|
@@ -801,7 +801,7 @@ describe('HonoEndpointAdaptor', () => {
|
|
|
801
801
|
expect(await response.json()).toEqual({ success: true });
|
|
802
802
|
});
|
|
803
803
|
|
|
804
|
-
it('should return
|
|
804
|
+
it('should return 403 when authorize returns false', async () => {
|
|
805
805
|
const endpoint = new Endpoint({
|
|
806
806
|
route: '/protected',
|
|
807
807
|
method: 'GET',
|
|
@@ -827,11 +827,9 @@ describe('HonoEndpointAdaptor', () => {
|
|
|
827
827
|
adaptor.addRoute(serviceDiscovery, app);
|
|
828
828
|
|
|
829
829
|
const response = await app.request('/protected');
|
|
830
|
-
expect(response.status).toBe(
|
|
831
|
-
expect(await response.json()).toEqual({ error: '
|
|
832
|
-
expect(mockLogger.warn).toHaveBeenCalledWith(
|
|
833
|
-
'Unauthorized access attempt',
|
|
834
|
-
);
|
|
830
|
+
expect(response.status).toBe(403);
|
|
831
|
+
expect(await response.json()).toEqual({ error: 'Forbidden' });
|
|
832
|
+
expect(mockLogger.warn).toHaveBeenCalledWith('Forbidden access attempt');
|
|
835
833
|
});
|
|
836
834
|
|
|
837
835
|
it('should handle async authorize functions with headers', async () => {
|
|
@@ -873,8 +871,8 @@ describe('HonoEndpointAdaptor', () => {
|
|
|
873
871
|
const invalidResponse = await app.request('/protected', {
|
|
874
872
|
headers: { Authorization: 'Bearer invalid-token' },
|
|
875
873
|
});
|
|
876
|
-
expect(invalidResponse.status).toBe(
|
|
877
|
-
expect(await invalidResponse.json()).toEqual({ error: '
|
|
874
|
+
expect(invalidResponse.status).toBe(403);
|
|
875
|
+
expect(await invalidResponse.json()).toEqual({ error: 'Forbidden' });
|
|
878
876
|
});
|
|
879
877
|
|
|
880
878
|
it('should authorize with services available', async () => {
|
|
@@ -924,7 +922,7 @@ describe('HonoEndpointAdaptor', () => {
|
|
|
924
922
|
const invalidResponse = await app.request('/protected', {
|
|
925
923
|
headers: { Authorization: 'Bearer invalid-token' },
|
|
926
924
|
});
|
|
927
|
-
expect(invalidResponse.status).toBe(
|
|
925
|
+
expect(invalidResponse.status).toBe(403);
|
|
928
926
|
});
|
|
929
927
|
|
|
930
928
|
it('should authorize with session', async () => {
|
|
@@ -966,7 +964,7 @@ describe('HonoEndpointAdaptor', () => {
|
|
|
966
964
|
|
|
967
965
|
// Test with no token (no session)
|
|
968
966
|
const noTokenResponse = await app.request('/protected');
|
|
969
|
-
expect(noTokenResponse.status).toBe(
|
|
967
|
+
expect(noTokenResponse.status).toBe(403);
|
|
970
968
|
});
|
|
971
969
|
|
|
972
970
|
it('should handle authorization errors', async () => {
|
|
@@ -1099,7 +1097,7 @@ describe('HonoEndpointAdaptor', () => {
|
|
|
1099
1097
|
body: JSON.stringify({ role: 'viewer' }),
|
|
1100
1098
|
});
|
|
1101
1099
|
|
|
1102
|
-
expect(response.status).toBe(
|
|
1100
|
+
expect(response.status).toBe(403);
|
|
1103
1101
|
});
|
|
1104
1102
|
});
|
|
1105
1103
|
|
|
@@ -140,7 +140,7 @@ describe('MswEndpointAdaptor', () => {
|
|
|
140
140
|
expect(body.name).toBe('Test User');
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
-
it('should return
|
|
143
|
+
it('should return 403 when authorization fails', async () => {
|
|
144
144
|
const contextId = crypto.randomUUID();
|
|
145
145
|
registerContext(contextId, {});
|
|
146
146
|
|
|
@@ -151,7 +151,7 @@ describe('MswEndpointAdaptor', () => {
|
|
|
151
151
|
},
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
-
expect(response.status).toBe(
|
|
154
|
+
expect(response.status).toBe(403);
|
|
155
155
|
});
|
|
156
156
|
|
|
157
157
|
it('should return 200 when authorization passes', async () => {
|
|
@@ -491,7 +491,7 @@ describe('TestEndpointAdaptor', () => {
|
|
|
491
491
|
services: mockServices,
|
|
492
492
|
headers: { host: 'example.com' },
|
|
493
493
|
}),
|
|
494
|
-
).rejects.toThrow('
|
|
494
|
+
).rejects.toThrow('Forbidden');
|
|
495
495
|
});
|
|
496
496
|
|
|
497
497
|
it('should allow when authorize uses body to allow', async () => {
|