1
+ // real-db-integration-controller.ts
2
+ // Test access control with actual database queries
3
+
4
+ import { Controller , Get , Query , Inject } from '@nestjs/common' ;
5
+ import { Repository } from 'typeorm' ;
6
+ import { InjectRepository } from '@nestjs/typeorm' ;
7
+ import { simpleAccessControlledGetAll } from '@klerick/json-api-nestjs-typeorm' ;
8
+
9
+ // Import your entities
10
+ import {
11
+ Users ,
12
+ Addresses ,
13
+ Comments ,
14
+ Roles ,
15
+ BookList ,
16
+ School ,
17
+ User ,
18
+ Workspace ,
19
+ YasserNasser
20
+ } from '@nestjs-json-api/typeorm-database' ;
21
+
22
+ @Controller ( 'api/real-test' )
23
+ export class RealDbIntegrationController {
24
+
25
+ constructor (
26
+ @InjectRepository ( School ) private usersRepository : Repository < School >
27
+ ) { }
28
+
29
+ @Get ( 'users-original' )
30
+ async getOriginalUsers ( @Query ( ) query : any ) {
31
+ console . log ( '📊 Testing ORIGINAL database query (no access control)...' ) ;
32
+
33
+ const pageSize = parseInt ( query . size ) || 10 ;
34
+ const pageNumber = parseInt ( query . page ) || 1 ;
35
+ const skip = ( pageNumber - 1 ) * pageSize ;
36
+
37
+ // Simple original query
38
+ const [ data , totalItems ] = await this . usersRepository . findAndCount ( {
39
+ take : pageSize ,
40
+ skip : skip
41
+ } ) ;
42
+
43
+ console . log ( `📊 Original query: ${ data . length } items returned, ${ totalItems } total` ) ;
44
+ console . log ( '📊 First user:' , data [ 0 ] ) ;
45
+
46
+ return {
47
+ meta : {
48
+ pageNumber,
49
+ totalItems,
50
+ pageSize,
51
+ } ,
52
+ data,
53
+ message : 'Original query - no access control'
54
+ } ;
55
+ }
56
+
57
+ @Get ( 'users-access-controlled' )
58
+ async getAccessControlledUsers ( @Query ( ) query : any ) {
59
+ console . log ( '🔐 Testing ACCESS CONTROLLED database query...' ) ;
60
+
61
+ // Mock TypeORM service structure
62
+ const mockTypeOrmService = {
63
+ repository : this . usersRepository ,
64
+ typeormUtilsService : {
65
+ currentAlias : 'school' ,
66
+ currentPrimaryColumn : 'id'
67
+ } ,
68
+ transformDataService : {
69
+ transformData : ( data : any , query : any ) => ( {
70
+ data,
71
+ included : null
72
+ } )
73
+ }
74
+ } ;
75
+
76
+ // Mock user context
77
+ const userContext = {
78
+ id : 'test-user-123' ,
79
+ workspaceId : 'test-workspace-123' ,
80
+ roles : [ 'admin' ] // Try changing to ['user'] to see different results
81
+ } ;
82
+
83
+ // Mock query structure
84
+ const mockQuery = {
85
+ page : {
86
+ size : parseInt ( query . size ) || 10 ,
87
+ number : parseInt ( query . page ) || 1
88
+ }
89
+ } ;
90
+
91
+ try {
92
+ // Call our access-controlled function
93
+ const result = await simpleAccessControlledGetAll (
94
+ mockTypeOrmService ,
95
+ mockQuery ,
96
+ userContext
97
+ ) ;
98
+
99
+ console . log ( '🔐 Access controlled result:' , result ) ;
100
+
101
+ return {
102
+ ...result ,
103
+ message : 'Access controlled query - only accessible users returned'
104
+ } ;
105
+
106
+ } catch ( error ) {
107
+ console . error ( '❌ Error in access controlled query:' , error ) ;
108
+ return {
109
+ error : 'Access controlled query failed' ,
110
+ details : error . message ,
111
+ data : [ ]
112
+ } ;
113
+ }
114
+ }
115
+
116
+ @Get ( 'compare' )
117
+ async compareResults ( @Query ( ) query : any ) {
118
+ console . log ( '🔍 COMPARING original vs access-controlled results...' ) ;
119
+
120
+ try {
121
+ // Get both results
122
+ const original = await this . getOriginalUsers ( query ) ;
123
+ const accessControlled = await this . getAccessControlledUsers ( query ) ;
124
+
125
+ console . log ( '📊 COMPARISON RESULTS:' ) ;
126
+ console . log ( `Original: ${ original . data ?. length || 0 } users` ) ;
127
+ console . log ( `Access Controlled: ${ accessControlled . data ?. length || 0 } users` ) ;
128
+
129
+ return {
130
+ original : {
131
+ count : original . data ?. length || 0 ,
132
+ totalItems : original . meta ?. totalItems || 0 ,
133
+ data : original . data
134
+ } ,
135
+ accessControlled : {
136
+ count : accessControlled . data ?. length || 0 ,
137
+ totalItems : accessControlled . meta ?. totalItems || 0 ,
138
+ data : accessControlled . data
139
+ } ,
140
+ comparison : {
141
+ filtered : ( original . data ?. length || 0 ) - ( accessControlled . data ?. length || 0 ) ,
142
+ message : 'Access control successfully filtered results'
143
+ }
144
+ } ;
145
+
146
+ } catch ( error ) {
147
+ console . error ( '❌ Comparison failed:' , error ) ;
148
+ return {
149
+ error : 'Comparison failed' ,
150
+ details : error . message
151
+ } ;
152
+ }
153
+ }
154
+
155
+ @Get ( 'test-different-users' )
156
+ async testDifferentUsers ( ) {
157
+ console . log ( '👥 Testing DIFFERENT USER ROLES...' ) ;
158
+
159
+ const mockTypeOrmService = {
160
+ repository : this . usersRepository ,
161
+ typeormUtilsService : {
162
+ currentAlias : 'users' ,
163
+ currentPrimaryColumn : 'id'
164
+ } ,
165
+ transformDataService : {
166
+ transformData : ( data : any , query : any ) => ( { data, included : null } )
167
+ }
168
+ } ;
169
+
170
+ const mockQuery = { page : { size : 10 , number : 1 } } ;
171
+
172
+ // Test admin user
173
+ const adminContext = {
174
+ id : 'admin-user' ,
175
+ workspaceId : 'test-workspace-123' ,
176
+ roles : [ 'admin' ]
177
+ } ;
178
+
179
+ // Test regular user
180
+ const userContext = {
181
+ id : 'regular-user' ,
182
+ workspaceId : 'test-workspace-123' ,
183
+ roles : [ 'user' ]
184
+ } ;
185
+
186
+ try {
187
+ const adminResult = await simpleAccessControlledGetAll ( mockTypeOrmService , mockQuery , adminContext ) ;
188
+ const userResult = await simpleAccessControlledGetAll ( mockTypeOrmService , mockQuery , userContext ) ;
189
+
190
+ console . log ( `👨💼 Admin sees: ${ adminResult . data ?. length || 0 } users` ) ;
191
+ console . log ( `👤 Regular user sees: ${ userResult . data ?. length || 0 } users` ) ;
192
+
193
+ return {
194
+ admin : {
195
+ accessibleIds : [ '1' , '2' , '3' , '4' , '5' ] , // From our mock function
196
+ actualResults : adminResult . data ?. length || 0 ,
197
+ data : adminResult . data
198
+ } ,
199
+ user : {
200
+ accessibleIds : [ '1' , '2' ] , // From our mock function
201
+ actualResults : userResult . data ?. length || 0 ,
202
+ data : userResult . data
203
+ } ,
204
+ message : 'Different users see different results based on access control'
205
+ } ;
206
+
207
+ } catch ( error ) {
208
+ console . error ( '❌ Multi-user test failed:' , error ) ;
209
+ return {
210
+ error : 'Multi-user test failed' ,
211
+ details : error . message
212
+ } ;
213
+ }
214
+ }
215
+ }
216
+
217
+ // ===================================
218
+ // ADD TO YOUR MODULE
219
+ // ===================================
220
+
221
+ /*
222
+ Add this to your resources-type.module.ts:
223
+
224
+ import { RealDbIntegrationController } from './real-db-integration-controller';
225
+
226
+ @Module ({
227
+ imports: [
228
+ TypeOrmModule.forFeature([Users]), // Make sure Users entity is available
229
+ TypeOrmJsonApiModule.forRoot({
230
+ entities: [Users, Documents],
231
+ })
232
+ ],
233
+ controllers: [TestController, RealDbIntegrationController], // Add the new controller
234
+ })
235
+ export class ResourcesTypeModule {}
236
+ */
237
+
238
+ // ===================================
239
+ // TESTING ENDPOINTS
240
+ // ===================================
241
+
242
+ /*
243
+ NOW TEST THESE ENDPOINTS:
244
+
245
+ 1. GET /api/real-test/users-original
246
+ → Should return ALL users from database (no filtering)
247
+
248
+ 2. GET /api/real-test/users-access-controlled
249
+ → Should return ONLY users with IDs ['1','2','3','4','5'] (admin) or ['1','2'] (user)
250
+
251
+ 3. GET /api/real-test/compare
252
+ → Shows side-by-side comparison of original vs access-controlled results
253
+
254
+ 4. GET /api/real-test/test-different-users
255
+ → Tests admin vs regular user access patterns
256
+
257
+ WHAT TO LOOK FOR:
258
+
259
+ ✅ Original query returns all users in database
260
+ ✅ Access controlled query only returns users with IDs in access list
261
+ ✅ Admin user gets more results than regular user
262
+ ✅ SQL IN clause is properly generated and executed
263
+ ✅ No errors or crashes
264
+
265
+ If you see SQL like:
266
+ SELECT * FROM users WHERE users.id IN ('1','2','3','4','5') LIMIT 10
267
+
268
+ Then our access control is working perfectly! 🎉
269
+ */
0 commit comments