digitaltwin-core 0.14.3 → 1.0.0

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 (123) hide show
  1. package/README.md +135 -0
  2. package/dist/auth/apisix_parser.d.ts +46 -51
  3. package/dist/auth/apisix_parser.d.ts.map +1 -1
  4. package/dist/auth/apisix_parser.js +62 -86
  5. package/dist/auth/apisix_parser.js.map +1 -1
  6. package/dist/auth/auth_provider.d.ts +118 -0
  7. package/dist/auth/auth_provider.d.ts.map +1 -0
  8. package/dist/auth/auth_provider.js +8 -0
  9. package/dist/auth/auth_provider.js.map +1 -0
  10. package/dist/auth/auth_provider_factory.d.ts +91 -0
  11. package/dist/auth/auth_provider_factory.d.ts.map +1 -0
  12. package/dist/auth/auth_provider_factory.js +146 -0
  13. package/dist/auth/auth_provider_factory.js.map +1 -0
  14. package/dist/auth/index.d.ts +3 -0
  15. package/dist/auth/index.d.ts.map +1 -1
  16. package/dist/auth/index.js +3 -0
  17. package/dist/auth/index.js.map +1 -1
  18. package/dist/auth/providers/gateway_auth_provider.d.ts +78 -0
  19. package/dist/auth/providers/gateway_auth_provider.d.ts.map +1 -0
  20. package/dist/auth/providers/gateway_auth_provider.js +109 -0
  21. package/dist/auth/providers/gateway_auth_provider.js.map +1 -0
  22. package/dist/auth/providers/index.d.ts +4 -0
  23. package/dist/auth/providers/index.d.ts.map +1 -0
  24. package/dist/auth/providers/index.js +4 -0
  25. package/dist/auth/providers/index.js.map +1 -0
  26. package/dist/auth/providers/jwt_auth_provider.d.ts +91 -0
  27. package/dist/auth/providers/jwt_auth_provider.d.ts.map +1 -0
  28. package/dist/auth/providers/jwt_auth_provider.js +204 -0
  29. package/dist/auth/providers/jwt_auth_provider.js.map +1 -0
  30. package/dist/auth/providers/no_auth_provider.d.ts +61 -0
  31. package/dist/auth/providers/no_auth_provider.d.ts.map +1 -0
  32. package/dist/auth/providers/no_auth_provider.js +76 -0
  33. package/dist/auth/providers/no_auth_provider.js.map +1 -0
  34. package/dist/components/assets_manager.d.ts +1 -1
  35. package/dist/components/assets_manager.d.ts.map +1 -1
  36. package/dist/components/assets_manager.js +52 -44
  37. package/dist/components/assets_manager.js.map +1 -1
  38. package/dist/components/collector.d.ts.map +1 -1
  39. package/dist/components/collector.js +30 -18
  40. package/dist/components/collector.js.map +1 -1
  41. package/dist/components/custom_table_manager.d.ts.map +1 -1
  42. package/dist/components/custom_table_manager.js +36 -65
  43. package/dist/components/custom_table_manager.js.map +1 -1
  44. package/dist/components/harvester.d.ts.map +1 -1
  45. package/dist/components/harvester.js +46 -33
  46. package/dist/components/harvester.js.map +1 -1
  47. package/dist/components/tileset_manager.d.ts.map +1 -1
  48. package/dist/components/tileset_manager.js +20 -15
  49. package/dist/components/tileset_manager.js.map +1 -1
  50. package/dist/database/adapters/knex_database_adapter.d.ts +5 -0
  51. package/dist/database/adapters/knex_database_adapter.d.ts.map +1 -1
  52. package/dist/database/adapters/knex_database_adapter.js +116 -34
  53. package/dist/database/adapters/knex_database_adapter.js.map +1 -1
  54. package/dist/database/database_adapter.d.ts +11 -0
  55. package/dist/database/database_adapter.d.ts.map +1 -1
  56. package/dist/database/database_adapter.js.map +1 -1
  57. package/dist/engine/digital_twin_engine.d.ts +48 -6
  58. package/dist/engine/digital_twin_engine.d.ts.map +1 -1
  59. package/dist/engine/digital_twin_engine.js +175 -48
  60. package/dist/engine/digital_twin_engine.js.map +1 -1
  61. package/dist/engine/endpoints.d.ts.map +1 -1
  62. package/dist/engine/endpoints.js +35 -3
  63. package/dist/engine/endpoints.js.map +1 -1
  64. package/dist/engine/error_handler.d.ts +20 -0
  65. package/dist/engine/error_handler.d.ts.map +1 -0
  66. package/dist/engine/error_handler.js +69 -0
  67. package/dist/engine/error_handler.js.map +1 -0
  68. package/dist/engine/health.d.ts +112 -0
  69. package/dist/engine/health.d.ts.map +1 -0
  70. package/dist/engine/health.js +190 -0
  71. package/dist/engine/health.js.map +1 -0
  72. package/dist/engine/scheduler.d.ts.map +1 -1
  73. package/dist/engine/scheduler.js +9 -1
  74. package/dist/engine/scheduler.js.map +1 -1
  75. package/dist/engine/upload_processor.d.ts.map +1 -1
  76. package/dist/engine/upload_processor.js +24 -12
  77. package/dist/engine/upload_processor.js.map +1 -1
  78. package/dist/errors/index.d.ts +94 -0
  79. package/dist/errors/index.d.ts.map +1 -0
  80. package/dist/errors/index.js +149 -0
  81. package/dist/errors/index.js.map +1 -0
  82. package/dist/index.d.ts +6 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +8 -0
  85. package/dist/index.js.map +1 -1
  86. package/dist/storage/adapters/local_storage_service.d.ts +6 -0
  87. package/dist/storage/adapters/local_storage_service.d.ts.map +1 -1
  88. package/dist/storage/adapters/local_storage_service.js +26 -4
  89. package/dist/storage/adapters/local_storage_service.js.map +1 -1
  90. package/dist/storage/adapters/ovh_storage_service.d.ts.map +1 -1
  91. package/dist/storage/adapters/ovh_storage_service.js +5 -6
  92. package/dist/storage/adapters/ovh_storage_service.js.map +1 -1
  93. package/dist/storage/storage_factory.d.ts.map +1 -1
  94. package/dist/storage/storage_factory.js +4 -1
  95. package/dist/storage/storage_factory.js.map +1 -1
  96. package/dist/storage/storage_service.d.ts.map +1 -1
  97. package/dist/storage/storage_service.js +6 -2
  98. package/dist/storage/storage_service.js.map +1 -1
  99. package/dist/utils/graceful_shutdown.d.ts +44 -0
  100. package/dist/utils/graceful_shutdown.d.ts.map +1 -0
  101. package/dist/utils/graceful_shutdown.js +79 -0
  102. package/dist/utils/graceful_shutdown.js.map +1 -0
  103. package/dist/utils/http_responses.d.ts +20 -0
  104. package/dist/utils/http_responses.d.ts.map +1 -1
  105. package/dist/utils/http_responses.js +28 -2
  106. package/dist/utils/http_responses.js.map +1 -1
  107. package/dist/utils/safe_async.d.ts +50 -0
  108. package/dist/utils/safe_async.d.ts.map +1 -0
  109. package/dist/utils/safe_async.js +90 -0
  110. package/dist/utils/safe_async.js.map +1 -0
  111. package/dist/validation/index.d.ts +3 -0
  112. package/dist/validation/index.d.ts.map +1 -0
  113. package/dist/validation/index.js +7 -0
  114. package/dist/validation/index.js.map +1 -0
  115. package/dist/validation/schemas.d.ts +273 -0
  116. package/dist/validation/schemas.d.ts.map +1 -0
  117. package/dist/validation/schemas.js +82 -0
  118. package/dist/validation/schemas.js.map +1 -0
  119. package/dist/validation/validate.d.ts +49 -0
  120. package/dist/validation/validate.d.ts.map +1 -0
  121. package/dist/validation/validate.js +110 -0
  122. package/dist/validation/validate.js.map +1 -0
  123. package/package.json +9 -1
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @fileoverview JWT authentication provider for direct token validation.
3
+ *
4
+ * This provider validates JWT tokens from the Authorization header without
5
+ * requiring an API gateway. Useful for standalone deployments or when you
6
+ * want to handle authentication directly in the application.
7
+ *
8
+ * Supports:
9
+ * - HMAC algorithms (HS256, HS384, HS512) with a secret key
10
+ * - RSA algorithms (RS256, RS384, RS512) with a public key
11
+ * - EC algorithms (ES256, ES384, ES512) with a public key
12
+ * - Keycloak token format (realm_access.roles)
13
+ * - Custom claim paths for user ID and roles
14
+ */
15
+ import type { AuthProvider, AuthRequest, AuthProviderConfig } from '../auth_provider.js';
16
+ import type { AuthenticatedUser } from '../types.js';
17
+ /**
18
+ * Authentication provider for JWT token validation.
19
+ *
20
+ * This provider validates JWT tokens directly in the application, without
21
+ * requiring an API gateway. It extracts user information from token claims.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // With HMAC secret
26
+ * const provider = new JwtAuthProvider({
27
+ * mode: 'jwt',
28
+ * jwt: {
29
+ * secret: 'your-256-bit-secret',
30
+ * algorithm: 'HS256'
31
+ * }
32
+ * })
33
+ *
34
+ * // With RSA public key (Keycloak)
35
+ * const provider = new JwtAuthProvider({
36
+ * mode: 'jwt',
37
+ * jwt: {
38
+ * publicKey: fs.readFileSync('public.pem', 'utf-8'),
39
+ * algorithm: 'RS256',
40
+ * issuer: 'https://keycloak.example.com/realms/myrealm',
41
+ * rolesClaim: 'realm_access.roles'
42
+ * }
43
+ * })
44
+ * ```
45
+ */
46
+ export declare class JwtAuthProvider implements AuthProvider {
47
+ #private;
48
+ /**
49
+ * Creates a new JwtAuthProvider.
50
+ *
51
+ * @param config - Authentication configuration with JWT settings
52
+ * @throws Error if JWT configuration is missing or incomplete
53
+ */
54
+ constructor(config: AuthProviderConfig);
55
+ /**
56
+ * Parse the request and validate the JWT token.
57
+ *
58
+ * @param req - Request object with headers
59
+ * @returns Authenticated user, or null if token is missing/invalid
60
+ */
61
+ parseRequest(req: AuthRequest): AuthenticatedUser | null;
62
+ /**
63
+ * Check if the request has a valid Authorization header with Bearer token.
64
+ *
65
+ * @param req - Request object with headers
66
+ * @returns true if Authorization header is present with Bearer scheme
67
+ */
68
+ hasValidAuth(req: AuthRequest): boolean;
69
+ /**
70
+ * Check if the authenticated user has admin privileges.
71
+ *
72
+ * @param req - Request object with headers
73
+ * @returns true if the user has the admin role
74
+ */
75
+ isAdmin(req: AuthRequest): boolean;
76
+ /**
77
+ * Get the user ID from the JWT token.
78
+ *
79
+ * @param req - Request object with headers
80
+ * @returns User ID, or null if not authenticated
81
+ */
82
+ getUserId(req: AuthRequest): string | null;
83
+ /**
84
+ * Get the user roles from the JWT token.
85
+ *
86
+ * @param req - Request object with headers
87
+ * @returns Array of role names, empty array if not authenticated
88
+ */
89
+ getUserRoles(req: AuthRequest): string[];
90
+ }
91
+ //# sourceMappingURL=jwt_auth_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt_auth_provider.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/jwt_auth_provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,eAAgB,YAAW,YAAY;;IAShD;;;;;OAKG;gBACS,MAAM,EAAE,kBAAkB;IAwBtC;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB,GAAG,IAAI;IAuBxD;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO;IAIvC;;;;;OAKG;IACH,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO;IAKlC;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAK1C;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,EAAE;CAkE3C"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * @fileoverview JWT authentication provider for direct token validation.
3
+ *
4
+ * This provider validates JWT tokens from the Authorization header without
5
+ * requiring an API gateway. Useful for standalone deployments or when you
6
+ * want to handle authentication directly in the application.
7
+ *
8
+ * Supports:
9
+ * - HMAC algorithms (HS256, HS384, HS512) with a secret key
10
+ * - RSA algorithms (RS256, RS384, RS512) with a public key
11
+ * - EC algorithms (ES256, ES384, ES512) with a public key
12
+ * - Keycloak token format (realm_access.roles)
13
+ * - Custom claim paths for user ID and roles
14
+ */
15
+ import jwt from 'jsonwebtoken';
16
+ /**
17
+ * Authentication provider for JWT token validation.
18
+ *
19
+ * This provider validates JWT tokens directly in the application, without
20
+ * requiring an API gateway. It extracts user information from token claims.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // With HMAC secret
25
+ * const provider = new JwtAuthProvider({
26
+ * mode: 'jwt',
27
+ * jwt: {
28
+ * secret: 'your-256-bit-secret',
29
+ * algorithm: 'HS256'
30
+ * }
31
+ * })
32
+ *
33
+ * // With RSA public key (Keycloak)
34
+ * const provider = new JwtAuthProvider({
35
+ * mode: 'jwt',
36
+ * jwt: {
37
+ * publicKey: fs.readFileSync('public.pem', 'utf-8'),
38
+ * algorithm: 'RS256',
39
+ * issuer: 'https://keycloak.example.com/realms/myrealm',
40
+ * rolesClaim: 'realm_access.roles'
41
+ * }
42
+ * })
43
+ * ```
44
+ */
45
+ export class JwtAuthProvider {
46
+ #secret;
47
+ #algorithm;
48
+ #issuer;
49
+ #audience;
50
+ #userIdClaim;
51
+ #rolesClaim;
52
+ #adminRoleName;
53
+ /**
54
+ * Creates a new JwtAuthProvider.
55
+ *
56
+ * @param config - Authentication configuration with JWT settings
57
+ * @throws Error if JWT configuration is missing or incomplete
58
+ */
59
+ constructor(config) {
60
+ if (!config.jwt) {
61
+ throw new Error('JWT configuration required for JWT auth mode');
62
+ }
63
+ const { jwt: jwtConfig } = config;
64
+ // Secret or public key
65
+ if (jwtConfig.publicKey) {
66
+ this.#secret = jwtConfig.publicKey;
67
+ }
68
+ else if (jwtConfig.secret) {
69
+ this.#secret = jwtConfig.secret;
70
+ }
71
+ else {
72
+ throw new Error('JWT secret or publicKey required');
73
+ }
74
+ this.#algorithm = jwtConfig.algorithm || 'HS256';
75
+ this.#issuer = jwtConfig.issuer;
76
+ this.#audience = jwtConfig.audience;
77
+ this.#userIdClaim = jwtConfig.userIdClaim || 'sub';
78
+ this.#rolesClaim = jwtConfig.rolesClaim || 'roles';
79
+ this.#adminRoleName = config.adminRoleName || 'admin';
80
+ }
81
+ /**
82
+ * Parse the request and validate the JWT token.
83
+ *
84
+ * @param req - Request object with headers
85
+ * @returns Authenticated user, or null if token is missing/invalid
86
+ */
87
+ parseRequest(req) {
88
+ const token = this.#extractToken(req);
89
+ if (!token)
90
+ return null;
91
+ try {
92
+ const decoded = jwt.verify(token, this.#secret, {
93
+ algorithms: [this.#algorithm],
94
+ issuer: this.#issuer,
95
+ audience: this.#audience
96
+ });
97
+ const userId = this.#extractClaim(decoded, this.#userIdClaim);
98
+ if (!userId || typeof userId !== 'string')
99
+ return null;
100
+ const roles = this.#extractRoles(decoded);
101
+ return { id: userId, roles };
102
+ }
103
+ catch {
104
+ // Token invalid or expired
105
+ return null;
106
+ }
107
+ }
108
+ /**
109
+ * Check if the request has a valid Authorization header with Bearer token.
110
+ *
111
+ * @param req - Request object with headers
112
+ * @returns true if Authorization header is present with Bearer scheme
113
+ */
114
+ hasValidAuth(req) {
115
+ return !!this.#extractToken(req);
116
+ }
117
+ /**
118
+ * Check if the authenticated user has admin privileges.
119
+ *
120
+ * @param req - Request object with headers
121
+ * @returns true if the user has the admin role
122
+ */
123
+ isAdmin(req) {
124
+ const user = this.parseRequest(req);
125
+ return user?.roles.includes(this.#adminRoleName) ?? false;
126
+ }
127
+ /**
128
+ * Get the user ID from the JWT token.
129
+ *
130
+ * @param req - Request object with headers
131
+ * @returns User ID, or null if not authenticated
132
+ */
133
+ getUserId(req) {
134
+ const user = this.parseRequest(req);
135
+ return user?.id ?? null;
136
+ }
137
+ /**
138
+ * Get the user roles from the JWT token.
139
+ *
140
+ * @param req - Request object with headers
141
+ * @returns Array of role names, empty array if not authenticated
142
+ */
143
+ getUserRoles(req) {
144
+ const user = this.parseRequest(req);
145
+ return user?.roles ?? [];
146
+ }
147
+ /**
148
+ * Extract the Bearer token from the Authorization header.
149
+ */
150
+ #extractToken(req) {
151
+ const authHeader = this.#getHeader(req.headers, 'authorization');
152
+ if (!authHeader)
153
+ return null;
154
+ // Format: "Bearer <token>"
155
+ const parts = authHeader.split(' ');
156
+ if (parts.length !== 2 || parts[0].toLowerCase() !== 'bearer') {
157
+ return null;
158
+ }
159
+ return parts[1];
160
+ }
161
+ /**
162
+ * Extract a claim value from the token payload.
163
+ * Supports nested paths like "realm_access.roles".
164
+ */
165
+ #extractClaim(payload, path) {
166
+ const parts = path.split('.');
167
+ let current = payload;
168
+ for (const part of parts) {
169
+ if (current === null || current === undefined)
170
+ return undefined;
171
+ if (typeof current !== 'object')
172
+ return undefined;
173
+ current = current[part];
174
+ }
175
+ return current;
176
+ }
177
+ /**
178
+ * Extract roles from the token payload.
179
+ * Supports standard array format and Keycloak's realm_access.roles.
180
+ */
181
+ #extractRoles(payload) {
182
+ // Try configured roles claim first
183
+ const roles = this.#extractClaim(payload, this.#rolesClaim);
184
+ if (Array.isArray(roles)) {
185
+ return roles.filter((r) => typeof r === 'string');
186
+ }
187
+ // Fallback to Keycloak format
188
+ const realmAccess = payload.realm_access;
189
+ if (realmAccess?.roles && Array.isArray(realmAccess.roles)) {
190
+ return realmAccess.roles;
191
+ }
192
+ return [];
193
+ }
194
+ /**
195
+ * Get a header value as a string.
196
+ */
197
+ #getHeader(headers, name) {
198
+ const value = headers[name];
199
+ if (!value)
200
+ return null;
201
+ return Array.isArray(value) ? value[0] : value;
202
+ }
203
+ }
204
+ //# sourceMappingURL=jwt_auth_provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt_auth_provider.js","sourceRoot":"","sources":["../../../src/auth/providers/jwt_auth_provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @fileoverview No-authentication provider for development and testing.
3
+ *
4
+ * This provider bypasses all authentication checks and returns a configurable
5
+ * anonymous user for all requests. Use only in development or testing environments.
6
+ *
7
+ * WARNING: Never use this provider in production!
8
+ */
9
+ import type { AuthProvider, AuthRequest } from '../auth_provider.js';
10
+ import type { AuthenticatedUser } from '../types.js';
11
+ /**
12
+ * Authentication provider that bypasses authentication.
13
+ *
14
+ * All requests are treated as authenticated with a configurable anonymous user.
15
+ * This provider is useful for development and testing when you don't want to
16
+ * set up authentication infrastructure.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Development setup
21
+ * const provider = new NoAuthProvider('dev-user-123')
22
+ *
23
+ * // All requests return the same user
24
+ * const user = provider.parseRequest(req) // { id: 'dev-user-123', roles: ['user'] }
25
+ * provider.hasValidAuth(req) // always true
26
+ * provider.isAdmin(req) // always false
27
+ * ```
28
+ */
29
+ export declare class NoAuthProvider implements AuthProvider {
30
+ #private;
31
+ /**
32
+ * Creates a new NoAuthProvider.
33
+ *
34
+ * @param anonymousUserId - User ID for the anonymous user (default: 'anonymous')
35
+ * @param anonymousRoles - Roles for the anonymous user (default: ['anonymous'])
36
+ */
37
+ constructor(anonymousUserId?: string, anonymousRoles?: string[]);
38
+ /**
39
+ * Returns the anonymous user for all requests.
40
+ *
41
+ * @returns Anonymous user with configured ID and roles
42
+ */
43
+ parseRequest(_req: AuthRequest): AuthenticatedUser | null;
44
+ /**
45
+ * Always returns true (all requests are "authenticated").
46
+ */
47
+ hasValidAuth(_req: AuthRequest): boolean;
48
+ /**
49
+ * Always returns false (anonymous user is never admin).
50
+ */
51
+ isAdmin(_req: AuthRequest): boolean;
52
+ /**
53
+ * Returns the anonymous user ID.
54
+ */
55
+ getUserId(_req: AuthRequest): string | null;
56
+ /**
57
+ * Returns the anonymous user roles.
58
+ */
59
+ getUserRoles(_req: AuthRequest): string[];
60
+ }
61
+ //# sourceMappingURL=no_auth_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no_auth_provider.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/no_auth_provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAe,YAAW,YAAY;;IAI/C;;;;;OAKG;gBACS,eAAe,SAAc,EAAE,cAAc,GAAE,MAAM,EAAkB;IAKnF;;;;OAIG;IACH,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,iBAAiB,GAAG,IAAI;IAOzD;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAIxC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAInC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAI3C;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE;CAG5C"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @fileoverview No-authentication provider for development and testing.
3
+ *
4
+ * This provider bypasses all authentication checks and returns a configurable
5
+ * anonymous user for all requests. Use only in development or testing environments.
6
+ *
7
+ * WARNING: Never use this provider in production!
8
+ */
9
+ /**
10
+ * Authentication provider that bypasses authentication.
11
+ *
12
+ * All requests are treated as authenticated with a configurable anonymous user.
13
+ * This provider is useful for development and testing when you don't want to
14
+ * set up authentication infrastructure.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * // Development setup
19
+ * const provider = new NoAuthProvider('dev-user-123')
20
+ *
21
+ * // All requests return the same user
22
+ * const user = provider.parseRequest(req) // { id: 'dev-user-123', roles: ['user'] }
23
+ * provider.hasValidAuth(req) // always true
24
+ * provider.isAdmin(req) // always false
25
+ * ```
26
+ */
27
+ export class NoAuthProvider {
28
+ #anonymousUserId;
29
+ #anonymousRoles;
30
+ /**
31
+ * Creates a new NoAuthProvider.
32
+ *
33
+ * @param anonymousUserId - User ID for the anonymous user (default: 'anonymous')
34
+ * @param anonymousRoles - Roles for the anonymous user (default: ['anonymous'])
35
+ */
36
+ constructor(anonymousUserId = 'anonymous', anonymousRoles = ['anonymous']) {
37
+ this.#anonymousUserId = anonymousUserId;
38
+ this.#anonymousRoles = anonymousRoles;
39
+ }
40
+ /**
41
+ * Returns the anonymous user for all requests.
42
+ *
43
+ * @returns Anonymous user with configured ID and roles
44
+ */
45
+ parseRequest(_req) {
46
+ return {
47
+ id: this.#anonymousUserId,
48
+ roles: this.#anonymousRoles
49
+ };
50
+ }
51
+ /**
52
+ * Always returns true (all requests are "authenticated").
53
+ */
54
+ hasValidAuth(_req) {
55
+ return true;
56
+ }
57
+ /**
58
+ * Always returns false (anonymous user is never admin).
59
+ */
60
+ isAdmin(_req) {
61
+ return false;
62
+ }
63
+ /**
64
+ * Returns the anonymous user ID.
65
+ */
66
+ getUserId(_req) {
67
+ return this.#anonymousUserId;
68
+ }
69
+ /**
70
+ * Returns the anonymous user roles.
71
+ */
72
+ getUserRoles(_req) {
73
+ return this.#anonymousRoles;
74
+ }
75
+ }
76
+ //# sourceMappingURL=no_auth_provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no_auth_provider.js","sourceRoot":"","sources":["../../../src/auth/providers/no_auth_provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,cAAc;IACd,gBAAgB,CAAQ;IACxB,eAAe,CAAU;IAElC;;;;;OAKG;IACH,YAAY,eAAe,GAAG,WAAW,EAAE,iBAA2B,CAAC,WAAW,CAAC;QAC/E,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAA;QACvC,IAAI,CAAC,eAAe,GAAG,cAAc,CAAA;IACzC,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,IAAiB;QAC1B,OAAO;YACH,EAAE,EAAE,IAAI,CAAC,gBAAgB;YACzB,KAAK,EAAE,IAAI,CAAC,eAAe;SAC9B,CAAA;IACL,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,IAAiB;QAC1B,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,IAAiB;QACrB,OAAO,KAAK,CAAA;IAChB,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAAiB;QACvB,OAAO,IAAI,CAAC,gBAAgB,CAAA;IAChC,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,IAAiB;QAC1B,OAAO,IAAI,CAAC,eAAe,CAAA;IAC/B,CAAC;CACJ"}
@@ -299,7 +299,7 @@ export declare abstract class AssetsManager implements Component, Servable, Open
299
299
  private readTempFile;
