@solidstarters/solid-core 1.2.166 → 1.2.169

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 (80) hide show
  1. package/dist/config/iam.config.d.ts +2 -0
  2. package/dist/config/iam.config.d.ts.map +1 -1
  3. package/dist/config/iam.config.js +1 -0
  4. package/dist/config/iam.config.js.map +1 -1
  5. package/dist/dtos/create-ai-interaction.dto.d.ts +3 -0
  6. package/dist/dtos/create-ai-interaction.dto.d.ts.map +1 -1
  7. package/dist/dtos/create-ai-interaction.dto.js +19 -1
  8. package/dist/dtos/create-ai-interaction.dto.js.map +1 -1
  9. package/dist/dtos/post-chatter-message.dto.js.map +1 -1
  10. package/dist/dtos/update-ai-interaction.dto.d.ts +3 -0
  11. package/dist/dtos/update-ai-interaction.dto.d.ts.map +1 -1
  12. package/dist/dtos/update-ai-interaction.dto.js +19 -1
  13. package/dist/dtos/update-ai-interaction.dto.js.map +1 -1
  14. package/dist/entities/ai-interaction.entity.d.ts +3 -0
  15. package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
  16. package/dist/entities/ai-interaction.entity.js +13 -1
  17. package/dist/entities/ai-interaction.entity.js.map +1 -1
  18. package/dist/entities/chatter-message.entity.js.map +1 -1
  19. package/dist/filters/http-exception.filter.d.ts.map +1 -1
  20. package/dist/filters/http-exception.filter.js +2 -1
  21. package/dist/filters/http-exception.filter.js.map +1 -1
  22. package/dist/helpers/security.helper.d.ts +4 -2
  23. package/dist/helpers/security.helper.d.ts.map +1 -1
  24. package/dist/helpers/security.helper.js +38 -23
  25. package/dist/helpers/security.helper.js.map +1 -1
  26. package/dist/helpers/solid-core-error-codes-provider.service.js +3 -3
  27. package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -1
  28. package/dist/helpers/solid-registry.d.ts +0 -1
  29. package/dist/helpers/solid-registry.d.ts.map +1 -1
  30. package/dist/helpers/solid-registry.js +0 -1
  31. package/dist/helpers/solid-registry.js.map +1 -1
  32. package/dist/index.d.ts +0 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +0 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +2 -2
  37. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
  38. package/dist/seeders/seed-data/solid-core-metadata.json +33 -0
  39. package/dist/services/authentication.service.d.ts +1 -5
  40. package/dist/services/authentication.service.d.ts.map +1 -1
  41. package/dist/services/authentication.service.js +22 -63
  42. package/dist/services/authentication.service.js.map +1 -1
  43. package/dist/services/chatter-message.service.d.ts.map +1 -1
  44. package/dist/services/chatter-message.service.js.map +1 -1
  45. package/dist/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.js +1 -1
  46. package/dist/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.js.map +1 -1
  47. package/dist/services/model-metadata.service.js +1 -1
  48. package/dist/services/model-metadata.service.js.map +1 -1
  49. package/dist/services/setting.service.d.ts.map +1 -1
  50. package/dist/services/setting.service.js +2 -1
  51. package/dist/services/setting.service.js.map +1 -1
  52. package/dist/solid-core.module.d.ts.map +1 -1
  53. package/dist/solid-core.module.js +0 -2
  54. package/dist/solid-core.module.js.map +1 -1
  55. package/dist/tsconfig.tsbuildinfo +1 -1
  56. package/package.json +1 -1
  57. package/src/config/iam.config.ts +1 -0
  58. package/src/dtos/create-ai-interaction.dto.ts +15 -0
  59. package/src/dtos/post-chatter-message.dto.ts +1 -1
  60. package/src/dtos/update-ai-interaction.dto.ts +15 -0
  61. package/src/entities/ai-interaction.entity.ts +9 -0
  62. package/src/entities/chatter-message.entity.ts +3 -3
  63. package/src/filters/http-exception.filter.ts +5 -2
  64. package/src/helpers/security.helper.ts +95 -30
  65. package/src/helpers/solid-core-error-codes-provider.service.ts +4 -4
  66. package/src/helpers/solid-registry.ts +0 -1
  67. package/src/index.ts +0 -1
  68. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +2 -2
  69. package/src/seeders/seed-data/solid-core-metadata.json +35 -2
  70. package/src/services/authentication.service.ts +31 -142
  71. package/src/services/chatter-message.service.ts +373 -374
  72. package/src/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.ts +1 -1
  73. package/src/services/model-metadata.service.ts +1 -1
  74. package/src/services/setting.service.ts +2 -1
  75. package/src/solid-core.module.ts +0 -8
  76. package/dist/entities/user-password-history.entity.d.ts +0 -7
  77. package/dist/entities/user-password-history.entity.d.ts.map +0 -1
  78. package/dist/entities/user-password-history.entity.js +0 -35
  79. package/dist/entities/user-password-history.entity.js.map +0 -1
  80. package/src/entities/user-password-history.entity.ts +0 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidstarters/solid-core",
