@solidxai/core 0.1.9-beta.6 → 0.1.9-beta.8

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 (254) hide show
  1. package/dist/constants/chatter-message.constants.d.ts +6 -0
  2. package/dist/constants/chatter-message.constants.d.ts.map +1 -1
  3. package/dist/constants/chatter-message.constants.js +7 -1
  4. package/dist/constants/chatter-message.constants.js.map +1 -1
  5. package/dist/controllers/authentication.controller.d.ts +12 -0
  6. package/dist/controllers/authentication.controller.d.ts.map +1 -1
  7. package/dist/controllers/authentication.controller.js +13 -0
  8. package/dist/controllers/authentication.controller.js.map +1 -1
  9. package/dist/controllers/chatter-message.controller.d.ts +1 -0
  10. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  11. package/dist/controllers/chatter-message.controller.js +12 -0
  12. package/dist/controllers/chatter-message.controller.js.map +1 -1
  13. package/dist/controllers/facebook-authentication.controller.d.ts +27 -0
  14. package/dist/controllers/facebook-authentication.controller.d.ts.map +1 -0
  15. package/dist/controllers/facebook-authentication.controller.js +117 -0
  16. package/dist/controllers/facebook-authentication.controller.js.map +1 -0
  17. package/dist/controllers/menu-item-metadata.controller.d.ts +1 -0
  18. package/dist/controllers/menu-item-metadata.controller.d.ts.map +1 -1
  19. package/dist/controllers/menu-item-metadata.controller.js +15 -0
  20. package/dist/controllers/menu-item-metadata.controller.js.map +1 -1
  21. package/dist/controllers/microsoft-authentication.controller.d.ts +27 -0
  22. package/dist/controllers/microsoft-authentication.controller.d.ts.map +1 -0
  23. package/dist/controllers/microsoft-authentication.controller.js +118 -0
  24. package/dist/controllers/microsoft-authentication.controller.js.map +1 -0
  25. package/dist/controllers/setting.controller.d.ts +2 -2
  26. package/dist/controllers/setting.controller.js +2 -2
  27. package/dist/decorators/auth.decorator.d.ts.map +1 -1
  28. package/dist/decorators/computed-field-provider.decorator.d.ts.map +1 -1
  29. package/dist/decorators/dashboard-question-data-provider.decorator.d.ts.map +1 -1
  30. package/dist/decorators/dashboard-selection-provider.decorator.d.ts.map +1 -1
  31. package/dist/decorators/disallow-in-production.decorator.d.ts.map +1 -1
  32. package/dist/decorators/error-codes-provider.decorator.d.ts.map +1 -1
  33. package/dist/decorators/extension-user-creation-provider.decorator.d.ts.map +1 -1
  34. package/dist/decorators/is-not-in-enum.decorator.d.ts.map +1 -1
  35. package/dist/decorators/mail-provider.decorator.d.ts.map +1 -1
  36. package/dist/decorators/roles.decorator.d.ts.map +1 -1
  37. package/dist/decorators/scheduled-job-provider.decorator.d.ts.map +1 -1
  38. package/dist/decorators/security-rule-config-provider.decorator.d.ts.map +1 -1
  39. package/dist/decorators/selection-provider.decorator.d.ts.map +1 -1
  40. package/dist/decorators/sms-provider.decorator.d.ts.map +1 -1
  41. package/dist/decorators/solid-database-module.decorator.d.ts.map +1 -1
  42. package/dist/decorators/whatsapp-provider.decorator.d.ts.map +1 -1
  43. package/dist/dtos/create-chatter-message.dto.d.ts +1 -0
  44. package/dist/dtos/create-chatter-message.dto.d.ts.map +1 -1
  45. package/dist/dtos/create-chatter-message.dto.js +7 -1
  46. package/dist/dtos/create-chatter-message.dto.js.map +1 -1
  47. package/dist/dtos/post-chatter-message.dto.d.ts +1 -0
  48. package/dist/dtos/post-chatter-message.dto.d.ts.map +1 -1
  49. package/dist/dtos/post-chatter-message.dto.js +6 -1
  50. package/dist/dtos/post-chatter-message.dto.js.map +1 -1
  51. package/dist/dtos/update-chatter-message.dto.d.ts +1 -0
  52. package/dist/dtos/update-chatter-message.dto.d.ts.map +1 -1
  53. package/dist/dtos/update-chatter-message.dto.js +7 -1
  54. package/dist/dtos/update-chatter-message.dto.js.map +1 -1
  55. package/dist/entities/chatter-message.entity.d.ts +1 -0
  56. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  57. package/dist/entities/chatter-message.entity.js +5 -1
  58. package/dist/entities/chatter-message.entity.js.map +1 -1
  59. package/dist/entities/user.entity.d.ts +8 -0
  60. package/dist/entities/user.entity.d.ts.map +1 -1
  61. package/dist/entities/user.entity.js +33 -1
  62. package/dist/entities/user.entity.js.map +1 -1
  63. package/dist/helpers/cors.helper.js +1 -1
  64. package/dist/helpers/cors.helper.js.map +1 -1
  65. package/dist/helpers/facebook-oauth.helper.d.ts +8 -0
  66. package/dist/helpers/facebook-oauth.helper.d.ts.map +1 -0
  67. package/dist/helpers/facebook-oauth.helper.js +11 -0
  68. package/dist/helpers/facebook-oauth.helper.js.map +1 -0
  69. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js +5 -5
  70. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js.map +1 -1
  71. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.d.ts.map +1 -1
  72. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js +2 -2
  73. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js.map +1 -1
  74. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js +5 -5
  75. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js.map +1 -1
  76. package/dist/helpers/microsoft-oauth.helper.d.ts +9 -0
  77. package/dist/helpers/microsoft-oauth.helper.d.ts.map +1 -0
  78. package/dist/helpers/microsoft-oauth.helper.js +12 -0
  79. package/dist/helpers/microsoft-oauth.helper.js.map +1 -0
  80. package/dist/helpers/module-metadata-helper.service.js +3 -3
  81. package/dist/helpers/module-metadata-helper.service.js.map +1 -1
  82. package/dist/helpers/security.helper.d.ts.map +1 -1
  83. package/dist/helpers/string.helper.d.ts +1 -0
  84. package/dist/helpers/string.helper.d.ts.map +1 -1
  85. package/dist/helpers/string.helper.js +4 -1
  86. package/dist/helpers/string.helper.js.map +1 -1
  87. package/dist/helpers/user-helper.d.ts.map +1 -1
  88. package/dist/helpers/user-helper.js +4 -0
  89. package/dist/helpers/user-helper.js.map +1 -1
  90. package/dist/index.d.ts +2 -0
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +2 -0
  93. package/dist/index.js.map +1 -1
  94. package/dist/interfaces.d.ts +19 -0
  95. package/dist/interfaces.d.ts.map +1 -1
  96. package/dist/interfaces.js.map +1 -1
  97. package/dist/passport-strategies/facebook-oauth.strategy.d.ts +14 -0
  98. package/dist/passport-strategies/facebook-oauth.strategy.d.ts.map +1 -0
  99. package/dist/passport-strategies/facebook-oauth.strategy.js +73 -0
  100. package/dist/passport-strategies/facebook-oauth.strategy.js.map +1 -0
  101. package/dist/passport-strategies/microsoft-oauth.strategy.d.ts +14 -0
  102. package/dist/passport-strategies/microsoft-oauth.strategy.d.ts.map +1 -0
  103. package/dist/passport-strategies/microsoft-oauth.strategy.js +77 -0
  104. package/dist/passport-strategies/microsoft-oauth.strategy.js.map +1 -0
  105. package/dist/repository/chatter-message-details.repository.d.ts.map +1 -1
  106. package/dist/repository/chatter-message-details.repository.js +7 -6
  107. package/dist/repository/chatter-message-details.repository.js.map +1 -1
  108. package/dist/repository/chatter-message.repository.d.ts.map +1 -1
  109. package/dist/repository/chatter-message.repository.js +4 -4
  110. package/dist/repository/chatter-message.repository.js.map +1 -1
  111. package/dist/repository/solid-base.repository.js +2 -2
  112. package/dist/repository/solid-base.repository.js.map +1 -1
  113. package/dist/seeders/module-test-data.service.js +4 -4
  114. package/dist/seeders/module-test-data.service.js.map +1 -1
  115. package/dist/seeders/seed-data/solid-core-metadata.json +27 -58
  116. package/dist/services/api-key.service.d.ts +17 -1
  117. package/dist/services/api-key.service.d.ts.map +1 -1
  118. package/dist/services/api-key.service.js +38 -2
  119. package/dist/services/api-key.service.js.map +1 -1
  120. package/dist/services/authentication.service.d.ts +51 -16
  121. package/dist/services/authentication.service.d.ts.map +1 -1
  122. package/dist/services/authentication.service.js +318 -150
  123. package/dist/services/authentication.service.js.map +1 -1
  124. package/dist/services/chatter-message.service.d.ts +1 -0
  125. package/dist/services/chatter-message.service.d.ts.map +1 -1
  126. package/dist/services/chatter-message.service.js +17 -0
  127. package/dist/services/chatter-message.service.js.map +1 -1
  128. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
  129. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +2 -2
  130. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
  131. package/dist/services/crud-helper.service.d.ts.map +1 -1
  132. package/dist/services/crud-helper.service.js +9 -9
  133. package/dist/services/crud-helper.service.js.map +1 -1
  134. package/dist/services/export-transaction.service.d.ts.map +1 -1
  135. package/dist/services/export-transaction.service.js +4 -3
  136. package/dist/services/export-transaction.service.js.map +1 -1
  137. package/dist/services/field-metadata.service.d.ts.map +1 -1
  138. package/dist/services/field-metadata.service.js +7 -7
  139. package/dist/services/field-metadata.service.js.map +1 -1
  140. package/dist/services/fixtures.service.js +2 -2
  141. package/dist/services/fixtures.service.js.map +1 -1
  142. package/dist/services/genai/mcp-handlers/mcp-handler-factory.service.d.ts.map +1 -1
  143. package/dist/services/genai/mcp-handlers/mcp-handler-factory.service.js +2 -2
  144. package/dist/services/genai/mcp-handlers/mcp-handler-factory.service.js.map +1 -1
  145. package/dist/services/import-transaction.service.d.ts.map +1 -1
  146. package/dist/services/import-transaction.service.js +2 -2
  147. package/dist/services/import-transaction.service.js.map +1 -1
  148. package/dist/services/menu-item-metadata.service.js +2 -2
  149. package/dist/services/menu-item-metadata.service.js.map +1 -1
  150. package/dist/services/model-metadata.service.d.ts.map +1 -1
  151. package/dist/services/model-metadata.service.js +12 -11
  152. package/dist/services/model-metadata.service.js.map +1 -1
  153. package/dist/services/module-metadata.service.d.ts.map +1 -1
  154. package/dist/services/module-metadata.service.js +2 -2
  155. package/dist/services/module-metadata.service.js.map +1 -1
  156. package/dist/services/queues/publisher-factory.service.d.ts.map +1 -1
  157. package/dist/services/queues/publisher-factory.service.js +2 -2
  158. package/dist/services/queues/publisher-factory.service.js.map +1 -1
  159. package/dist/services/selection-providers/pseudo-foreign-key-selection-provider.service.js +3 -3
  160. package/dist/services/selection-providers/pseudo-foreign-key-selection-provider.service.js.map +1 -1
  161. package/dist/services/setting.service.d.ts +5 -2
  162. package/dist/services/setting.service.d.ts.map +1 -1
  163. package/dist/services/setting.service.js +51 -6
  164. package/dist/services/setting.service.js.map +1 -1
  165. package/dist/services/settings/default-settings-provider.service.d.ts +830 -0
  166. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  167. package/dist/services/settings/default-settings-provider.service.js +1033 -117
  168. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  169. package/dist/services/solid-introspect.service.js +2 -2
  170. package/dist/services/solid-introspect.service.js.map +1 -1
  171. package/dist/services/user.service.d.ts +2 -0
  172. package/dist/services/user.service.d.ts.map +1 -1
  173. package/dist/services/user.service.js +72 -0
  174. package/dist/services/user.service.js.map +1 -1
  175. package/dist/services/view-metadata.service.d.ts.map +1 -1
  176. package/dist/services/view-metadata.service.js +2 -2
  177. package/dist/services/view-metadata.service.js.map +1 -1
  178. package/dist/solid-core.module.d.ts.map +1 -1
  179. package/dist/solid-core.module.js +11 -3
  180. package/dist/solid-core.module.js.map +1 -1
  181. package/dist/subscribers/computed-entity-field.subscriber.js +6 -6
  182. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  183. package/dist/transformers/array-transformer.d.ts.map +1 -1
  184. package/dist/transformers/boolean-transformer.d.ts.map +1 -1
  185. package/dist/transformers/datetime-transformer.d.ts.map +1 -1
  186. package/dist/transformers/integer-transformer.d.ts.map +1 -1
  187. package/dist/validators/is-parsable-int.d.ts.map +1 -1
  188. package/dist-tests/api/authenticate.spec.js +119 -0
  189. package/dist-tests/api/authenticate.spec.js.map +1 -0
  190. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
  191. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
  192. package/dist-tests/api/ping.spec.js +21 -0
  193. package/dist-tests/api/ping.spec.js.map +1 -0
  194. package/dist-tests/helpers/auth.js +41 -0
  195. package/dist-tests/helpers/auth.js.map +1 -0
  196. package/dist-tests/helpers/env.js +11 -0
  197. package/dist-tests/helpers/env.js.map +1 -0
  198. package/docs/java-spring/README.md +3 -0
  199. package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
  200. package/nest +0 -0
  201. package/package.json +7 -2
  202. package/src/constants/chatter-message.constants.ts +7 -0
  203. package/src/controllers/authentication.controller.ts +8 -1
  204. package/src/controllers/chatter-message.controller.ts +6 -0
  205. package/src/controllers/facebook-authentication.controller.ts +113 -0
  206. package/src/controllers/menu-item-metadata.controller.ts +21 -15
  207. package/src/controllers/microsoft-authentication.controller.ts +116 -0
  208. package/src/dtos/create-chatter-message.dto.ts +11 -0
  209. package/src/dtos/post-chatter-message.dto.ts +4 -0
  210. package/src/dtos/update-chatter-message.dto.ts +13 -1
  211. package/src/entities/chatter-message.entity.ts +4 -1
  212. package/src/entities/user.entity.ts +32 -0
  213. package/src/helpers/cors.helper.ts +1 -1
  214. package/src/helpers/facebook-oauth.helper.ts +17 -0
  215. package/src/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.ts +1 -1
  216. package/src/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.ts +1 -2
  217. package/src/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.ts +1 -1
  218. package/src/helpers/microsoft-oauth.helper.ts +19 -0
  219. package/src/helpers/module-metadata-helper.service.ts +3 -3
  220. package/src/helpers/string.helper.ts +3 -0
  221. package/src/helpers/user-helper.ts +4 -0
  222. package/src/index.ts +2 -0
  223. package/src/interfaces.ts +32 -1
  224. package/src/passport-strategies/facebook-oauth.strategy.ts +64 -0
  225. package/src/passport-strategies/microsoft-oauth.strategy.ts +70 -0
  226. package/src/repository/chatter-message-details.repository.ts +4 -3
  227. package/src/repository/chatter-message.repository.ts +4 -4
  228. package/src/repository/solid-base.repository.ts +2 -2
  229. package/src/seeders/module-test-data.service.ts +1 -1
  230. package/src/seeders/seed-data/solid-core-metadata.json +27 -58
  231. package/src/services/api-key.service.ts +77 -35
  232. package/src/services/authentication.service.ts +1717 -1278
  233. package/src/services/chatter-message.service.ts +22 -4
  234. package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +1 -2
  235. package/src/services/crud-helper.service.ts +1 -4
  236. package/src/services/export-transaction.service.ts +3 -4
  237. package/src/services/field-metadata.service.ts +1 -4
  238. package/src/services/fixtures.service.ts +1 -1
  239. package/src/services/genai/mcp-handlers/mcp-handler-factory.service.ts +1 -2
  240. package/src/services/import-transaction.service.ts +1 -1
  241. package/src/services/menu-item-metadata.service.ts +2 -2
  242. package/src/services/model-metadata.service.ts +11 -13
  243. package/src/services/module-metadata.service.ts +1 -2
  244. package/src/services/queues/publisher-factory.service.ts +1 -2
  245. package/src/services/selection-providers/pseudo-foreign-key-selection-provider.service.ts +1 -1
  246. package/src/services/setting.service.ts +64 -8
  247. package/src/services/settings/default-settings-provider.service.ts +1104 -155
  248. package/src/services/solid-introspect.service.ts +1 -1
  249. package/src/services/user.service.ts +87 -0
  250. package/src/services/view-metadata.service.ts +1 -5
  251. package/src/solid-core.module.ts +25 -8
  252. package/src/subscribers/computed-entity-field.subscriber.ts +6 -6
  253. package/.claude/settings.local.json +0 -15
  254. package/src/services/1.js +0 -6