300
300
  /**
301
301
  * Cleans up temporary file after processing.
302
- * Silently ignores cleanup errors.
302
+ * Logs cleanup errors but doesn't throw.
303
303
  *
304
304
  * @param filePath - Path to temporary file
305
305
  */
@@ -1 +1 @@
1
- {"version":3,"file":"assets_manager.d.ts","sourceRoot":"","sources":["../../src/components/assets_manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assets_manager.d.ts","sourceRoot":"","sources":["../../src/components/assets_manager.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,11 @@ import { UserService } from '../auth/user_service.js';
3
3
  import { AuthConfig } from '../auth/auth_config.js';
4
4
  import { successResponse, errorResponse, badRequestResponse, unauthorizedResponse, forbiddenResponse, notFoundResponse, textResponse, fileResponse, multiStatusResponse, HttpStatus } from '../utils/http_responses.js';
5
5
  import fs from 'fs/promises';
6
+ import { safeAsync } from '../utils/safe_async.js';
7
+ import { Logger } from '../utils/logger.js';
8
+ import { validateAssetUpdate, validateIdParam, validatePagination } from '../validation/index.js';
9
+ import { validateData, validateQuery, validateParams } from '../validation/validate.js';
10
+ const logger = new Logger('AssetsManager');
6
11
  /**
7
12
  * Abstract base class for Assets Manager components with authentication and access control.
8
13
  *
@@ -298,14 +303,12 @@ export class AssetsManager {
298
303
  }
299
304
  /**
300
305
  * Cleans up temporary file after processing.
301
- * Silently ignores cleanup errors.
306
+ * Logs cleanup errors but doesn't throw.
302
307
  *
303
308
  * @param filePath - Path to temporary file
304
309
  */
305
310
  async cleanupTempFile(filePath) {
306
- await fs.unlink(filePath).catch(() => {
307
- // Ignore cleanup errors
308
- });
311
+ await safeAsync(() => fs.unlink(filePath), `cleanup temp file ${filePath}`, logger);
309
312
  }
310
313
  /**
311
314
  * Validates ownership of an asset.
@@ -375,11 +378,9 @@ export class AssetsManager {
375
378
  * @returns Object with asset on success, or DataResponse on failure
376
379
  */
377
380
  async fetchAssetWithAccessCheck(req) {
378
- const { id } = req.params || {};
379
- if (!id) {
380
- return { success: false, response: badRequestResponse('Asset ID is required') };
381
- }
382
- const asset = await this.getAssetById(id);
381
+ // Validate ID parameter (ValidationError bubbles up to global handler -> 422)
382
+ const validatedParams = await validateParams(validateIdParam, req.params || {}, 'Asset ID');
383
+ const asset = await this.getAssetById(validatedParams.id.toString());
383
384
  if (!asset) {
384
385
  return { success: false, response: textResponse(HttpStatus.NOT_FOUND, 'Asset not found') };
385
386
  }
@@ -457,17 +458,29 @@ export class AssetsManager {
457
458
  */
458
459
  async retrieve(req) {
459
460
  try {
461
+ // Validate pagination parameters if present (ValidationError bubbles up to global handler -> 422)
462
+ let pagination = {};
463
+ if (req?.query && Object.keys(req.query).length > 0) {
464
+ pagination = await validateQuery(validatePagination, req.query, 'Pagination');
465
+ }
460
466
  const assets = await this.getAllAssets();
461
467
  const isAdmin = req && ApisixAuthParser.isAdmin(req.headers || {});
462
468
  // Admin can see everything
469
+ let visibleAssets;
463
470
  if (isAdmin) {
464
- return successResponse(this.formatAssetsForResponse(assets));
471
+ visibleAssets = assets;
472
+ }
473
+ else {
474
+ // Get authenticated user ID if available
475
+ const authenticatedUserId = await this.getAuthenticatedUserId(req);
476
+ // Filter to visible assets only
477
+ visibleAssets = assets.filter(asset => asset.is_public || (authenticatedUserId !== null && asset.owner_id === authenticatedUserId));
465
478
  }
466
- // Get authenticated user ID if available
467
- const authenticatedUserId = await this.getAuthenticatedUserId(req);
468
- // Filter to visible assets only
469
- const visibleAssets = assets.filter(asset => asset.is_public || (authenticatedUserId !== null && asset.owner_id === authenticatedUserId));
470
- return successResponse(this.formatAssetsForResponse(visibleAssets));
479
+ // Apply pagination
480
+ const offset = pagination.offset ?? 0;
481
+ const limit = pagination.limit ?? visibleAssets.length;
482
+ const paginatedAssets = visibleAssets.slice(offset, offset + limit);
483
+ return successResponse(this.formatAssetsForResponse(paginatedAssets));
471
484
  }
472
485
  catch (error) {
473
486
  return errorResponse(error);
@@ -584,22 +597,19 @@ export class AssetsManager {
584
597
  if (record.name !== config.name) {
585
598
  throw new Error(`Asset ${id} does not belong to component ${config.name}`);
586
599
  }
587
- // Apply updates, keeping existing values for non-updated fields
588
- const updatedMetadata = {
589
- id: parseInt(id),
590
- name: config.name,
591
- type: record.contentType,
592
- url: record.url,
593
- date: record.date, // Keep original date
594
- description: updates.description ?? record.description ?? '',
595
- source: updates.source ?? record.source ?? '',
596
- owner_id: record.owner_id ?? null,
597
- filename: record.filename ?? '',
598
- is_public: updates.is_public !== undefined ? updates.is_public : (record.is_public ?? true)
599
- };
600
- // Update the record - delete and re-create with updated metadata
601
- await this.db.delete(id, this.getConfiguration().name);
602
- await this.db.save(updatedMetadata);
600
+ // Apply updates - only include fields that are being updated
601
+ const updateData = {};
602
+ if (updates.description !== undefined) {
603
+ updateData.description = updates.description;
604
+ }
605
+ if (updates.source !== undefined) {
606
+ updateData.source = updates.source;
607
+ }
608
+ if (updates.is_public !== undefined) {
609
+ updateData.is_public = updates.is_public;
610
+ }
611
+ // Use true UPDATE to preserve the record ID
612
+ await this.db.updateAssetMetadata(config.name, parseInt(id), updateData);
603
613
  }
604
614
  /**
605
615
  * Delete asset by ID.
@@ -1214,16 +1224,16 @@ export class AssetsManager {
1214
1224
  if (!userId) {
1215
1225
  return errorResponse('Failed to retrieve user information');
1216
1226
  }
1217
- const { id } = req.params || {};
1218
- const { description, source, is_public } = req.body || {};
1219
- if (!id) {
1220
- return badRequestResponse('Asset ID is required');
1221
- }
1227
+ // Validate ID parameter (ValidationError bubbles up to global handler -> 422)
1228
+ const validatedParams = await validateParams(validateIdParam, req.params || {}, 'Asset ID');
1229
+ // Validate request body (ValidationError bubbles up to global handler -> 422)
1230
+ const validatedBody = await validateData(validateAssetUpdate, req.body || {}, 'Asset update');
1231
+ const { description, source, is_public } = validatedBody;
1222
1232
  if (!description && !source && is_public === undefined) {
1223
1233
  return badRequestResponse('At least one field (description, source, or is_public) must be provided for update');
1224
1234
  }
1225
1235
  // Check if asset exists
1226
- const asset = await this.getAssetById(id);
1236
+ const asset = await this.getAssetById(validatedParams.id.toString());
1227
1237
  if (!asset) {
1228
1238
  return notFoundResponse('Asset not found');
1229
1239
  }
@@ -1240,7 +1250,7 @@ export class AssetsManager {
1240
1250
  updates.source = source;
1241
1251
  if (is_public !== undefined)
1242
1252
  updates.is_public = Boolean(is_public);
1243
- await this.updateAssetMetadata(id, updates);
1253
+ await this.updateAssetMetadata(validatedParams.id.toString(), updates);
1244
1254
  return successResponse({ message: 'Asset metadata updated successfully' });
1245
1255
  }
1246
1256
  catch (error) {
@@ -1338,12 +1348,10 @@ export class AssetsManager {
1338
1348
  if (!userId) {
1339
1349
  return errorResponse('Failed to retrieve user information');
1340
1350
  }
1341
- const { id } = req.params || {};
1342
- if (!id) {
1343
- return badRequestResponse('Asset ID is required');
1344
- }
1351
+ // Validate ID parameter (ValidationError bubbles up to global handler -> 422)
1352
+ const validatedParams = await validateParams(validateIdParam, req.params || {}, 'Asset ID');
1345
1353
  // Check if asset exists
1346
- const asset = await this.getAssetById(id);
1354
+ const asset = await this.getAssetById(validatedParams.id.toString());
1347
1355
  if (!asset) {
1348
1356
  return notFoundResponse('Asset not found');
1349
1357
  }
@@ -1352,7 +1360,7 @@ export class AssetsManager {
1352
1360
  if (ownershipError) {
1353
1361
  return ownershipError;
1354
1362
  }
1355
- await this.deleteAssetById(id);
1363
+ await this.deleteAssetById(validatedParams.id.toString());
1356
1364
  return successResponse({ message: 'Asset deleted successfully' });
1357
1365
  }
1358
1366
  catch (error) {