3
- "version": "1.2.166",
3
+ "version": "1.2.169",
4
4
  "description": "This module is a NestJS module containing all the required core providers required by a Solid application",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,6 +22,7 @@ export const iamConfig = registerAs('iam', () => {
22
22
  callbackURL: process.env.IAM_GOOGLE_OAUTH_CALLBACK_URL,
23
23
  redirectURL: process.env.IAM_GOOGLE_OAUTH_REDIRECT_URL,
24
24
  },
25
+ iamAutoGeneratedPassword:process.env.IAM_AUTOGENERATED_PASSWORD || true
25
26
  };
26
27
  })
27
28
 
@@ -64,4 +64,19 @@ export class CreateAiInteractionDto {
64
64
  @IsBoolean()
65
65
  @ApiProperty()
66
66
  isAutoApply: boolean = false;
67
+
68
+ @IsOptional()
69
+ @IsInt()
70
+ @ApiProperty()
71
+ inputTokens: number;
72
+
73
+ @IsOptional()
74
+ @IsInt()
75
+ @ApiProperty()
76
+ outputTokens: number;
77
+
78
+ @IsOptional()
79
+ @IsInt()
80
+ @ApiProperty()
81
+ totalTokens: number;
67
82
  }
@@ -16,4 +16,4 @@ export class PostChatterMessageDto {
16
16
  @IsString()
17
17
  @IsOptional()
18
18
  messageSubType?: string;
19
- }
19
+ }
@@ -68,4 +68,19 @@ export class UpdateAiInteractionDto {
68
68
  @IsBoolean()
69
69
  @ApiProperty()
70
70
  isAutoApply: boolean;
71
+
72
+ @IsOptional()
73
+ @IsInt()
74
+ @ApiProperty()
75
+ inputTokens: number;
76
+
77
+ @IsOptional()
78
+ @IsInt()
79
+ @ApiProperty()
80
+ outputTokens: number;
81
+
82
+ @IsOptional()
83
+ @IsInt()
84
+ @ApiProperty()
85
+ totalTokens: number;
71
86
  }
@@ -39,4 +39,13 @@ export class AiInteraction extends CommonEntity {
39
39
  externalId: string;
40
40
  @Column({ type: "boolean", nullable: true, default: false })
41
41
  isAutoApply: boolean = false;
42
+
43
+ @Column({ type: "integer", nullable: true })
44
+ inputTokens: number;
45
+
46
+ @Column({ type: "integer", nullable: true })
47
+ outputTokens: number;
48
+
49
+ @Column({ type: "integer", nullable: true })
50
+ totalTokens: number;
42
51
  }
@@ -1,14 +1,14 @@
1
1
  import { CommonEntity } from 'src/entities/common.entity'
2
- import {Entity, Column, Index, JoinColumn, ManyToOne} from 'typeorm';
2
+ import { Entity, Column, Index, JoinColumn, ManyToOne } from 'typeorm';
3
3
  import { User } from 'src/entities/user.entity'
4
4
 
5
5
  @Entity("ss_chatter_message")