@@ -2,3 +2,6 @@ export const lowerFirst = (str: string): string => {
2
2
  if (!str) return str;
3
3
  return str.charAt(0).toLowerCase() + str.slice(1);
4
4
  }
5
+
6
+ import { upperFirst, camelCase } from 'lodash';
7
+ export const classify = (s: string): string => upperFirst(camelCase(s));
@@ -11,6 +11,10 @@ export function getUserExcludedFields(): string[] {
11
11
  "forcePasswordChange",
12
12
  "lastLoginProvider",
13
13
  "googleProfilePicture",
14
+ "facebookAccessToken",
15
+ "facebookId",
16
+ "microsoftAccessToken",
17
+ "microsoftId",
14
18
  "forgotPasswordConfirmedAt",
15
19
  "verificationTokenOnForgotPassword",
16
20
  "verificationTokenOnForgotPasswordExpiresAt",
package/src/index.ts CHANGED
@@ -261,6 +261,8 @@ export * from './jobs/redis/twilio-sms-subscriber-redis.service'
261
261
  export * from './listeners/user-registration.listener'
262
262
 
263
263
  export * from './passport-strategies/google-oauth.strategy'
264
+ export * from './passport-strategies/facebook-oauth.strategy'
265
+ export * from './passport-strategies/microsoft-oauth.strategy'
264
266
 
265
267
  export * from './services/selection-providers/list-of-values-selection-providers.service'
266
268
 
package/src/interfaces.ts CHANGED
@@ -68,12 +68,44 @@ export enum SettingLevel {
68
68
  InternalUser = "internal-user"
69
69
  }
70
70
 
71
+ export type SettingControlType =
72
+ | 'shortText'
73
+ | 'longText'
74
+ | 'numeric'
75
+ | 'boolean'
76
+ | 'date'
77
+ | 'datetime'
78
+ | 'mediaSingle'
79
+ | 'selectionStatic'
80
+ | 'custom';
81
+
82
+ export interface SettingOption {
83
+ label: string;
84
+ value: string | number | boolean;
85
+ }
86
+
71
87
  export interface SettingDefinition<T = any> {
72
88
  moduleName: string;
73
89
  key: string;
74
90
  value: T;
75
91
  level: SettingLevel;
76
92
  encrypted?: boolean;
93
+ label?: string;
94
+ description?: string;
95
+ placeholder?: string;
96
+ group?: string;
97
+ sortOrder?: number;
98
+ controlType?: SettingControlType;
99
+ options?: SettingOption[];
100
+ settingsWidget?: string; // for custom controlType, specify the frontend widget to use
101
+ }
102
+
103
+ export interface AdminSettingDefinition<T = any> extends SettingDefinition<T> {
104
+ editable: boolean;
105
+ }
106
+
107
+ export interface AdminSettingsResponse<T = any> {
108
+ data: AdminSettingDefinition<T>[];
77
109
  }
78
110
 
79
111
  // solid-core/settings/settings-provider.interface.ts
@@ -419,4 +451,3 @@ export interface AuditQueuePayload {
419
451
  userId?: number | null;
420
452
  }
421
453
 
422
-
@@ -0,0 +1,64 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import { AuthGuard, PassportStrategy } from '@nestjs/passport';
3
+ import { Strategy } from 'passport-facebook';
4
+ import { FacebookAuthConfiguration, isFacebookOAuthConfigured } from 'src/helpers/facebook-oauth.helper';
5
+ import { v4 as uuid } from 'uuid';
6
+ import { UserService } from '../services/user.service';
7
+
8
+ const DUMMY_CLIENT_ID = 'DUMMY_CLIENT_ID';
9
+ const DUMMY_CLIENT_SECRET = 'DUMMY_CLIENT_SECRET';
10
+ const DUMMY_CALLBACK_URL = 'DUMMY_CALLBACK_URL';
11
+
12
+ @Injectable()
13
+ export class FacebookOauthGuard extends AuthGuard('facebook') { }
14
+
15
+ @Injectable()
16
+ export class FacebookOAuthStrategy extends PassportStrategy(Strategy, 'facebook') {
17
+ private readonly logger = new Logger(FacebookOAuthStrategy.name);
18
+
19
+ constructor(private readonly userService: UserService) {
20
+ // Reading configuration from environment variables (Static approach like Google)
21
+ const clientID = process.env.IAM_FACEBOOK_OAUTH_CLIENT_ID ?? DUMMY_CLIENT_ID;
22
+ const clientSecret = process.env.IAM_FACEBOOK_OAUTH_CLIENT_SECRET ?? DUMMY_CLIENT_SECRET;
23
+ const callbackURL = process.env.IAM_FACEBOOK_OAUTH_CALLBACK_URL ?? DUMMY_CALLBACK_URL;
24
+ const redirectURL = process.env.IAM_FACEBOOK_OAUTH_REDIRECT_URL;
25
+
26
+ super({
27
+ clientID,
28
+ clientSecret,
29
+ callbackURL,
30
+ scope: ['email'],
31
+ profileFields: ['id', 'emails', 'name', 'photos'],
32
+ });
33
+
34
+ const facebookOauth: FacebookAuthConfiguration = { clientID, clientSecret, callbackURL, redirectURL };
35
+ if (!isFacebookOAuthConfigured(facebookOauth)) {
36
+ this.logger.debug('Facebook OAuth strategy is not configured');
37
+ }
38
+ }
39
+
40
+ async validate(_accessToken: string, _refreshToken: string, profile: any, done: any): Promise<any> {
41
+ const { id, name, emails, photos } = profile;
42
+
43
+ // generate a unique access code.
44
+ const loginAccessCode: string = uuid();
45
+
46
+ const user = {
47
+ provider: 'facebook',
48
+ providerId: id,
49
+ email: emails?.[0]?.value,
50
+ name: `${name.givenName} ${name.familyName}`,
51
+ picture: photos?.[0]?.value,
52
+ accessCode: loginAccessCode,
53
+ };
54
+
55
+ // store the access code and the access token in the database.
56
+ await this.userService.resolveUserOnOauthFacebook({
57
+ ...user,
58
+ accessToken: _accessToken,
59
+ refreshToken: null
60
+ });
61
+
62
+ done(null, user);
63
+ }
64
+ }
@@ -0,0 +1,70 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import { AuthGuard, PassportStrategy } from '@nestjs/passport';
3
+ import { Strategy } from 'passport-microsoft';
4
+ import { MicrosoftAuthConfiguration, isMicrosoftOAuthConfigured } from 'src/helpers/microsoft-oauth.helper';
5
+ import { v4 as uuid } from 'uuid';
6
+ import { UserService } from '../services/user.service';
7
+
8
+ const DUMMY_CLIENT_ID = 'DUMMY_CLIENT_ID';
9
+ const DUMMY_CLIENT_SECRET = 'DUMMY_CLIENT_SECRET';
10
+ const DUMMY_TENANT = 'common';
11
+ const DUMMY_CALLBACK_URL = 'DUMMY_CALLBACK_URL';
12
+
13
+ @Injectable()
14
+ export class MicrosoftOauthGuard extends AuthGuard('microsoft') { }
15
+
16
+ @Injectable()
17
+ export class MicrosoftOAuthStrategy extends PassportStrategy(Strategy, 'microsoft') {
18
+ private readonly logger = new Logger(MicrosoftOAuthStrategy.name);
19
+
20
+ constructor(private readonly userService: UserService) {
21
+ // Reading configuration from environment variables (Static approach like Google)
22
+ const clientID = process.env.IAM_MICROSOFT_OAUTH_CLIENT_ID ?? DUMMY_CLIENT_ID;
23
+ const clientSecret = process.env.IAM_MICROSOFT_OAUTH_CLIENT_SECRET ?? DUMMY_CLIENT_SECRET;
24
+ const tenant = process.env.IAM_MICROSOFT_OAUTH_TENANT_ID ?? DUMMY_TENANT;
25
+ const callbackURL = process.env.IAM_MICROSOFT_OAUTH_CALLBACK_URL ?? DUMMY_CALLBACK_URL;
26
+ const redirectURL = process.env.IAM_MICROSOFT_OAUTH_REDIRECT_URL;
27
+
28
+ super({
29
+ clientID,
30
+ clientSecret,
31
+ callbackURL,
32
+ tenant,
33
+ scope: ['user.read'],
34
+ addUPNAsEmail: true,
35
+ });
36
+
37
+ const microsoftOauth: MicrosoftAuthConfiguration = { clientID, clientSecret, tenant, callbackURL, redirectURL };
38
+ if (!isMicrosoftOAuthConfigured(microsoftOauth)) {
39
+ this.logger.debug('Microsoft OAuth strategy is not configured');
40
+ }
41
+ }
42
+
43
+ async validate(_accessToken: string, _refreshToken: string, profile: any, done: any): Promise<any> {
44
+ const { id, displayName, emails, photos } = profile;
45
+
46
+ // generate a unique access code.
47
+ const loginAccessCode: string = uuid();
48
+
49
+ // Handle email fallback logic within the standard validate flow
50
+ const email = emails?.[0]?.value || profile._json?.mail || profile._json?.userPrincipalName;
51
+
52
+ const user = {
53
+ provider: 'microsoft',
54
+ providerId: id,
55
+ email: email,
56
+ name: displayName,
57
+ picture: photos?.[0]?.value || null,
58
+ accessCode: loginAccessCode,
59
+ };
60
+
61
+ // store the access code and the access token in the database.
62
+ await this.userService.resolveUserOnOauthMicrosoft({
63
+ ...user,
64
+ accessToken: _accessToken,
65
+ refreshToken: null
66
+ });
67
+
68
+ done(null, user);
69
+ }
70
+ }
@@ -4,7 +4,8 @@ import {
4
4
  QueryRunner,
5
5
  SelectQueryBuilder,
6
6
  } from 'typeorm';
7
- import { camelize, classify } from '@angular-devkit/core/src/utils/strings';
7
+ import { upperFirst, camelCase } from 'lodash';
8
+ import { classify } from '../helpers/string.helper';
8
9
 
9
10
  import { ChatterMessageDetails } from 'src/entities/chatter-message-details.entity';
10
11
  import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
@@ -80,7 +81,7 @@ export class ChatterMessageDetailsRepository extends SolidBaseRepository<Chatter
80
81
  const entityName = classify(coModelName); // "client" -> "Client"
81
82
  const meta = this.dataSource.getMetadata(entityName); // throws if not registered
82
83
  // const table = meta.tablePath; // schema-qualified
83
- const coAlias = camelize(meta.name); // stable alias, e.g., "client"
84
+ const coAlias = camelCase(meta.name); // stable alias, e.g., "client"
84
85
 
85
86
  // LEFT JOIN "<schema>"."<table>" "<coAlias>"
86
87
  // ON "<coAlias>"."id" = "message"."co_model_entity_id"
@@ -103,7 +104,7 @@ export class ChatterMessageDetailsRepository extends SolidBaseRepository<Chatter
103
104
  const coModelName = get(requestFilter, this.CO_MODEL_NAME_PATH);
104
105
  if (!coModelName) return [undefined, undefined];
105
106
 
106
- const alias = camelize(coModelName);
107
+ const alias = camelCase(coModelName);
107
108
  return [coModelName, alias];
108
109
  }
