@lenne.tech/nest-server 11.35.0 → 11.35.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.
- package/.claude/rules/configurable-features.md +1 -1
- package/FRAMEWORK-API.md +1 -1
- package/dist/core/common/helpers/file.helper.js +3 -2
- package/dist/core/common/helpers/file.helper.js.map +1 -1
- package/dist/core/modules/file/core-file-access-audit.initializer.d.ts +13 -0
- package/dist/core/modules/file/core-file-access-audit.initializer.js +109 -0
- package/dist/core/modules/file/core-file-access-audit.initializer.js.map +1 -0
- package/dist/core/modules/file/file-roles.config.d.ts +21 -0
- package/dist/core/modules/file/file-roles.config.js +51 -2
- package/dist/core/modules/file/file-roles.config.js.map +1 -1
- package/dist/core/modules/file/file-roles.helper.d.ts +2 -2
- package/dist/core/modules/file/file-roles.helper.js +10 -16
- package/dist/core/modules/file/file-roles.helper.js.map +1 -1
- package/dist/core.module.js +3 -1
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/migration-guides/11.34.x-to-11.35.x.md +17 -3
- package/migration-guides/11.35.0-to-11.35.1.md +152 -0
- package/package.json +1 -1
- package/src/core/common/helpers/file.helper.ts +11 -5
- package/src/core/modules/file/README.md +10 -0
- package/src/core/modules/file/core-file-access-audit.initializer.ts +164 -0
- package/src/core/modules/file/file-roles.config.ts +156 -1
- package/src/core/modules/file/file-roles.helper.ts +15 -22
- package/src/core.module.ts +10 -2
- package/src/index.ts +4 -0
|
@@ -3,7 +3,7 @@ import { Logger } from '@nestjs/common';
|
|
|
3
3
|
import { IFileConfig } from '../../common/interfaces/server-options.interface';
|
|
4
4
|
import { CoreFileController } from './core-file.controller';
|
|
5
5
|
import { CoreFileResolver } from './core-file.resolver';
|
|
6
|
-
import { FileRoleKey, resolveRoles } from './file-roles.config';
|
|
6
|
+
import { FILE_ROLE_MEMBERS, FileEndpointClassName, FileRoleKey, resolveRoles } from './file-roles.config';
|
|
7
7
|
|
|
8
8
|
const logger = new Logger('CoreFileRoles');
|
|
9
9
|
|
|
@@ -12,32 +12,25 @@ const logger = new Logger('CoreFileRoles');
|
|
|
12
12
|
// imports the endpoint classes, which inject CoreFileService — see file-roles.config.ts.
|
|
13
13
|
export {
|
|
14
14
|
FILE_ROLE_DEFAULTS,
|
|
15
|
+
FILE_ROLE_MEMBERS,
|
|
15
16
|
resolveRoles,
|
|
16
17
|
warnOnPresignedDownloadsWithRestrictedRoles,
|
|
18
|
+
warnOnUndecidedEffectiveFileAccess,
|
|
17
19
|
warnOnUndecidedFileAccess,
|
|
18
20
|
} from './file-roles.config';
|
|
19
|
-
export type { FileRoleKey } from './file-roles.config';
|
|
21
|
+
export type { FileEndpointClassName, FileRoleKey, ObservedFileHandler } from './file-roles.config';
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
|
-
*
|
|
24
|
+
* The prototypes the member names in {@link FILE_ROLE_MEMBERS} resolve against.
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* bucket's contents list while believing downloads were still closed.
|
|
26
|
+
* The NAMES live in `file-roles.config.ts` so the boot audit can share them without importing these
|
|
27
|
+
* classes (that import is what makes this file a non-leaf — see the header of `file-roles.config.ts`
|
|
28
|
+
* for the temporal-dead-zone crash it caused). Only the class lookup lives here.
|
|
28
29
|
*/
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
owner: () => CoreFileController.prototype.getFileById,
|
|
34
|
-
},
|
|
35
|
-
{ key: 'downloadRoles', member: 'CoreFileController.getFile', owner: () => CoreFileController.prototype.getFile },
|
|
36
|
-
{ key: 'downloadRoles', member: 'CoreFileResolver.getFileInfo', owner: () => CoreFileResolver.prototype.getFileInfo },
|
|
37
|
-
{ key: 'uploadRoles', member: 'CoreFileResolver.uploadFile', owner: () => CoreFileResolver.prototype.uploadFile },
|
|
38
|
-
{ key: 'uploadRoles', member: 'CoreFileResolver.uploadFiles', owner: () => CoreFileResolver.prototype.uploadFiles },
|
|
39
|
-
{ key: 'deleteRoles', member: 'CoreFileResolver.deleteFile', owner: () => CoreFileResolver.prototype.deleteFile },
|
|
40
|
-
];
|
|
30
|
+
const ENDPOINT_PROTOTYPES: Record<FileEndpointClassName, unknown> = {
|
|
31
|
+
CoreFileController: CoreFileController.prototype,
|
|
32
|
+
CoreFileResolver: CoreFileResolver.prototype,
|
|
33
|
+
};
|
|
41
34
|
|
|
42
35
|
/**
|
|
43
36
|
* Apply the configured file roles to the core file endpoints.
|
|
@@ -65,14 +58,14 @@ const ROLE_TARGETS: { key: FileRoleKey; member: string; owner: () => unknown }[]
|
|
|
65
58
|
export function applyFileRoles(config?: IFileConfig): void {
|
|
66
59
|
const resolved = new Map<FileRoleKey, string[]>();
|
|
67
60
|
|
|
68
|
-
for (const {
|
|
61
|
+
for (const { className, key, method } of FILE_ROLE_MEMBERS) {
|
|
69
62
|
if (!resolved.has(key)) {
|
|
70
63
|
resolved.set(key, resolveRoles(key, config));
|
|
71
64
|
}
|
|
72
65
|
|
|
73
|
-
const target =
|
|
66
|
+
const target = (ENDPOINT_PROTOTYPES[className] as Record<string, unknown>)[method];
|
|
74
67
|
if (typeof target !== 'function') {
|
|
75
|
-
logger.warn(`Cannot apply file.${key}: ${
|
|
68
|
+
logger.warn(`Cannot apply file.${key}: ${className}.${method} is not a function — skipping.`);
|
|
76
69
|
continue;
|
|
77
70
|
}
|
|
78
71
|
|
package/src/core.module.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
|
|
2
2
|
import { DynamicModule, Global, MiddlewareConsumer, Module, NestModule, UnauthorizedException } from '@nestjs/common';
|
|
3
|
-
import { APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core';
|
|
3
|
+
import { APP_INTERCEPTOR, APP_PIPE, DiscoveryModule } from '@nestjs/core';
|
|
4
4
|
import { GraphQLModule } from '@nestjs/graphql';
|
|
5
5
|
import { MongooseModule } from '@nestjs/mongoose';
|
|
6
6
|
import type { Context } from 'graphql-ws';
|
|
@@ -51,6 +51,7 @@ import { CoreBetterAuthUserMapper } from './core/modules/better-auth/core-better
|
|
|
51
51
|
import { CoreBetterAuthModule } from './core/modules/better-auth/core-better-auth.module';
|
|
52
52
|
import { CoreBetterAuthService } from './core/modules/better-auth/core-better-auth.service';
|
|
53
53
|
import { ErrorCodeModule } from './core/modules/error-code/error-code.module';
|
|
54
|
+
import { CoreFileAccessAuditInitializer } from './core/modules/file/core-file-access-audit.initializer';
|
|
54
55
|
import { applyFileRoles, warnOnPresignedDownloadsWithRestrictedRoles } from './core/modules/file/file-roles.helper';
|
|
55
56
|
import { CoreHealthCheckModule } from './core/modules/health-check/core-health-check.module';
|
|
56
57
|
import { CoreHubModule } from './core/modules/hub/core-hub.module';
|
|
@@ -305,6 +306,11 @@ export class CoreModule implements NestModule {
|
|
|
305
306
|
|
|
306
307
|
// Core Services
|
|
307
308
|
CoreCronJobsInitializer,
|
|
309
|
+
// Audits the file endpoints the project actually REGISTERED. applyFileRoles() above can only
|
|
310
|
+
// reach the base-class members; a subclass that re-declares one keeps its own @Roles() and the
|
|
311
|
+
// configuration never reaches that route. Only a bootstrap-time look at the registered class
|
|
312
|
+
// can tell those apart — see the initializer.
|
|
313
|
+
CoreFileAccessAuditInitializer,
|
|
308
314
|
CoreRedisService,
|
|
309
315
|
CoreS3Service,
|
|
310
316
|
CoreTrustProxyInitializer,
|
|
@@ -381,7 +387,9 @@ export class CoreModule implements NestModule {
|
|
|
381
387
|
}
|
|
382
388
|
}
|
|
383
389
|
|
|
384
|
-
|
|
390
|
+
// DiscoveryModule: CoreFileAccessAuditInitializer needs the registered controller/resolver
|
|
391
|
+
// classes, which only exist once Nest has built its route table.
|
|
392
|
+
const imports: any[] = [DiscoveryModule, MongooseModule.forRoot(config.mongoose.uri, config.mongoose.options)];
|
|
385
393
|
|
|
386
394
|
if (isGraphQlEnabled && config.graphQl) {
|
|
387
395
|
imports.push(
|
package/src/index.ts
CHANGED
|
@@ -36,9 +36,11 @@ export * from './core/common/helpers/cookies.helper';
|
|
|
36
36
|
export * from './core/common/helpers/graceful-shutdown.helper';
|
|
37
37
|
export * from './core/common/helpers/db.helper';
|
|
38
38
|
export * from './core/common/helpers/decorator.helper';
|
|
39
|
+
export * from './core/common/helpers/execution-context-request.helper';
|
|
39
40
|
export * from './core/common/helpers/file.helper';
|
|
40
41
|
export * from './core/common/helpers/filter.helper';
|
|
41
42
|
export * from './core/common/helpers/graphql.helper';
|
|
43
|
+
export * from './core/common/helpers/graphql-ws-context.helper';
|
|
42
44
|
export * from './core/common/helpers/interceptor.helper';
|
|
43
45
|
export * from './core/common/helpers/gridfs.helper';
|
|
44
46
|
export * from './core/common/helpers/input.helper';
|
|
@@ -94,6 +96,7 @@ export * from './core/common/services/core-cron-jobs.service';
|
|
|
94
96
|
export * from './core/common/services/core-redis.service';
|
|
95
97
|
export * from './core/common/services/core-redis-pubsub';
|
|
96
98
|
export * from './core/common/services/core-s3.service';
|
|
99
|
+
export * from './core/common/services/core-tenant-context.registry';
|
|
97
100
|
export * from './core/common/services/rate-limit-store';
|
|
98
101
|
export * from './core/common/services/crud.service';
|
|
99
102
|
export * from './core/common/services/email.service';
|
|
@@ -173,6 +176,7 @@ export * from './core/modules/error-code';
|
|
|
173
176
|
// Core - Modules - File
|
|
174
177
|
// =====================================================================================================================
|
|
175
178
|
|
|
179
|
+
export * from './core/modules/file/core-file-access-audit.initializer';
|
|
176
180
|
export * from './core/modules/file/core-file-info.model';
|
|
177
181
|
export * from './core/modules/file/core-file.controller';
|
|
178
182
|
export * from './core/modules/file/core-file.resolver';
|