6
6
  export class ChatterMessage extends CommonEntity {
7
7
  @Index()
8
8
  @Column({ type: "varchar" })
9
- messageType: string;
9
+ messageType: string; // audit | custom
10
10
  @Column({ type: "varchar" })
11
- messageSubType: string;
11
+ messageSubType: string; // update | insert | delete | post_message
12
12
  @Column({ type: "text" })
13
13
  messageBody: string;
14
14
  @Index()
@@ -33,7 +33,7 @@ export class HttpExceptionFilter implements ExceptionFilter {
33
33
  // Canonical code + static message
34
34
  const code: ErrorCode = this.errorMapper.mapException(exception);
35
35
  const defaultStatus = this.errorMapper.getHttpStatus(code);
36
- const message = this.errorMapper.getMessage(code);
36
+ const message = code === 'unknown-error' ? `${exception?.message}` : this.errorMapper.getMessage(code);
37
37
 
38
38
  const status = explicitStatus ?? defaultStatus ?? 500;
39
39
 
@@ -55,9 +55,12 @@ export class HttpExceptionFilter implements ExceptionFilter {
55
55
  response.status(status).json({
56
56
  statusCode: status,
57
57
  statusCodeMessage: HttpStatusCodeMessages[status] || 'Internal Server Error',
58
- // message: [message],
58
+ // Keeping this for backward compatibility..
59
+ message: message,
59
60
  errorCode: code,
60
61
  error: message,
62
+ // We can make this conditional based on whether we are running in prod mode or dev mode...
63
+ // errorStack: exception.stack,
61
64
  data: extra,
62
65
  });
63
66
  }
@@ -1,38 +1,74 @@
1
+ import { HelmetOptions } from "helmet";
1
2
  import { Environment } from "src/decorators/disallow-in-production.decorator";
2
- import { HelmetOptions } from "helmet";
3
3
 
4
+ /**
5
+ * Default security headers for SolidX apps.
6
+ * - HSTS only in prod over HTTPS
7
+ * - CSP with frame-ancestors 'none' (prevents clickjacking)
8
+ * - X-Frame-Options: DENY (legacy fallback)
9
+ * - No X-XSS-Protection (deprecated)
10
+ */
4
11
  export function buildDefaultSecurityHeaderOptions(): Readonly<HelmetOptions> {
5
- return {
6
- referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
12
+ const isProd = process.env.ENV === Environment.Production;
13
+
14
+ return {
15
+ // Modern CSP. Add more directives as your app needs (script-src, connect-src, etc.)
16
+ contentSecurityPolicy: {
17
+ useDefaults: true,
18
+ directives: {
19
+ // sensible secure defaults
20
+ // "default-src": ["'self'"],
21
+ // "base-uri": ["'self'"],
22
+ // "object-src": ["'none'"],
23
+ // "form-action": ["'self'"],
24
+
25
+ // clickjacking defense (modern)
26
+ "frame-ancestors": ["'none'"],
27
+
28
+ // add/adjust as needed for your app:
29
+ // "script-src": ["'self'"], // add hashes/nonces/CSPRO if needed
30
+ // "style-src": ["'self'", "'unsafe-inline'"],
31
+ // "img-src": ["'self'", "data:"],
32
+ // "connect-src": ["'self'", "https://api.example.com"],
33
+ // "frame-src": ["'none'"], // iframes you intentionally allow
34
+ },
35
+ },
36
+
37
+
38
+ // Legacy clickjacking defense (kept for older UAs)
39
+ frameguard: { action: "deny" },
40
+
41
+ // Referrer/cross-origin policies
42
+ referrerPolicy: { policy: "strict-origin-when-cross-origin" },
7
43
  crossOriginEmbedderPolicy: false,
8
- crossOriginResourcePolicy: { policy: 'same-site' },
9
- frameguard: { action: 'sameorigin' }, // or { action: 'deny' }
10
- // HSTS: send only in prod over HTTPS
11
- hsts:
12
- process.env.NODE_ENV === Environment.Production
13
- ? { maxAge: 31536000, includeSubDomains: true, preload: true } // 1 year
14
- : false,
15
- }
44
+ crossOriginResourcePolicy: { policy: "same-site" },
45
+
46
+ // HSTS only when you’re on HTTPS in production
47
+ hsts: isProd
48
+ ? { maxAge: 31536000, includeSubDomains: true, preload: true }
49
+ : false,
50
+ };
16
51
  }
17
52
 
18
- type Source = 'self' | 'none' | string; // string = an origin like 'https://cdn.example.com'
19
- type DirectiveConfig = 'self' | 'none' | Source[];
53
+ /* ---------------- Permissions-Policy (formerly Feature-Policy) ---------------- */
20
54
 
55
+ type Source = "self" | "none" | string;
56
+ type DirectiveConfig = "self" | "none" | Source[];
21
57
  export type PermissionsPolicyConfig = Record<string, DirectiveConfig>;
22
58
 
23
59
  export const DEFAULT_PERMISSIONS_POLICY: PermissionsPolicyConfig = {
24
- camera: 'none',
25
- microphone: 'none',
26
- geolocation: 'none',
27
- fullscreen: 'self', // allow same-origin fullscreen
28
- payment: 'none',
29
- accelerometer: 'none',
30
- autoplay: 'none',
31
- 'clipboard-read': 'none',
32
- 'clipboard-write': 'none',
33
- gyroscope: 'none',
34
- magnetometer: 'none',
35
- usb: 'none',
60
+ camera: "none",
61
+ microphone: "none",
62
+ geolocation: "none",
63
+ fullscreen: "self",
64
+ payment: "none",
65
+ accelerometer: "none",
66
+ autoplay: "none",
67
+ "clipboard-read": "none",
68
+ "clipboard-write": "none",
69
+ gyroscope: "none",
70
+ magnetometer: "none",
71
+ usb: "none",
36
72
  };
37
73
 
38
74
  export function buildPermissionsPolicyHeader(
@@ -41,13 +77,42 @@ export function buildPermissionsPolicyHeader(
41
77
  const merged: PermissionsPolicyConfig = { ...DEFAULT_PERMISSIONS_POLICY, ...overrides };
42
78
  return Object.entries(merged)
43
79
  .map(([feature, value]) => `${feature}=${serializeValue(value)}`)
44
- .join(', ');
80
+ .join(", ");
45
81
  }
46
82
 
47
83
  function serializeValue(v: DirectiveConfig): string {
48
- if (v === 'none') return '()';
49
- if (v === 'self') return '(self)';
50
- // array of sources: allow 'self' and/or explicit origins
51
- const parts = v.map(src => (src === 'self' ? 'self' : src)).join(' ');
84
+ if (v === "none") return "()";
85
+ if (v === "self") return "(self)";
86
+ const parts = v.map((src) => (src === "self" ? "self" : src)).join(" ");
52
87
  return `(${parts})`;
53
88
  }
89
+
90
+ /* ---------------- Cache-Control helpers ---------------- */
91
+
92
+ /**
93
+ * Default: no-store for HTML/API responses unless you have a reason to cache.
94
+ * Attach as a global middleware or on selected routes.
95
+ */
96
+ export const DEFAULT_CACHE_CONTROL =
97
+ "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0, s-maxage=0";
98
+
99
+ export function setDefaultCacheControl() {
100
+ return function cacheControlMiddleware(
101
+ _req: import("express").Request,
102
+ _res: import("express").Response,
103
+ next: import("express").NextFunction
104
+ ) {
105
+ _res.setHeader("Cache-Control", DEFAULT_CACHE_CONTROL);
106
+ next();
107
+ };
108
+ }
109
+
110
+ /* ---------------- Example Express wiring ---------------- */
111
+ // import express from "express";
112
+ // const app = express();
113
+ // app.use(helmet(buildDefaultSecurityHeaderOptions()));
114
+ // app.use((req, res, next) => {
115
+ // res.setHeader("Permissions-Policy", buildPermissionsPolicyHeader());
116
+ // next();
117
+ // });
118
+ // app.use(setDefaultCacheControl());
@@ -15,7 +15,7 @@ export class SolidCoreErrorCodesProvider implements IErrorCodeProvider {
15
15
  return [
16
16
  {
17
17
  code: 'solidx-mcp-server-unavailable',
18
- priority: 100, // run early
18
+ priority: 100,
19
19
  match: (txt) =>
20
20
  txt.includes('all connection attempts failed') &&
21
21
  txt.includes('unhandled errors in a taskgroup (1 sub-exception)'),
@@ -25,7 +25,7 @@ export class SolidCoreErrorCodesProvider implements IErrorCodeProvider {
25
25
  },
26
26
  },
27
27
  {
28
- code: 'db-duplicate-key',
28
+ code: 'solidx-db-duplicate-key',
29
29
  priority: 90,
30
30
  match: (txt) => txt.includes('unique constraint') || txt.includes('duplicate key'),
31
31
  meta: {
@@ -34,7 +34,7 @@ export class SolidCoreErrorCodesProvider implements IErrorCodeProvider {
34
34
  },
35
35
  },
36
36
  {
37
- code: 'db-foreign-key-error',
37
+ code: 'solidx-db-foreign-key-error',
38
38
  priority: 90,
39
39
  match: (txt) => txt.includes('violates foreign key'),
40
40
  meta: {
@@ -44,7 +44,7 @@ export class SolidCoreErrorCodesProvider implements IErrorCodeProvider {
44
44
  },
45
45
  },
46
46
  {
47
- code: 'unknown-error',
47
+ code: 'solidx-unknown-error',
48
48
  priority: -1, // last resort
49
49
  match: (_txt) => true, // fallback catch-all
50
50
  meta: {
@@ -33,7 +33,6 @@ export enum RESERVED_SOLID_KEYWORDS {
33
33
  securityRule = "securityRule",
34
34
  setting = "setting",
35
35
  smsTemplate = "smsTemplate",
36
- userPasswordHistory = "userPasswordHistory",
37
36
  userMetadata = "userMetadata",
38
37
  user = "user",
39
38
  locale = "locale"
package/src/index.ts CHANGED
@@ -112,7 +112,6 @@ export * from './entities/scheduled-job.entity'
112
112
  export * from './entities/permission-metadata.entity'
113
113
  export * from './entities/role-metadata.entity'
114
114
  export * from './entities/sms-template.entity'
115
- export * from './entities/user-password-history.entity'
116
115
  export * from './entities/user.entity'
117
116
  export * from './entities/view-metadata.entity'
118
117
  export * from './entities/setting.entity'
@@ -67,7 +67,7 @@ export class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<Trigg
67
67
  errorMessage: errorsStr,
68
68
  modelUsed: aiResponse.model,
69
69
  responseTimeMs: aiResponse.duration_ms,
70
- metadata: JSON.stringify(aiResponse),
70
+ metadata: JSON.stringify(aiResponse, null, 2),
71
71
  isApplied: aiInteraction.isApplied,
72
72
  status: aiResponse.success ? 'succeeded' : 'failed'
73
73
  });
@@ -88,7 +88,7 @@ export class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<Trigg
88
88
  errorMessage: '',
89
89
  modelUsed: aiResponse.model,
90
90
  responseTimeMs: aiResponse.duration_ms,
91
- metadata: JSON.stringify(aiResponse),
91
+ metadata: JSON.stringify(aiResponse, null, 2),
92
92
  isApplied: aiInteraction.isApplied,
93
93
  status: aiResponse.success ? 'succeeded' : 'failed'
94
94
  });
@@ -5152,6 +5152,39 @@
5152
5152
  "index": false,
5153
5153
  "private": false,
5154
5154
  "encrypt": false
5155
+ },
5156
+ {
5157
+ "name": "inputTokens",
5158
+ "displayName": "Input Tokens",
5159
+ "type": "int",
5160
+ "ormType": "integer",
5161
+ "required": false,
5162
+ "unique": false,
5163
+ "index": false,
5164
+ "private": false,
5165
+ "encrypt": false
5166
+ },
5167
+ {
5168
+ "name": "outputTokens",
5169
+ "displayName": "Output Tokens",
5170
+ "type": "int",
5171
+ "ormType": "integer",
5172
+ "required": false,
5173
+ "unique": false,
5174
+ "index": false,
5175
+ "private": false,
5176
+ "encrypt": false
5177
+ },
5178
+ {
5179
+ "name": "totalTokens",
5180
+ "displayName": "Total Tokens",
5181
+ "type": "int",
5182
+ "ormType": "integer",
5183
+ "required": false,
5184
+ "unique": false,
5185
+ "index": false,
5186
+ "private": false,
5187
+ "encrypt": false
5155
5188
  }
5156
5189
  ]
5157
5190
  }
@@ -5584,7 +5617,7 @@
5584
5617
  "moduleUserKey": "solid-core",
5585
5618
  "modelUserKey": "setting"
5586
5619
  },
5587
- {
5620
+ {
5588
5621
  "displayName": "Ai settings",
5589
5622
  "name": "ai-settings-action",
5590
5623
  "type": "custom",
@@ -5965,7 +5998,7 @@
5965
5998
  "moduleUserKey": "solid-core",
5966
5999
  "parentMenuItemUserKey": "settings-menu-item"
5967
6000
  },
5968
- {
6001
+ {
5969
6002
  "displayName": "Ai Settings",
5970
6003
  "name": "ai-settings-menu-item",
5971
6004
  "sequenceNumber": 3,