109
110
 
@@ -1,4 +1,3 @@
1
- import { camelize, classify } from "@angular-devkit/core/src/utils/strings";
2
1
  import { Injectable } from "@nestjs/common";
3
2
  import { ChatterMessage } from "src/entities/chatter-message.entity";
4
3
  import { ActiveUserData } from "src/interfaces/active-user-data.interface";
@@ -6,7 +5,8 @@ import { RequestContextService } from "src/services/request-context.service";
6
5
  import { DataSource, QueryRunner, SelectQueryBuilder } from "typeorm";
7
6
  import { SecurityRuleRepository } from "./security-rule.repository";
8
7
  import { SolidBaseRepository } from "./solid-base.repository";
9
- import {get} from "lodash"
8
+ import { get, camelCase } from 'lodash';
9
+ import { classify } from '../helpers/string.helper';
10
10
 
11
11
  @Injectable()
12
12
  export class ChatterMessageRepository extends SolidBaseRepository<ChatterMessage> {
@@ -44,7 +44,7 @@ export class ChatterMessageRepository extends SolidBaseRepository<ChatterMessage
44
44
  // const Target = resolveEntityFromCoModelName(coModelName); // your mapping
45
45
  const entityName = classify(coModelName)
46
46
  const meta = this.dataSource.getMetadata(entityName);
47
- const alias = camelize(meta.name);
47
+ const alias = camelCase(meta.name);
48
48
  qb.leftJoin(
49
49
  entityName,
50
50
  alias,
@@ -63,7 +63,7 @@ export class ChatterMessageRepository extends SolidBaseRepository<ChatterMessage
63
63
 
64
64
  const coModelName = get(requestFilter, this.CO_MODEL_NAME_PATH);
65
65
  if (!coModelName) return [undefined, undefined];
66
- const alias = camelize(coModelName);
66
+ const alias = camelCase(coModelName);
67
67
  return [coModelName, alias];
68
68
  }
69
69
 
@@ -1,4 +1,4 @@
1
- import { camelize } from '@angular-devkit/core/src/utils/strings';
1
+ import { camelCase } from 'lodash';
2
2
  import { Logger } from '@nestjs/common';
3
3
  import { CommonEntity } from 'src/entities/common.entity';
4
4
  import { ModelMetadata } from 'src/entities/model-metadata.entity';
@@ -33,7 +33,7 @@ export class SolidBaseRepository<T extends CommonEntity> extends Repository<T> {
33
33
  }
34
34
 
35
35
  modelSingularName(): string {
36
- return camelize(this.metadata.name);
36
+ return camelCase(this.metadata.name);
37
37
  }
38
38
 
39
39
  async findOneByUserKey(userKeyValue: string | number): Promise<T | null> {
@@ -1,7 +1,7 @@
1
1
  import { Injectable, Logger } from '@nestjs/common';
2
2
  import { DiscoveryService, ModuleRef } from '@nestjs/core';
3
3
  import { getDataSourceToken } from '@nestjs/typeorm';
4
- import { classify } from '@angular-devkit/core/src/utils/strings';
4
+ import { classify } from '../helpers/string.helper';
5
5
  import { DataSource, EntityManager } from 'typeorm';
6
6
  import * as fs from 'fs';
7
7
  import * as path from 'path';
@@ -1511,7 +1511,7 @@
1511
1511
  "encrypt": false,
1512
1512
  "relationType": "many-to-many",
1513
1513
  "relationCoModelSingularName": "roleMetadata",
1514
- "relationCoModelFieldName": "users",
1514
+ "relationCoModelFieldName": "menuItems",
1515
1515
  "relationCreateInverse": true,
1516
1516
  "relationCascade": "set null",
1517
1517
  "relationModelModuleName": "solid-core",
@@ -3780,7 +3780,9 @@
3780
3780
  "audit_insert:audit_insert",
3781
3781
  "audit_update:audit_update",
3782
3782
  "audit_delete:audit_delete",
3783
- "custom:custom"
3783
+ "custom:custom",
3784
+ "note:note",
3785
+ "task:task"
3784
3786
  ]
3785
3787
  },
