@lenne.tech/nest-server 11.21.1 → 11.21.3
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/dist/core/common/interfaces/server-options.interface.d.ts +1 -0
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +25 -25
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.js +8 -4
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.guard.d.ts +3 -0
- package/dist/core/modules/tenant/core-tenant.guard.js +102 -10
- package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.helpers.js.map +1 -1
- package/dist/test/test.helper.d.ts +6 -2
- package/dist/test/test.helper.js +28 -6
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -8
- package/src/core/common/interfaces/server-options.interface.ts +26 -0
- package/src/core/modules/better-auth/README.md +20 -1
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +29 -25
- package/src/core/modules/better-auth/core-better-auth.service.ts +13 -9
- package/src/core/modules/tenant/INTEGRATION-CHECKLIST.md +32 -2
- package/src/core/modules/tenant/README.md +59 -1
- package/src/core/modules/tenant/core-tenant.guard.ts +223 -16
- package/src/core/modules/tenant/core-tenant.helpers.ts +6 -2
- package/src/test/README.md +47 -0
- package/src/test/test.helper.ts +55 -6
|
@@ -5,7 +5,10 @@ const SYSTEM_ROLE_PREFIX = 's_';
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Merge handler-level and class-level @Roles() metadata arrays into a single flat array.
|
|
8
|
-
* Used by RolesGuard, BetterAuthRolesGuard, and CoreTenantGuard
|
|
8
|
+
* Used by RolesGuard, BetterAuthRolesGuard, and CoreTenantGuard.
|
|
9
|
+
*
|
|
10
|
+
* OR semantics: class-level roles serve as a base that method-level roles extend.
|
|
11
|
+
* Example: class @Roles(ADMIN) + method @Roles(S_USER) → [S_USER, ADMIN] — both are alternatives.
|
|
9
12
|
*
|
|
10
13
|
* @param meta - Two-element tuple [handlerRoles, classRoles] from Reflector.getAll or Reflect.getMetadata
|
|
11
14
|
*/
|
|
@@ -22,7 +25,8 @@ export function getRoleHierarchy(): Record<string, number> {
|
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* Check if a role is a system role (S_USER, S_EVERYONE, etc.).
|
|
25
|
-
* System roles are
|
|
28
|
+
* System roles are checked by RolesGuard/BetterAuthRolesGuard for authentication
|
|
29
|
+
* and by CoreTenantGuard as OR alternatives before real role checks.
|
|
26
30
|
*/
|
|
27
31
|
export function isSystemRole(role: string): boolean {
|
|
28
32
|
return role.startsWith(SYSTEM_ROLE_PREFIX);
|
package/src/test/README.md
CHANGED
|
@@ -174,6 +174,53 @@ await testHelper.rest('/protected-endpoint', {
|
|
|
174
174
|
});
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
+
## File Download Testing (`testHelper.download()` / `testHelper.downloadBuffer()`)
|
|
178
|
+
|
|
179
|
+
### `download(url, tokenOrOptions?)`
|
|
180
|
+
|
|
181
|
+
Download a file and return the response with a `data` string property for content comparison.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// No authentication
|
|
185
|
+
const res = await testHelper.download('/files/id/abc123');
|
|
186
|
+
expect(res.statusCode).toEqual(200);
|
|
187
|
+
expect(res.data).toEqual('file content');
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### `downloadBuffer(url, tokenOrOptions?)`
|
|
191
|
+
|
|
192
|
+
Download a file and return a `Buffer` for binary comparison or saving.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const buffer = await testHelper.downloadBuffer('/files/id/abc123', jwtToken);
|
|
196
|
+
await fs.promises.writeFile('/tmp/downloaded.bin', buffer);
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### TestDownloadOptions
|
|
200
|
+
|
|
201
|
+
The second parameter accepts either a plain token string or a `TestDownloadOptions` object:
|
|
202
|
+
|
|
203
|
+
| Option | Type | Description |
|
|
204
|
+
| --------- | -------- | ------------------------------------------------------------- |
|
|
205
|
+
| `token` | `string` | Bearer token via Authorization header (JWT) |
|
|
206
|
+
| `cookies` | `string` | Plain session token, converted via `buildBetterAuthCookies()` |
|
|
207
|
+
|
|
208
|
+
Both can be used simultaneously — `token` sets the Authorization header while `cookies` sets the Cookie header.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
// String form (backward compatible) — sets Authorization: bearer <token>
|
|
212
|
+
await testHelper.download('/files/id/abc123', jwtToken);
|
|
213
|
+
|
|
214
|
+
// Options object with JWT token
|
|
215
|
+
await testHelper.download('/files/id/abc123', { token: jwtToken });
|
|
216
|
+
|
|
217
|
+
// Options object with cookie-based session auth
|
|
218
|
+
await testHelper.download('/files/id/abc123', { cookies: sessionToken });
|
|
219
|
+
|
|
220
|
+
// Both simultaneously
|
|
221
|
+
await testHelper.download('/files/id/abc123', { cookies: sessionToken, token: jwtToken });
|
|
222
|
+
```
|
|
223
|
+
|
|
177
224
|
## GraphQL Testing (`testHelper.graphQl()`)
|
|
178
225
|
|
|
179
226
|
```typescript
|
package/src/test/test.helper.ts
CHANGED
|
@@ -154,6 +154,25 @@ export interface TestRestOptions {
|
|
|
154
154
|
token?: string;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Options for download/downloadBuffer requests
|
|
159
|
+
*/
|
|
160
|
+
export interface TestDownloadOptions {
|
|
161
|
+
/**
|
|
162
|
+
* Cookie-based authentication. Pass a plain session token string
|
|
163
|
+
* which is converted via buildBetterAuthCookies() to all relevant cookie names
|
|
164
|
+
* (iam.session_token, token).
|
|
165
|
+
*/
|
|
166
|
+
cookies?: string;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Bearer token via Authorization header (JWT authentication).
|
|
170
|
+
* Can be used simultaneously with `cookies` — token sets the Authorization header
|
|
171
|
+
* while cookies sets the Cookie header.
|
|
172
|
+
*/
|
|
173
|
+
token?: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
157
176
|
/**
|
|
158
177
|
* Test helper
|
|
159
178
|
*/
|
|
@@ -176,13 +195,28 @@ export class TestHelper {
|
|
|
176
195
|
/**
|
|
177
196
|
* Download file from URL
|
|
178
197
|
* To compare content data via string comparison
|
|
198
|
+
* @param url - URL to download from
|
|
199
|
+
* @param tokenOrOptions - Bearer token string, or {@link TestDownloadOptions} with `cookies` and/or `token`
|
|
179
200
|
* @return Superagent response with additional data field containing the content of the file
|
|
180
201
|
*/
|
|
181
|
-
download(url: string,
|
|
202
|
+
download(url: string, tokenOrOptions?: string | TestDownloadOptions): Promise<any> {
|
|
182
203
|
return new Promise((resolve, reject) => {
|
|
183
204
|
const request = supertest((this.app as INestApplication).getHttpServer()).get(url);
|
|
184
|
-
if (
|
|
185
|
-
request.set('Authorization', `bearer ${
|
|
205
|
+
if (typeof tokenOrOptions === 'string') {
|
|
206
|
+
request.set('Authorization', `bearer ${tokenOrOptions}`);
|
|
207
|
+
} else if (tokenOrOptions) {
|
|
208
|
+
if (tokenOrOptions.cookies) {
|
|
209
|
+
const cookieRecord = TestHelper.buildBetterAuthCookies(tokenOrOptions.cookies);
|
|
210
|
+
request.set(
|
|
211
|
+
'Cookie',
|
|
212
|
+
Object.entries(cookieRecord)
|
|
213
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
|
|
214
|
+
.join('; '),
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
if (tokenOrOptions.token) {
|
|
218
|
+
request.set('Authorization', `bearer ${tokenOrOptions.token}`);
|
|
219
|
+
}
|
|
186
220
|
}
|
|
187
221
|
let data = '';
|
|
188
222
|
request
|
|
@@ -207,12 +241,27 @@ export class TestHelper {
|
|
|
207
241
|
/**
|
|
208
242
|
* Download file from URL and get buffer
|
|
209
243
|
* To compare content data via buffer comparison and with the possibility to save the file
|
|
244
|
+
* @param url - URL to download from
|
|
245
|
+
* @param tokenOrOptions - Bearer token string, or {@link TestDownloadOptions} with `cookies` and/or `token`
|
|
210
246
|
*/
|
|
211
|
-
downloadBuffer(url: string,
|
|
247
|
+
downloadBuffer(url: string, tokenOrOptions?: string | TestDownloadOptions): Promise<Buffer> {
|
|
212
248
|
return new Promise((resolve, reject) => {
|
|
213
249
|
const request = supertest(this.app.getHttpServer()).get(url);
|
|
214
|
-
if (
|
|
215
|
-
request.set('Authorization', `bearer ${
|
|
250
|
+
if (typeof tokenOrOptions === 'string') {
|
|
251
|
+
request.set('Authorization', `bearer ${tokenOrOptions}`);
|
|
252
|
+
} else if (tokenOrOptions) {
|
|
253
|
+
if (tokenOrOptions.cookies) {
|
|
254
|
+
const cookieRecord = TestHelper.buildBetterAuthCookies(tokenOrOptions.cookies);
|
|
255
|
+
request.set(
|
|
256
|
+
'Cookie',
|
|
257
|
+
Object.entries(cookieRecord)
|
|
258
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
|
|
259
|
+
.join('; '),
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
if (tokenOrOptions.token) {
|
|
263
|
+
request.set('Authorization', `bearer ${tokenOrOptions.token}`);
|
|
264
|
+
}
|
|
216
265
|
}
|
|
217
266
|
|
|
218
267
|
// Array to store the data chunks
|