3786
3788
  {
@@ -3891,6 +3893,21 @@
3891
3893
  "private": false,
3892
3894
  "encrypt": false,
3893
3895
  "isSystem": false
3896
+ },
3897
+ {
3898
+ "name": "status",
3899
+ "displayName": "Message Status",
3900
+ "type": "selectionStatic",
3901
+ "defaultValue": "pending",
3902
+ "length": 256,
3903
+ "required": true,
3904
+ "index": false,
3905
+ "isSystem": false,
3906
+ "selectionValueType": "string",
3907
+ "selectionStaticValues": [
3908
+ "pending:pending",
3909
+ "completed:completed"
3910
+ ]
3894
3911
  }
3895
3912
  ]
3896
3913
  },
@@ -5907,7 +5924,8 @@
5907
5924
  },
5908
5925
  "permissions": [
5909
5926
  "mcp:invoke",
5910
- "agent:invoke"
5927
+ "agent:invoke",
5928
+ "settings:view_encrypted"
5911
5929
  ],
5912
5930
  "roles": [
5913
5931
  {
@@ -5951,6 +5969,7 @@
5951
5969
  "ChatterMessageController.getChatterMessages",
5952
5970
  "ChatterMessageController.postMessage",
5953
5971
  "ChatterMessageController.findMany",
5972
+ "ChatterMessageController.markCompleted",
5954
5973
  "ImportTransactionController.getImportTemplate",
5955
5974
  "ImportTransactionController.getImportInstructions",
5956
5975
  "ImportTransactionController.getImportMappingInfo",
@@ -6408,38 +6427,12 @@
6408
6427
  "modelUserKey": "userActivityHistory"
6409
6428
  },
6410
6429
  {
6411
- "displayName": "App Settings",
6412
- "name": "appSettings-action",
6413
- "type": "custom",
6414
- "domain": "",
6415
- "context": "",
6416
- "customComponent": "/admin/core/solid-core/settings/app-settings",
6417
- "customIsModal": true,
6418
- "serverEndpoint": "",
6419
- "viewUserKey": "",
6420
- "moduleUserKey": "solid-core",
6421
- "modelUserKey": "setting"
6422
- },
6423
- {
6424
- "displayName": "Authentication Settings Action",
6425
- "name": "authenticationSettings-action",
6426
- "type": "custom",
6427
- "domain": "",
6428
- "context": "",
6429
- "customComponent": "/admin/core/solid-core/settings/authentication-settings",
6430
- "customIsModal": true,
6431
- "serverEndpoint": "",
6432
- "viewUserKey": "",
6433
- "moduleUserKey": "solid-core",
6434
- "modelUserKey": "setting"
6435
- },
6436
- {
6437
- "displayName": "Misc Action",
6438
- "name": "miscSettings-action",
6430
+ "displayName": "Settings",
6431
+ "name": "settings-action",
6439
6432
  "type": "custom",
6440
6433
  "domain": "",
6441
6434
  "context": "",
6442
- "customComponent": "/admin/core/solid-core/settings/misc-settings",
6435
+ "customComponent": "/admin/core/settings",
6443
6436
  "customIsModal": true,
6444
6437
  "serverEndpoint": "",
6445
6438
  "viewUserKey": "",
@@ -6920,35 +6913,11 @@
6920
6913
  "displayName": "Settings",
6921
6914
  "name": "settings-menu-item",
6922
6915
  "sequenceNumber": 9,
6923
- "actionUserKey": "",
6916
+ "actionUserKey": "settings-action",
6924
6917
  "moduleUserKey": "solid-core",
6925
6918
  "parentMenuItemUserKey": "",
6926
6919
  "iconName": "settings"
6927
6920
  },
6928
- {
6929
- "displayName": "App Settings",
6930
- "name": "appSettings-menu-item",
6931
- "sequenceNumber": 1,
6932
- "actionUserKey": "appSettings-action",
6933
- "moduleUserKey": "solid-core",
6934
- "parentMenuItemUserKey": "settings-menu-item"
6935
- },
6936
- {
6937
- "displayName": "Authentication Settings",
6938
- "name": "authenticationSettings-menu-item",
6939
- "sequenceNumber": 2,
6940
- "actionUserKey": "authenticationSettings-action",
6941
- "moduleUserKey": "solid-core",
6942
- "parentMenuItemUserKey": "settings-menu-item"
6943
- },
6944
- {
6945
- "displayName": "Misc",
6946
- "name": "miscSettings-menu-item",
6947
- "sequenceNumber": 3,
6948
- "actionUserKey": "miscSettings-action",
6949
- "moduleUserKey": "solid-core",
6950
- "parentMenuItemUserKey": "settings-menu-item"
6951
- },
6952
6921
  {
6953
6922
  "displayName": "Model Sequence",
6954
6923
  "name": "modelSequence-menu-item",
@@ -10518,7 +10487,7 @@
10518
10487
  "edit": true,
10519
10488
  "delete": true,
10520
10489
  "groupBy": "stage",
10521
- "draggable": true,
10490
+ "draggable": false,
10522
10491
  "allowedViews": [
10523
10492
  "list",
10524
10493
  "kanban"
@@ -6,6 +6,7 @@ import {
6
6
  UnauthorizedException,
7
7
  } from '@nestjs/common';
8
8
  import { createHash, randomBytes } from 'crypto';
9
+ import { ERROR_MESSAGES } from 'src/constants/error-messages';
9
10
  import { CreateApiKeyDto } from 'src/dtos/create-api-key.dto';
10
11
  import { UpdateApiKeyDto } from 'src/dtos/update-api-key.dto';
11
12
  import { UserApiKey } from 'src/entities/user-api-key.entity';
@@ -13,6 +14,8 @@ import { User } from 'src/entities/user.entity';
13
14
  import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
14
15
  import { UserApiKeyRepository } from 'src/repository/user-api-key.repository';
15
16
  import { PermissionMetadataService } from 'src/services/permission-metadata.service';
17
+ import { AuthenticationService } from './authentication.service';
18
+ import { UserRepository } from 'src/repository/user.repository';
16
19
 
17
20
  @Injectable()
18
21
  export class ApiKeyService {
@@ -21,53 +24,55 @@ export class ApiKeyService {
21
24
  constructor(
22
25
  private readonly apiKeyRepository: UserApiKeyRepository,
23
26
  private readonly permissionMetadataService: PermissionMetadataService,
27
+ private readonly authenticationService: AuthenticationService,
28
+ private readonly userRepository: UserRepository,
24
29
  ) {}
25
30
 
26
- async generate(userId: number, dto: CreateApiKeyDto): Promise<{ apiKey: string; record: UserApiKey }> {
27
- const user = await this.apiKeyRepository.manager.findOne(User, {
28
- where: { id: userId },
29
- select: ['id', 'isAllowedToGenerateApiKeys'],
30
- });
31
+ async generate(userId: number, dto: CreateApiKeyDto): Promise < { apiKey: string; record: UserApiKey } > {
32
+ const user = await this.apiKeyRepository.manager.findOne(User, {
33
+ where: { id: userId },
34
+ select: ['id', 'isAllowedToGenerateApiKeys'],
35
+ });
31
36
 
32
- if (!user?.isAllowedToGenerateApiKeys) {
33
- throw new ForbiddenException('You are not allowed to generate API keys');
34
- }
37
+ if(!user?.isAllowedToGenerateApiKeys) {
38
+ throw new ForbiddenException('You are not allowed to generate API keys');
39
+ }
35
40
 
36
41
  const rawKey = 'sldx_' + randomBytes(32).toString('hex');
37
- const hashedKey = this.hash(rawKey);
38
- const maskedKey = 'sldx_****' + rawKey.slice(-4);
39
-
40
- const record = this.apiKeyRepository.create({
41
- name: dto.name,
42
- hashedKey,
43
- maskedKey,
44
- isActive: true,
45
- expiresAt: dto.expiresAt ? new Date(dto.expiresAt) : null,
46
- user,
47
- });
42
+ const hashedKey = this.hash(rawKey);
43
+ const maskedKey = 'sldx_****' + rawKey.slice(-4);
48
44
 
49
- await this.apiKeyRepository.save(record);
45
+ const record = this.apiKeyRepository.create({
46
+ name: dto.name,
47
+ hashedKey,
48
+ maskedKey,
49
+ isActive: true,
50
+ expiresAt: dto.expiresAt ? new Date(dto.expiresAt) : null,
51
+ user,
52
+ });
50
53
 
51
- // Strip hashedKey from the returned record — maskedKey is all the UI needs
52
- delete (record as any).hashedKey;
54
+ await this.apiKeyRepository.save(record);
53
55
 
54
- return { apiKey: rawKey, record };
55
- }
56
+ // Strip hashedKey from the returned record — maskedKey is all the UI needs
57
+ delete(record as any).hashedKey;
56
58
 
57
- async validate(rawKey: string): Promise<ActiveUserData> {
58
- const hashedKey = this.hash(rawKey);
59
+ return { apiKey: rawKey, record };
60
+ }
59
61
 
60
- // Bypass security rules for auth validation — must find the key regardless of caller context
61
- const keyRecord = await this.apiKeyRepository.findOne({
62
- where: { hashedKey, isActive: true },
63
- relations: ['user', 'user.roles'],
64
- });
62
+ async validate(rawKey: string): Promise < ActiveUserData > {
63
+ const hashedKey = this.hash(rawKey);
65
64
 
66
- if (!keyRecord) {
67
- throw new UnauthorizedException();
68
- }
65
+ // Bypass security rules for auth validation — must find the key regardless of caller context
66
+ const keyRecord = await this.apiKeyRepository.findOne({
67
+ where: { hashedKey, isActive: true },
68
+ relations: ['user', 'user.roles'],
69
+ });
69
70
 
70
- if (keyRecord.expiresAt && keyRecord.expiresAt < new Date()) {
71
+ if(!keyRecord) {
72
+ throw new UnauthorizedException();
73
+ }
74
+
75
+ if(keyRecord.expiresAt && keyRecord.expiresAt < new Date()) {
71
76
  throw new UnauthorizedException('API key expired');
72
77
  }
73
78
 
@@ -105,6 +110,43 @@ export class ApiKeyService {
105
110
  .execute();
106
111
  }
107
112
 
113
+
114
+ async apiKeyMe(apiKey: string) {
115
+
116
+ const hasedKey = this.hash(apiKey);
117
+ const apiKeyRecord = await this.apiKeyRepository.findOne({
118
+ where: {
119
+ hashedKey: hasedKey,
120
+ },
121
+ relations: {
122
+ user: {
123
+ roles: true
124
+ }
125
+ }
126
+ });
127
+
128
+ if (!apiKeyRecord) {
129
+ throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);
130
+ }
131
+
132
+ const user = apiKeyRecord.user;
133
+
134
+ const tokens = await this.authenticationService.generateTokens(user);
135
+
136
+
137
+ return {
138
+ user: {
139
+ email: user.email,
140
+ mobile: user.mobile,
141
+ username: user.username,
142
+ forcePasswordChange: user.forcePasswordChange,
143
+ id: user.id,
144
+ roles: user.roles.map((role) => role.name)
145
+ },
146
+ ...tokens
147
+ }
148
+ }
149
+
108
150
  private hash(rawKey: string): string {
109
151
  return createHash('sha256').update(rawKey).digest('hex');
110
152
  }