@solidxai/core 0.1.9-beta.7 → 0.1.9

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 (165) hide show
  1. package/LICENSE +89 -0
  2. package/README.md +3 -1
  3. package/dist/constants/chatter-message.constants.d.ts +6 -0
  4. package/dist/constants/chatter-message.constants.d.ts.map +1 -1
  5. package/dist/constants/chatter-message.constants.js +7 -1
  6. package/dist/constants/chatter-message.constants.js.map +1 -1
  7. package/dist/controllers/authentication.controller.d.ts +12 -0
  8. package/dist/controllers/authentication.controller.d.ts.map +1 -1
  9. package/dist/controllers/authentication.controller.js +13 -0
  10. package/dist/controllers/authentication.controller.js.map +1 -1
  11. package/dist/controllers/chatter-message.controller.d.ts +1 -0
  12. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  13. package/dist/controllers/chatter-message.controller.js +12 -0
  14. package/dist/controllers/chatter-message.controller.js.map +1 -1
  15. package/dist/controllers/facebook-authentication.controller.d.ts +27 -0
  16. package/dist/controllers/facebook-authentication.controller.d.ts.map +1 -0
  17. package/dist/controllers/facebook-authentication.controller.js +117 -0
  18. package/dist/controllers/facebook-authentication.controller.js.map +1 -0
  19. package/dist/controllers/menu-item-metadata.controller.d.ts +1 -0
  20. package/dist/controllers/menu-item-metadata.controller.d.ts.map +1 -1
  21. package/dist/controllers/menu-item-metadata.controller.js +15 -0
  22. package/dist/controllers/menu-item-metadata.controller.js.map +1 -1
  23. package/dist/controllers/microsoft-authentication.controller.d.ts +27 -0
  24. package/dist/controllers/microsoft-authentication.controller.d.ts.map +1 -0
  25. package/dist/controllers/microsoft-authentication.controller.js +118 -0
  26. package/dist/controllers/microsoft-authentication.controller.js.map +1 -0
  27. package/dist/controllers/setting.controller.d.ts +2 -2
  28. package/dist/controllers/setting.controller.js +2 -2
  29. package/dist/decorators/auth.decorator.d.ts.map +1 -1
  30. package/dist/decorators/computed-field-provider.decorator.d.ts.map +1 -1
  31. package/dist/decorators/dashboard-question-data-provider.decorator.d.ts.map +1 -1
  32. package/dist/decorators/dashboard-selection-provider.decorator.d.ts.map +1 -1
  33. package/dist/decorators/disallow-in-production.decorator.d.ts.map +1 -1
  34. package/dist/decorators/error-codes-provider.decorator.d.ts.map +1 -1
  35. package/dist/decorators/extension-user-creation-provider.decorator.d.ts.map +1 -1
  36. package/dist/decorators/is-not-in-enum.decorator.d.ts.map +1 -1
  37. package/dist/decorators/mail-provider.decorator.d.ts.map +1 -1
  38. package/dist/decorators/roles.decorator.d.ts.map +1 -1
  39. package/dist/decorators/scheduled-job-provider.decorator.d.ts.map +1 -1
  40. package/dist/decorators/security-rule-config-provider.decorator.d.ts.map +1 -1
  41. package/dist/decorators/selection-provider.decorator.d.ts.map +1 -1
  42. package/dist/decorators/sms-provider.decorator.d.ts.map +1 -1
  43. package/dist/decorators/solid-database-module.decorator.d.ts.map +1 -1
  44. package/dist/decorators/whatsapp-provider.decorator.d.ts.map +1 -1
  45. package/dist/dtos/create-chatter-message.dto.d.ts +1 -0
  46. package/dist/dtos/create-chatter-message.dto.d.ts.map +1 -1
  47. package/dist/dtos/create-chatter-message.dto.js +7 -1
  48. package/dist/dtos/create-chatter-message.dto.js.map +1 -1
  49. package/dist/dtos/post-chatter-message.dto.d.ts +1 -0
  50. package/dist/dtos/post-chatter-message.dto.d.ts.map +1 -1
  51. package/dist/dtos/post-chatter-message.dto.js +6 -1
  52. package/dist/dtos/post-chatter-message.dto.js.map +1 -1
  53. package/dist/dtos/update-chatter-message.dto.d.ts +1 -0
  54. package/dist/dtos/update-chatter-message.dto.d.ts.map +1 -1
  55. package/dist/dtos/update-chatter-message.dto.js +7 -1
  56. package/dist/dtos/update-chatter-message.dto.js.map +1 -1
  57. package/dist/entities/chatter-message.entity.d.ts +1 -0
  58. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  59. package/dist/entities/chatter-message.entity.js +5 -1
  60. package/dist/entities/chatter-message.entity.js.map +1 -1
  61. package/dist/entities/user.entity.d.ts +8 -0
  62. package/dist/entities/user.entity.d.ts.map +1 -1
  63. package/dist/entities/user.entity.js +33 -1
  64. package/dist/entities/user.entity.js.map +1 -1
  65. package/dist/helpers/cors.helper.js +1 -1
  66. package/dist/helpers/cors.helper.js.map +1 -1
  67. package/dist/helpers/facebook-oauth.helper.d.ts +8 -0
  68. package/dist/helpers/facebook-oauth.helper.d.ts.map +1 -0
  69. package/dist/helpers/facebook-oauth.helper.js +11 -0
  70. package/dist/helpers/facebook-oauth.helper.js.map +1 -0
  71. package/dist/helpers/microsoft-oauth.helper.d.ts +9 -0
  72. package/dist/helpers/microsoft-oauth.helper.d.ts.map +1 -0
  73. package/dist/helpers/microsoft-oauth.helper.js +12 -0
  74. package/dist/helpers/microsoft-oauth.helper.js.map +1 -0
  75. package/dist/helpers/security.helper.d.ts.map +1 -1
  76. package/dist/helpers/string.helper.d.ts.map +1 -1
  77. package/dist/helpers/user-helper.d.ts.map +1 -1
  78. package/dist/helpers/user-helper.js +4 -0
  79. package/dist/helpers/user-helper.js.map +1 -1
  80. package/dist/index.d.ts +2 -0
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +2 -0
  83. package/dist/index.js.map +1 -1
  84. package/dist/interfaces.d.ts +19 -0
  85. package/dist/interfaces.d.ts.map +1 -1
  86. package/dist/interfaces.js.map +1 -1
  87. package/dist/passport-strategies/facebook-oauth.strategy.d.ts +16 -0
  88. package/dist/passport-strategies/facebook-oauth.strategy.d.ts.map +1 -0
  89. package/dist/passport-strategies/facebook-oauth.strategy.js +96 -0
  90. package/dist/passport-strategies/facebook-oauth.strategy.js.map +1 -0
  91. package/dist/passport-strategies/microsoft-oauth.strategy.d.ts +14 -0
  92. package/dist/passport-strategies/microsoft-oauth.strategy.d.ts.map +1 -0
  93. package/dist/passport-strategies/microsoft-oauth.strategy.js +77 -0
  94. package/dist/passport-strategies/microsoft-oauth.strategy.js.map +1 -0
  95. package/dist/seeders/seed-data/solid-core-metadata.json +27 -58
  96. package/dist/services/api-key.service.d.ts +17 -1
  97. package/dist/services/api-key.service.d.ts.map +1 -1
  98. package/dist/services/api-key.service.js +38 -2
  99. package/dist/services/api-key.service.js.map +1 -1
  100. package/dist/services/authentication.service.d.ts +61 -27
  101. package/dist/services/authentication.service.d.ts.map +1 -1
  102. package/dist/services/authentication.service.js +356 -164
  103. package/dist/services/authentication.service.js.map +1 -1
  104. package/dist/services/chatter-message.service.d.ts +1 -0
  105. package/dist/services/chatter-message.service.d.ts.map +1 -1
  106. package/dist/services/chatter-message.service.js +24 -7
  107. package/dist/services/chatter-message.service.js.map +1 -1
  108. package/dist/services/crud-helper.service.d.ts.map +1 -1
  109. package/dist/services/model-metadata.service.js +1 -1
  110. package/dist/services/model-metadata.service.js.map +1 -1
  111. package/dist/services/setting.service.d.ts +5 -2
  112. package/dist/services/setting.service.d.ts.map +1 -1
  113. package/dist/services/setting.service.js +51 -6
  114. package/dist/services/setting.service.js.map +1 -1
  115. package/dist/services/settings/default-settings-provider.service.d.ts +846 -0
  116. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  117. package/dist/services/settings/default-settings-provider.service.js +1096 -117
  118. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  119. package/dist/services/user.service.d.ts +12 -8
  120. package/dist/services/user.service.d.ts.map +1 -1
  121. package/dist/services/user.service.js +143 -32
  122. package/dist/services/user.service.js.map +1 -1
  123. package/dist/solid-core.module.d.ts.map +1 -1
  124. package/dist/solid-core.module.js +11 -3
  125. package/dist/solid-core.module.js.map +1 -1
  126. package/dist/transformers/array-transformer.d.ts.map +1 -1
  127. package/dist/transformers/boolean-transformer.d.ts.map +1 -1
  128. package/dist/transformers/datetime-transformer.d.ts.map +1 -1
  129. package/dist/transformers/integer-transformer.d.ts.map +1 -1
  130. package/dist/validators/is-parsable-int.d.ts.map +1 -1
  131. package/nest +0 -0
  132. package/package.json +8 -2
  133. package/src/constants/chatter-message.constants.ts +7 -0
  134. package/src/controllers/authentication.controller.ts +8 -1
  135. package/src/controllers/chatter-message.controller.ts +6 -0
  136. package/src/controllers/facebook-authentication.controller.ts +113 -0
  137. package/src/controllers/menu-item-metadata.controller.ts +21 -15
  138. package/src/controllers/microsoft-authentication.controller.ts +116 -0
  139. package/src/dtos/create-chatter-message.dto.ts +11 -0
  140. package/src/dtos/post-chatter-message.dto.ts +4 -0
  141. package/src/dtos/update-chatter-message.dto.ts +13 -1
  142. package/src/entities/chatter-message.entity.ts +4 -1
  143. package/src/entities/user.entity.ts +32 -0
  144. package/src/helpers/cors.helper.ts +1 -1
  145. package/src/helpers/facebook-oauth.helper.ts +17 -0
  146. package/src/helpers/microsoft-oauth.helper.ts +19 -0
  147. package/src/helpers/user-helper.ts +4 -0
  148. package/src/index.ts +2 -0
  149. package/src/interfaces.ts +32 -1
  150. package/src/passport-strategies/facebook-oauth.strategy.ts +115 -0
  151. package/src/passport-strategies/microsoft-oauth.strategy.ts +70 -0
  152. package/src/seeders/seed-data/solid-core-metadata.json +27 -58
  153. package/src/services/api-key.service.ts +77 -35
  154. package/src/services/authentication.service.ts +1947 -1432
  155. package/src/services/chatter-message.service.ts +23 -3
  156. package/src/services/model-metadata.service.ts +1 -1
  157. package/src/services/setting.service.ts +64 -8
  158. package/src/services/settings/default-settings-provider.service.ts +1168 -156
  159. package/src/services/user.service.ts +220 -61
  160. package/src/solid-core.module.ts +25 -8
  161. package/dev-grooming-docs/ozzy-prompts.txt +0 -70
  162. package/docs/grouping-enhancements.md +0 -89
  163. package/docs/seed-changes.md +0 -65
  164. package/docs/test-data-workflow.md +0 -200
  165. package/docs/type-declaration-import-issue.md +0 -24
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";;;AA+DA,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,wCAAwB,CAAA;IACxB,6DAA6C,CAAA;IAC7C,6DAA6C,CAAA;IAC7C,8CAA8B,CAAA;AAChC,CAAC,EALW,YAAY,4BAAZ,YAAY,QAKvB;AA2HD,IAAY,SAEX;AAFD,WAAY,SAAS;IACnB,gDAAmC,CAAA;AACrC,CAAC,EAFW,SAAS,yBAAT,SAAS,QAEpB;AAED,MAAa,YAAY;IACvB,YACS,IAAS,EACT,OAAU;QADV,SAAI,GAAJ,IAAI,CAAK;QACT,YAAO,GAAP,OAAO,CAAG;IACf,CAAC;CACN;AALD,oCAKC;AAyED,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,mCAAqB,CAAA;IACrB,mCAAqB,CAAA;IACrB,6BAAe,CAAA;AACjB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["import { Repository } from 'typeorm';\nimport { User } from 'src/entities/user.entity';\nimport { CreateUserDto } from 'src/dtos/create-user.dto';\nimport { CreateEmailTemplateDto } from 'src/dtos/create-email-template.dto';\nimport { CreateSmsTemplateDto } from 'src/dtos/create-sms-template.dto';\nimport { SignUpDto } from 'src/dtos/sign-up.dto';\nimport { Readable } from 'stream';\nimport { CreateMediaStorageProviderMetadataDto } from './dtos/create-media-storage-provider-metadata.dto';\nimport { DatasourceType } from './dtos/create-model-metadata.dto';\nimport { CreateModuleMetadataDto } from './dtos/create-module-metadata.dto';\nimport { CreateRoleMetadataDto } from './dtos/create-role-metadata.dto';\nimport { CreateSecurityRuleDto } from './dtos/create-security-rule.dto';\nimport { FieldMetadata } from './entities/field-metadata.entity';\nimport { Media } from './entities/media.entity';\nimport { DashboardQuestion } from './entities/dashboard-question.entity';\nimport { ComputedFieldMetadata } from './helpers/solid-registry';\nimport { SqlExpression } from './services/question-data-providers/chartjs-sql-data-provider.service';\nimport { CreateDashboardDto } from './dtos/create-dashboard.dto';\nimport { AiInteraction } from './entities/ai-interaction.entity';\nimport { ActiveUserData } from './interfaces/active-user-data.interface';\nimport { SecurityRuleConfig } from './dtos/security-rule-config.dto';\nimport { SecurityRule } from './entities/security-rule.entity';\n\nexport interface FieldCrudManager {\n // fieldMetadata: FieldMetadata;\n // entityManager?: EntityManager;\n // createDto: any;\n // files : Array<Express.Multer.File>;\n validate(\n dto: any,\n files: Array<Express.Multer.File>,\n ): ValidationError[] | Promise<ValidationError[]>;\n transformForCreate(dto: any, ctxt?: any): any | Promise<any>;\n}\n\nexport interface ValidationError {\n field: string;\n error: string;\n}\n\n// export interface MediaStorage\nexport interface MediaStorageProvider<T> {\n store(files: Express.Multer.File[], entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;\n delete(entity: T, mediaFieldMetadata: FieldMetadata): Promise<void>;\n retrieve(entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;\n storeStreams(streamPairs: [Readable, string][], entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;\n // delete(file: string): Promise<void>;\n}\n\nexport interface ModuleMetadataConfiguration {\n moduleMetadata?: CreateModuleMetadataDto,\n roles?: CreateRoleMetadataDto[],\n users?: SignUpDto[],\n actions?: any[],\n menus?: any[],\n views?: any[],\n emailTemplates?: CreateEmailTemplateDto[],\n smsTemplates?: CreateSmsTemplateDto[],\n mediaStorageProviders?: CreateMediaStorageProviderMetadataDto[]\n securityRules?: CreateSecurityRuleDto[],\n dashboards?: CreateDashboardDto[],\n}\n\nexport enum SettingLevel {\n SystemEnv = 'system-env',\n SystemAdminReadonly = 'system-admin-readonly',\n SystemAdminEditable = 'system-admin-editable',\n InternalUser = \"internal-user\"\n}\n\nexport interface SettingDefinition<T = any> {\n moduleName: string;\n key: string;\n value: T;\n level: SettingLevel;\n encrypted?: boolean;\n}\n\n// solid-core/settings/settings-provider.interface.ts\nexport interface ISettingsProvider {\n getSettings(): SettingDefinition[];\n}\n\nexport interface CodeGenerationOptions {\n moduleId?: number;\n moduleUserKey?: string;\n modelId?: number;\n modelUserKey?: string;\n fieldIdsForRemoval?: number[];\n fieldNamesForRemoval?: string[];\n dryRun?: boolean;\n fieldIdsForRefresh?: number[];\n fieldNamesForRefresh?: string[];\n}\n\nexport interface TriggerMcpClientOptions {\n aiInteractionId: number;\n moduleName: string;\n}\n\nexport interface McpResponse {\n success: boolean;\n request: string;\n response: string;\n model?: string;\n tools_invoked?: string[];\n tool_calls?: any[];\n duration_ms?: number;\n errors?: string[];\n error_trace?: string[];\n content_type?: string;\n}\n\nexport interface ISelectionProviderContext {\n limit: number;\n offset: number;\n formValues: Record<string, any>;\n //Attribute to control the validation on creating the record\n validateOnSave?: boolean;\n // query: string;\n}\n\nexport interface ISelectionProviderValues {\n label: string;\n value: string;\n}\n\nexport interface ISelectionProvider<T extends ISelectionProviderContext> {\n help(): string;\n\n name(): string;\n\n value(optionValue: string, ctxt: T): Promise<ISelectionProviderValues | any>;\n\n values(query: any, ctxt: T): Promise<readonly ISelectionProviderValues[]>;\n}\n\nexport interface IDashboardVariableSelectionProvider<T extends ISelectionProviderContext> extends ISelectionProvider<T> {\n}\n\nexport interface IMcpToolResponseHandler {\n apply(aiInteraction: AiInteraction);\n}\n\nexport interface QuestionSqlDataProviderContext {\n // questionSqlDatasetConfig: QuestionSqlDatasetConfig;\n // questionId: number;\n // question: Question;\n expressions?: SqlExpression[]\n}\nexport interface IDashboardQuestionDataProvider<TContext, TData> {\n help(): string;\n\n name(): string;\n\n getData(question: DashboardQuestion, ctxt?: TContext): Promise<TData[] | TData>;\n}\n\n/**\n * @deprecated Use `IEntityComputedFieldProvider` instead.\n */\nexport interface IComputedFieldProvider<T> {\n help(): string;\n\n name(): string;\n\n valueType(): string;\n\n computeValue(dto: any, ctxt: T): Promise<string | number>; // FIXME : Improve the types to make it more specific using generics\n}\n\nexport interface IEntityComputedFieldProvider {\n help(): string;\n\n name(): string;\n}\n\nexport interface IEntityPreComputeFieldProvider<TTriggerEntity, TContext, TValue = void> extends IEntityComputedFieldProvider {\n preComputeValue(triggerEntity: TTriggerEntity, computedFieldMetadata: ComputedFieldMetadata<TContext>): Promise<TValue>;\n}\n\nexport interface IEntityPostComputeFieldProvider<TTriggerEntity, TContext> extends IEntityComputedFieldProvider {\n postComputeAndSaveValue(triggerEntity: TTriggerEntity, computedFieldMetadata: ComputedFieldMetadata<TContext>): Promise<void>;\n}\n\nexport interface ISolidDatabaseModule {\n name(): string;\n\n type(): DatasourceType;\n}\n\nexport enum EventType {\n USER_REGISTERED = 'user.registered',\n}\n\nexport class EventDetails<T> {\n constructor(\n public type: any,\n public payload: T,\n ) { }\n}\n\nexport interface IExtensionUserCreationProvider<T extends User = User, TDto extends CreateUserDto = CreateUserDto> {\n readonly repo: Repository<T>;\n buildExtensionEntity(dto: TDto): Promise<T>;\n roles(dto: TDto): string[];\n}\n\nexport interface IMail<TResponse = unknown> {\n sendEmail(\n to: string,\n subject: string,\n body: string,\n shouldQueueEmails: boolean,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string,\n ): Promise<TResponse>;\n\n sendEmailUsingTemplate(\n to: string,\n templateName: string,\n templateParams: any,\n shouldQueueEmails: boolean,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string,\n ): Promise<TResponse>;\n}\n\nexport interface ISMS {\n sendSMS(to: string, body: string, shouldQueueSms: boolean): Promise<any>;\n\n sendSMSUsingTemplate(\n to: string,\n templateName: string,\n templateParams: any,\n shouldQueueSms: boolean,\n ): Promise<any>;\n}\n\nexport interface IWhatsAppTransport {\n sendWhatsAppMessage(\n to: string,\n templateId: string,\n parameters: any,\n parentEntity?: any,\n parentEntityId?: any\n ): Promise<any>;\n}\n\nexport interface MailAttachmentWrapper {\n relativePath?: string;\n attachment?: MailAttachment;\n}\n\nexport interface MailAttachment {\n filename: string;\n templatePath?: string; // deprecated\n templateParams?: any; // deprecated\n content?: string | Buffer;\n contentType?: string;\n path?: string; //Filesystem absolute path or URL. \n}\n\nexport enum BrokerType {\n RabbitMQ = 'rabbitmq',\n Database = 'database',\n Redis = 'redis',\n}\n\nexport interface QueuesModuleOptions {\n name: string;\n type: BrokerType;\n queueName: string;\n prefetch?: number;\n persistToDatabase?: boolean;\n}\n\nexport type MediaWithFullUrl = Media & {\n _full_url: string;\n};\n\n\nexport type ErrorCode = string;\n\nexport type ErrorMeta = {\n message: string;\n httpStatus?: number;\n};\n\nexport type ErrorRule = {\n /** Canonical error code. Keep them kebab-case for consistency. */\n code: ErrorCode;\n /** Higher runs earlier. Defaults to 0 if not provided. */\n priority?: number;\n /** Return true if this rule matches the combined error text. */\n match: (combinedErrorText: string) => boolean;\n /** Display + HTTP mapping for this code. */\n meta: ErrorMeta;\n};\n\nexport interface IErrorCodeProvider {\n /** Used for registry identity & logs */\n name(): string;\n\n /**\n * Return all rules this provider contributes.\n * These will be merged with other providers’ rules, then sorted by priority.\n */\n rules(): ReadonlyArray<ErrorRule>;\n\n /**\n * Optional fallback meta for codes this provider owns (when called by getMessage/getHttpStatus).\n * If omitted, the ErrorMapperService will rely on the rule.meta of the first matching rule.\n */\n resolve?(code: ErrorCode): ErrorMeta | undefined;\n}\n\n// MCP Tool Related\n\nexport type PlanStep = CreateNewFileStep | RegisterNestProviderStep | AddMethodToExistingClassStep | RegisterSolidXExtensionComponentStep | AddListViewButtonStep | AddFormViewButtonStep | AddImportStep;\nexport interface AddImportStep {\n type: \"addImport\";\n path: string; // e.g. apps/api/src/address-master/services/address-master.service.ts\n importStatement: string; // e.g. import { Something } from 'somewhere';\n overwrite?: boolean; // default=false\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface CreateNewFileStep {\n type: \"createNewFile\";\n path: string; // repo-relative e.g. solid-api/api/src/computed-providers/foo.provider.ts\n content: string; // full file content\n overwrite?: boolean; // default=false\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface RegisterNestProviderStep {\n type: \"registerNestProvider\";\n modulePath: string; // e.g. apps/api/src/address-master/address-master.module.ts\n providerClassName: string; // e.g. StateTotalCitiesComputedFieldProvider\n importFrom: string; // e.g. \"@/computed-providers/state-total-cities.provider\"\n registerIn: Array<\"providers\" | \"exports\">; // which arrays to add to\n uniqueGuard?: boolean; // default=true\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface AddMethodToExistingClassStep {\n type: \"addMethodToExistingClass\";\n path: string; // e.g. apps/api/src/address-master/services/address-master.service.ts\n className: string // e.g. CountryService\n methodName: string // e.g. addCountry\n content: string // Full Method Code\n importStatements?: string[]; // e.g. [ \"import { X } from 'y';\" ]\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface RegisterSolidXExtensionComponentStep {\n type: \"registerSolidXExtensionComponent\";\n path: string; // e.g. apps/api/src/address-master/services/address-master.service.ts\n content?: string; // Code\n importExtensionComponent?: string;\n}\n\nexport interface AddListViewButtonStep {\n type: \"addListViewButton\";\n moduleName?: string;\n modelName?: string;\n buttonType?: string;\n content?: string; // Code\n}\n\nexport interface AddFormViewButtonStep {\n type: \"addFormViewButton\";\n moduleName?: string;\n modelName?: string;\n buttonType?: string;\n content?: string; // Code\n}\n\nexport interface McpComputedProviderResponse {\n plan: PlanStep[];\n // provider?: any; // (intentionally ignored per your note)\n}\n\nexport interface ISecurityRuleConfigProvider {\n securityRuleConfig(activeUser: ActiveUserData, securityRule: SecurityRule): Promise<SecurityRuleConfig>;\n}\n\n\nexport interface AwsS3Config {\n S3_AWS_ACCESS_KEY: string;\n S3_AWS_SECRET_KEY: string;\n S3_AWS_REGION_NAME: string;\n}\n\n// Prevents inference so callers must provide explicit type arguments; reusable for other APIs.\nexport type NoInfer<T> = [T][T extends any ? 0 : never];\n\nexport type AuditEventType = 'insert' | 'update' | 'delete';\n\nexport interface AuditQueuePayload {\n eventType: AuditEventType;\n modelName: string;\n entityId: string | number | null;\n occurredAt: string;\n after?: any;\n before?: any;\n updatedColumnNames?: string[];\n userId?: number | null;\n}\n\n\n"]}
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";;;AA+DA,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,wCAAwB,CAAA;IACxB,6DAA6C,CAAA;IAC7C,6DAA6C,CAAA;IAC7C,8CAA8B,CAAA;AAChC,CAAC,EALW,YAAY,4BAAZ,YAAY,QAKvB;AA2JD,IAAY,SAEX;AAFD,WAAY,SAAS;IACnB,gDAAmC,CAAA;AACrC,CAAC,EAFW,SAAS,yBAAT,SAAS,QAEpB;AAED,MAAa,YAAY;IACvB,YACS,IAAS,EACT,OAAU;QADV,SAAI,GAAJ,IAAI,CAAK;QACT,YAAO,GAAP,OAAO,CAAG;IACf,CAAC;CACN;AALD,oCAKC;AAyED,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,mCAAqB,CAAA;IACrB,mCAAqB,CAAA;IACrB,6BAAe,CAAA;AACjB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["import { Repository } from 'typeorm';\nimport { User } from 'src/entities/user.entity';\nimport { CreateUserDto } from 'src/dtos/create-user.dto';\nimport { CreateEmailTemplateDto } from 'src/dtos/create-email-template.dto';\nimport { CreateSmsTemplateDto } from 'src/dtos/create-sms-template.dto';\nimport { SignUpDto } from 'src/dtos/sign-up.dto';\nimport { Readable } from 'stream';\nimport { CreateMediaStorageProviderMetadataDto } from './dtos/create-media-storage-provider-metadata.dto';\nimport { DatasourceType } from './dtos/create-model-metadata.dto';\nimport { CreateModuleMetadataDto } from './dtos/create-module-metadata.dto';\nimport { CreateRoleMetadataDto } from './dtos/create-role-metadata.dto';\nimport { CreateSecurityRuleDto } from './dtos/create-security-rule.dto';\nimport { FieldMetadata } from './entities/field-metadata.entity';\nimport { Media } from './entities/media.entity';\nimport { DashboardQuestion } from './entities/dashboard-question.entity';\nimport { ComputedFieldMetadata } from './helpers/solid-registry';\nimport { SqlExpression } from './services/question-data-providers/chartjs-sql-data-provider.service';\nimport { CreateDashboardDto } from './dtos/create-dashboard.dto';\nimport { AiInteraction } from './entities/ai-interaction.entity';\nimport { ActiveUserData } from './interfaces/active-user-data.interface';\nimport { SecurityRuleConfig } from './dtos/security-rule-config.dto';\nimport { SecurityRule } from './entities/security-rule.entity';\n\nexport interface FieldCrudManager {\n // fieldMetadata: FieldMetadata;\n // entityManager?: EntityManager;\n // createDto: any;\n // files : Array<Express.Multer.File>;\n validate(\n dto: any,\n files: Array<Express.Multer.File>,\n ): ValidationError[] | Promise<ValidationError[]>;\n transformForCreate(dto: any, ctxt?: any): any | Promise<any>;\n}\n\nexport interface ValidationError {\n field: string;\n error: string;\n}\n\n// export interface MediaStorage\nexport interface MediaStorageProvider<T> {\n store(files: Express.Multer.File[], entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;\n delete(entity: T, mediaFieldMetadata: FieldMetadata): Promise<void>;\n retrieve(entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;\n storeStreams(streamPairs: [Readable, string][], entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;\n // delete(file: string): Promise<void>;\n}\n\nexport interface ModuleMetadataConfiguration {\n moduleMetadata?: CreateModuleMetadataDto,\n roles?: CreateRoleMetadataDto[],\n users?: SignUpDto[],\n actions?: any[],\n menus?: any[],\n views?: any[],\n emailTemplates?: CreateEmailTemplateDto[],\n smsTemplates?: CreateSmsTemplateDto[],\n mediaStorageProviders?: CreateMediaStorageProviderMetadataDto[]\n securityRules?: CreateSecurityRuleDto[],\n dashboards?: CreateDashboardDto[],\n}\n\nexport enum SettingLevel {\n SystemEnv = 'system-env',\n SystemAdminReadonly = 'system-admin-readonly',\n SystemAdminEditable = 'system-admin-editable',\n InternalUser = \"internal-user\"\n}\n\nexport type SettingControlType =\n | 'shortText'\n | 'longText'\n | 'numeric'\n | 'boolean'\n | 'date'\n | 'datetime'\n | 'mediaSingle'\n | 'selectionStatic'\n | 'custom';\n\nexport interface SettingOption {\n label: string;\n value: string | number | boolean;\n}\n\nexport interface SettingDefinition<T = any> {\n moduleName: string;\n key: string;\n value: T;\n level: SettingLevel;\n encrypted?: boolean;\n label?: string;\n description?: string;\n placeholder?: string;\n group?: string;\n sortOrder?: number;\n controlType?: SettingControlType;\n options?: SettingOption[];\n settingsWidget?: string; // for custom controlType, specify the frontend widget to use\n}\n\nexport interface AdminSettingDefinition<T = any> extends SettingDefinition<T> {\n editable: boolean;\n}\n\nexport interface AdminSettingsResponse<T = any> {\n data: AdminSettingDefinition<T>[];\n}\n\n// solid-core/settings/settings-provider.interface.ts\nexport interface ISettingsProvider {\n getSettings(): SettingDefinition[];\n}\n\nexport interface CodeGenerationOptions {\n moduleId?: number;\n moduleUserKey?: string;\n modelId?: number;\n modelUserKey?: string;\n fieldIdsForRemoval?: number[];\n fieldNamesForRemoval?: string[];\n dryRun?: boolean;\n fieldIdsForRefresh?: number[];\n fieldNamesForRefresh?: string[];\n}\n\nexport interface TriggerMcpClientOptions {\n aiInteractionId: number;\n moduleName: string;\n}\n\nexport interface McpResponse {\n success: boolean;\n request: string;\n response: string;\n model?: string;\n tools_invoked?: string[];\n tool_calls?: any[];\n duration_ms?: number;\n errors?: string[];\n error_trace?: string[];\n content_type?: string;\n}\n\nexport interface ISelectionProviderContext {\n limit: number;\n offset: number;\n formValues: Record<string, any>;\n //Attribute to control the validation on creating the record\n validateOnSave?: boolean;\n // query: string;\n}\n\nexport interface ISelectionProviderValues {\n label: string;\n value: string;\n}\n\nexport interface ISelectionProvider<T extends ISelectionProviderContext> {\n help(): string;\n\n name(): string;\n\n value(optionValue: string, ctxt: T): Promise<ISelectionProviderValues | any>;\n\n values(query: any, ctxt: T): Promise<readonly ISelectionProviderValues[]>;\n}\n\nexport interface IDashboardVariableSelectionProvider<T extends ISelectionProviderContext> extends ISelectionProvider<T> {\n}\n\nexport interface IMcpToolResponseHandler {\n apply(aiInteraction: AiInteraction);\n}\n\nexport interface QuestionSqlDataProviderContext {\n // questionSqlDatasetConfig: QuestionSqlDatasetConfig;\n // questionId: number;\n // question: Question;\n expressions?: SqlExpression[]\n}\nexport interface IDashboardQuestionDataProvider<TContext, TData> {\n help(): string;\n\n name(): string;\n\n getData(question: DashboardQuestion, ctxt?: TContext): Promise<TData[] | TData>;\n}\n\n/**\n * @deprecated Use `IEntityComputedFieldProvider` instead.\n */\nexport interface IComputedFieldProvider<T> {\n help(): string;\n\n name(): string;\n\n valueType(): string;\n\n computeValue(dto: any, ctxt: T): Promise<string | number>; // FIXME : Improve the types to make it more specific using generics\n}\n\nexport interface IEntityComputedFieldProvider {\n help(): string;\n\n name(): string;\n}\n\nexport interface IEntityPreComputeFieldProvider<TTriggerEntity, TContext, TValue = void> extends IEntityComputedFieldProvider {\n preComputeValue(triggerEntity: TTriggerEntity, computedFieldMetadata: ComputedFieldMetadata<TContext>): Promise<TValue>;\n}\n\nexport interface IEntityPostComputeFieldProvider<TTriggerEntity, TContext> extends IEntityComputedFieldProvider {\n postComputeAndSaveValue(triggerEntity: TTriggerEntity, computedFieldMetadata: ComputedFieldMetadata<TContext>): Promise<void>;\n}\n\nexport interface ISolidDatabaseModule {\n name(): string;\n\n type(): DatasourceType;\n}\n\nexport enum EventType {\n USER_REGISTERED = 'user.registered',\n}\n\nexport class EventDetails<T> {\n constructor(\n public type: any,\n public payload: T,\n ) { }\n}\n\nexport interface IExtensionUserCreationProvider<T extends User = User, TDto extends CreateUserDto = CreateUserDto> {\n readonly repo: Repository<T>;\n buildExtensionEntity(dto: TDto): Promise<T>;\n roles(dto: TDto): string[];\n}\n\nexport interface IMail<TResponse = unknown> {\n sendEmail(\n to: string,\n subject: string,\n body: string,\n shouldQueueEmails: boolean,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string,\n ): Promise<TResponse>;\n\n sendEmailUsingTemplate(\n to: string,\n templateName: string,\n templateParams: any,\n shouldQueueEmails: boolean,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string,\n ): Promise<TResponse>;\n}\n\nexport interface ISMS {\n sendSMS(to: string, body: string, shouldQueueSms: boolean): Promise<any>;\n\n sendSMSUsingTemplate(\n to: string,\n templateName: string,\n templateParams: any,\n shouldQueueSms: boolean,\n ): Promise<any>;\n}\n\nexport interface IWhatsAppTransport {\n sendWhatsAppMessage(\n to: string,\n templateId: string,\n parameters: any,\n parentEntity?: any,\n parentEntityId?: any\n ): Promise<any>;\n}\n\nexport interface MailAttachmentWrapper {\n relativePath?: string;\n attachment?: MailAttachment;\n}\n\nexport interface MailAttachment {\n filename: string;\n templatePath?: string; // deprecated\n templateParams?: any; // deprecated\n content?: string | Buffer;\n contentType?: string;\n path?: string; //Filesystem absolute path or URL. \n}\n\nexport enum BrokerType {\n RabbitMQ = 'rabbitmq',\n Database = 'database',\n Redis = 'redis',\n}\n\nexport interface QueuesModuleOptions {\n name: string;\n type: BrokerType;\n queueName: string;\n prefetch?: number;\n persistToDatabase?: boolean;\n}\n\nexport type MediaWithFullUrl = Media & {\n _full_url: string;\n};\n\n\nexport type ErrorCode = string;\n\nexport type ErrorMeta = {\n message: string;\n httpStatus?: number;\n};\n\nexport type ErrorRule = {\n /** Canonical error code. Keep them kebab-case for consistency. */\n code: ErrorCode;\n /** Higher runs earlier. Defaults to 0 if not provided. */\n priority?: number;\n /** Return true if this rule matches the combined error text. */\n match: (combinedErrorText: string) => boolean;\n /** Display + HTTP mapping for this code. */\n meta: ErrorMeta;\n};\n\nexport interface IErrorCodeProvider {\n /** Used for registry identity & logs */\n name(): string;\n\n /**\n * Return all rules this provider contributes.\n * These will be merged with other providers’ rules, then sorted by priority.\n */\n rules(): ReadonlyArray<ErrorRule>;\n\n /**\n * Optional fallback meta for codes this provider owns (when called by getMessage/getHttpStatus).\n * If omitted, the ErrorMapperService will rely on the rule.meta of the first matching rule.\n */\n resolve?(code: ErrorCode): ErrorMeta | undefined;\n}\n\n// MCP Tool Related\n\nexport type PlanStep = CreateNewFileStep | RegisterNestProviderStep | AddMethodToExistingClassStep | RegisterSolidXExtensionComponentStep | AddListViewButtonStep | AddFormViewButtonStep | AddImportStep;\nexport interface AddImportStep {\n type: \"addImport\";\n path: string; // e.g. apps/api/src/address-master/services/address-master.service.ts\n importStatement: string; // e.g. import { Something } from 'somewhere';\n overwrite?: boolean; // default=false\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface CreateNewFileStep {\n type: \"createNewFile\";\n path: string; // repo-relative e.g. solid-api/api/src/computed-providers/foo.provider.ts\n content: string; // full file content\n overwrite?: boolean; // default=false\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface RegisterNestProviderStep {\n type: \"registerNestProvider\";\n modulePath: string; // e.g. apps/api/src/address-master/address-master.module.ts\n providerClassName: string; // e.g. StateTotalCitiesComputedFieldProvider\n importFrom: string; // e.g. \"@/computed-providers/state-total-cities.provider\"\n registerIn: Array<\"providers\" | \"exports\">; // which arrays to add to\n uniqueGuard?: boolean; // default=true\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface AddMethodToExistingClassStep {\n type: \"addMethodToExistingClass\";\n path: string; // e.g. apps/api/src/address-master/services/address-master.service.ts\n className: string // e.g. CountryService\n methodName: string // e.g. addCountry\n content: string // Full Method Code\n importStatements?: string[]; // e.g. [ \"import { X } from 'y';\" ]\n rationale?: string; // optional, ignored by executor\n}\n\nexport interface RegisterSolidXExtensionComponentStep {\n type: \"registerSolidXExtensionComponent\";\n path: string; // e.g. apps/api/src/address-master/services/address-master.service.ts\n content?: string; // Code\n importExtensionComponent?: string;\n}\n\nexport interface AddListViewButtonStep {\n type: \"addListViewButton\";\n moduleName?: string;\n modelName?: string;\n buttonType?: string;\n content?: string; // Code\n}\n\nexport interface AddFormViewButtonStep {\n type: \"addFormViewButton\";\n moduleName?: string;\n modelName?: string;\n buttonType?: string;\n content?: string; // Code\n}\n\nexport interface McpComputedProviderResponse {\n plan: PlanStep[];\n // provider?: any; // (intentionally ignored per your note)\n}\n\nexport interface ISecurityRuleConfigProvider {\n securityRuleConfig(activeUser: ActiveUserData, securityRule: SecurityRule): Promise<SecurityRuleConfig>;\n}\n\n\nexport interface AwsS3Config {\n S3_AWS_ACCESS_KEY: string;\n S3_AWS_SECRET_KEY: string;\n S3_AWS_REGION_NAME: string;\n}\n\n// Prevents inference so callers must provide explicit type arguments; reusable for other APIs.\nexport type NoInfer<T> = [T][T extends any ? 0 : never];\n\nexport type AuditEventType = 'insert' | 'update' | 'delete';\n\nexport interface AuditQueuePayload {\n eventType: AuditEventType;\n modelName: string;\n entityId: string | number | null;\n occurredAt: string;\n after?: any;\n before?: any;\n updatedColumnNames?: string[];\n userId?: number | null;\n}\n\n"]}
@@ -0,0 +1,16 @@
1
+ import { Strategy } from "passport-facebook";
2
+ import { SettingService } from "../services/setting.service";
3
+ import { UserService } from "../services/user.service";
4
+ declare const FacebookOauthGuard_base: import("@nestjs/passport").Type<import("@nestjs/passport").IAuthGuard>;
5
+ export declare class FacebookOauthGuard extends FacebookOauthGuard_base {
6
+ }
7
+ declare const FacebookOAuthStrategy_base: new (...args: any[]) => Strategy;
8
+ export declare class FacebookOAuthStrategy extends FacebookOAuthStrategy_base {
9
+ private readonly userService;
10
+ private readonly settingService;
11
+ private readonly logger;
12
+ constructor(userService: UserService, settingService: SettingService);
13
+ validate(_accessToken: string, _refreshToken: string, profile: any, done: any): Promise<any>;
14
+ }
15
+ export {};
16
+ //# sourceMappingURL=facebook-oauth.strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facebook-oauth.strategy.d.ts","sourceRoot":"","sources":["../../src/passport-strategies/facebook-oauth.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAO7C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;;AAMvD,qBACa,kBAAmB,SAAQ,uBAAqB;CAAG;;AAEhE,qBACa,qBAAsB,SAAQ,0BAG1C;IAIG,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAJjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;gBAG9C,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,cAAc;IAgD3C,QAAQ,CACZ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,GAAG,CAAC;CAiChB"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var FacebookOAuthStrategy_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.FacebookOAuthStrategy = exports.FacebookOauthGuard = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const passport_1 = require("@nestjs/passport");
16
+ const passport_facebook_1 = require("passport-facebook");
17
+ const facebook_oauth_helper_1 = require("../helpers/facebook-oauth.helper");
18
+ const uuid_1 = require("uuid");
19
+ const setting_service_1 = require("../services/setting.service");
20
+ const user_service_1 = require("../services/user.service");
21
+ const DUMMY_CLIENT_ID = "DUMMY_CLIENT_ID";
22
+ const DUMMY_CLIENT_SECRET = "DUMMY_CLIENT_SECRET";
23
+ const DUMMY_CALLBACK_URL = "DUMMY_CALLBACK_URL";
24
+ let FacebookOauthGuard = class FacebookOauthGuard extends (0, passport_1.AuthGuard)("facebook") {
25
+ };
26
+ exports.FacebookOauthGuard = FacebookOauthGuard;
27
+ exports.FacebookOauthGuard = FacebookOauthGuard = __decorate([
28
+ (0, common_1.Injectable)()
29
+ ], FacebookOauthGuard);
30
+ let FacebookOAuthStrategy = FacebookOAuthStrategy_1 = class FacebookOAuthStrategy extends (0, passport_1.PassportStrategy)(passport_facebook_1.Strategy, "facebook") {
31
+ constructor(userService, settingService) {
32
+ const clientID = settingService.getConfigValue("FACEBOOK_CLIENT_ID") ??
33
+ process.env.IAM_FACEBOOK_OAUTH_CLIENT_ID ??
34
+ DUMMY_CLIENT_ID;
35
+ const clientSecret = settingService.getConfigValue("FACEBOOK_CLIENT_SECRET") ??
36
+ process.env.IAM_FACEBOOK_OAUTH_CLIENT_SECRET ??
37
+ DUMMY_CLIENT_SECRET;
38
+ const callbackURL = settingService.getConfigValue("FACEBOOK_CALLBACK_URL") ??
39
+ process.env.IAM_FACEBOOK_OAUTH_CALLBACK_URL ??
40
+ DUMMY_CALLBACK_URL;
41
+ const redirectURL = settingService.getConfigValue("FACEBOOK_REDIRECT_URL") ?? process.env.IAM_FACEBOOK_OAUTH_REDIRECT_URL;
42
+ super({
43
+ clientID,
44
+ clientSecret,
45
+ callbackURL,
46
+ scope: ["email"],
47
+ profileFields: ["id", "name", "email", "picture.type(large)"],
48
+ });
49
+ this.userService = userService;
50
+ this.settingService = settingService;
51
+ this.logger = new common_1.Logger(FacebookOAuthStrategy_1.name);
52
+ const facebookOauth = {
53
+ clientID,
54
+ clientSecret,
55
+ callbackURL,
56
+ redirectURL,
57
+ };
58
+ if (!(0, facebook_oauth_helper_1.isFacebookOAuthConfigured)(facebookOauth)) {
59
+ this.logger.debug("Facebook OAuth strategy is not configured");
60
+ }
61
+ else {
62
+ this.logger.debug(`Facebook OAuth configured with callbackURL=${callbackURL}`);
63
+ }
64
+ }
65
+ async validate(_accessToken, _refreshToken, profile, done) {
66
+ const { id, name, emails, photos } = profile;
67
+ const loginAccessCode = (0, uuid_1.v4)();
68
+ const email = emails && emails.length > 0 ? emails[0].value : null;
69
+ const firstName = name?.givenName || "";
70
+ const lastName = name?.familyName || "";
71
+ const fullName = firstName || lastName
72
+ ? `${firstName} ${lastName}`.trim()
73
+ : profile.displayName;
74
+ const user = {
75
+ provider: "facebook",
76
+ providerId: id,
77
+ email: email,
78
+ name: `${name.givenName} ${name.familyName}`,
79
+ picture: photos?.[0]?.value,
80
+ accessCode: loginAccessCode,
81
+ };
82
+ await this.userService.resolveUserOnOauthFacebook({
83
+ ...user,
84
+ accessToken: _accessToken,
85
+ refreshToken: null,
86
+ });
87
+ done(null, user);
88
+ }
89
+ };
90
+ exports.FacebookOAuthStrategy = FacebookOAuthStrategy;
91
+ exports.FacebookOAuthStrategy = FacebookOAuthStrategy = FacebookOAuthStrategy_1 = __decorate([
92
+ (0, common_1.Injectable)(),
93
+ __metadata("design:paramtypes", [user_service_1.UserService,
94
+ setting_service_1.SettingService])
95
+ ], FacebookOAuthStrategy);
96
+ //# sourceMappingURL=facebook-oauth.strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facebook-oauth.strategy.js","sourceRoot":"","sources":["../../src/passport-strategies/facebook-oauth.strategy.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from \"@nestjs/common\";\nimport { AuthGuard, PassportStrategy } from \"@nestjs/passport\";\nimport { Strategy } from \"passport-facebook\";\nimport {\n FacebookAuthConfiguration,\n isFacebookOAuthConfigured,\n} from \"src/helpers/facebook-oauth.helper\";\nimport { v4 as uuid } from \"uuid\";\nimport type { SolidCoreSetting } from \"../services/settings/default-settings-provider.service\";\nimport { SettingService } from \"../services/setting.service\";\nimport { UserService } from \"../services/user.service\";\n\nconst DUMMY_CLIENT_ID = \"DUMMY_CLIENT_ID\";\nconst DUMMY_CLIENT_SECRET = \"DUMMY_CLIENT_SECRET\";\nconst DUMMY_CALLBACK_URL = \"DUMMY_CALLBACK_URL\";\n\n@Injectable()\nexport class FacebookOauthGuard extends AuthGuard(\"facebook\") {}\n\n@Injectable()\nexport class FacebookOAuthStrategy extends PassportStrategy(\n Strategy,\n \"facebook\",\n) {\n private readonly logger = new Logger(FacebookOAuthStrategy.name);\n\n constructor(\n private readonly userService: UserService,\n private readonly settingService: SettingService,\n ) {\n // Prefer settings cache (same source used by controller validation), fall back to env.\n const clientID =\n settingService.getConfigValue<SolidCoreSetting>(\"FACEBOOK_CLIENT_ID\") ??\n process.env.IAM_FACEBOOK_OAUTH_CLIENT_ID ??\n DUMMY_CLIENT_ID;\n const clientSecret =\n settingService.getConfigValue<SolidCoreSetting>(\n \"FACEBOOK_CLIENT_SECRET\",\n ) ??\n process.env.IAM_FACEBOOK_OAUTH_CLIENT_SECRET ??\n DUMMY_CLIENT_SECRET;\n const callbackURL =\n settingService.getConfigValue<SolidCoreSetting>(\n \"FACEBOOK_CALLBACK_URL\",\n ) ??\n process.env.IAM_FACEBOOK_OAUTH_CALLBACK_URL ??\n DUMMY_CALLBACK_URL;\n const redirectURL =\n settingService.getConfigValue<SolidCoreSetting>(\n \"FACEBOOK_REDIRECT_URL\",\n ) ?? process.env.IAM_FACEBOOK_OAUTH_REDIRECT_URL;\n\n super({\n clientID,\n clientSecret,\n callbackURL,\n scope: [\"email\"],\n // Facebook Graph API expects \"email\" and \"picture\", not \"emails\"/\"photos\".\n profileFields: [\"id\", \"name\", \"email\", \"picture.type(large)\"],\n });\n\n const facebookOauth: FacebookAuthConfiguration = {\n clientID,\n clientSecret,\n callbackURL,\n redirectURL,\n };\n if (!isFacebookOAuthConfigured(facebookOauth)) {\n this.logger.debug(\"Facebook OAuth strategy is not configured\");\n } else {\n this.logger.debug(\n `Facebook OAuth configured with callbackURL=${callbackURL}`,\n );\n }\n }\n\n async validate(\n _accessToken: string,\n _refreshToken: string,\n profile: any,\n done: any,\n ): Promise<any> {\n const { id, name, emails, photos } = profile;\n\n // generate a unique access code.\n const loginAccessCode: string = uuid();\n\n const email = emails && emails.length > 0 ? emails[0].value : null;\n\n const firstName = name?.givenName || \"\";\n const lastName = name?.familyName || \"\";\n const fullName =\n firstName || lastName\n ? `${firstName} ${lastName}`.trim()\n : profile.displayName;\n\n const user = {\n provider: \"facebook\",\n providerId: id,\n email: email,\n name: `${name.givenName} ${name.familyName}`,\n picture: photos?.[0]?.value,\n accessCode: loginAccessCode,\n };\n\n // store the access code and the access token in the database.\n await this.userService.resolveUserOnOauthFacebook({\n ...user,\n accessToken: _accessToken,\n refreshToken: null,\n });\n\n done(null, user);\n }\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { Strategy } from 'passport-microsoft';
2
+ import { UserService } from '../services/user.service';
3
+ declare const MicrosoftOauthGuard_base: import("@nestjs/passport").Type<import("@nestjs/passport").IAuthGuard>;
4
+ export declare class MicrosoftOauthGuard extends MicrosoftOauthGuard_base {
5
+ }
6
+ declare const MicrosoftOAuthStrategy_base: new (...args: any[]) => Strategy;
7
+ export declare class MicrosoftOAuthStrategy extends MicrosoftOAuthStrategy_base {
8
+ private readonly userService;
9
+ private readonly logger;
10
+ constructor(userService: UserService);
11
+ validate(_accessToken: string, _refreshToken: string, profile: any, done: any): Promise<any>;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=microsoft-oauth.strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microsoft-oauth.strategy.d.ts","sourceRoot":"","sources":["../../src/passport-strategies/microsoft-oauth.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;;AAOvD,qBACa,mBAAoB,SAAQ,wBAAsB;CAAI;;AAEnE,qBACa,sBAAuB,SAAQ,2BAAuC;IAGrE,OAAO,CAAC,QAAQ,CAAC,WAAW;IAFxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;gBAErC,WAAW,EAAE,WAAW;IAuB/C,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;CA2BnG"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var MicrosoftOAuthStrategy_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.MicrosoftOAuthStrategy = exports.MicrosoftOauthGuard = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const passport_1 = require("@nestjs/passport");
16
+ const passport_microsoft_1 = require("passport-microsoft");
17
+ const microsoft_oauth_helper_1 = require("../helpers/microsoft-oauth.helper");
18
+ const uuid_1 = require("uuid");
19
+ const user_service_1 = require("../services/user.service");
20
+ const DUMMY_CLIENT_ID = 'DUMMY_CLIENT_ID';
21
+ const DUMMY_CLIENT_SECRET = 'DUMMY_CLIENT_SECRET';
22
+ const DUMMY_TENANT = 'common';
23
+ const DUMMY_CALLBACK_URL = 'DUMMY_CALLBACK_URL';
24
+ let MicrosoftOauthGuard = class MicrosoftOauthGuard extends (0, passport_1.AuthGuard)('microsoft') {
25
+ };
26
+ exports.MicrosoftOauthGuard = MicrosoftOauthGuard;
27
+ exports.MicrosoftOauthGuard = MicrosoftOauthGuard = __decorate([
28
+ (0, common_1.Injectable)()
29
+ ], MicrosoftOauthGuard);
30
+ let MicrosoftOAuthStrategy = MicrosoftOAuthStrategy_1 = class MicrosoftOAuthStrategy extends (0, passport_1.PassportStrategy)(passport_microsoft_1.Strategy, 'microsoft') {
31
+ constructor(userService) {
32
+ const clientID = process.env.IAM_MICROSOFT_OAUTH_CLIENT_ID ?? DUMMY_CLIENT_ID;
33
+ const clientSecret = process.env.IAM_MICROSOFT_OAUTH_CLIENT_SECRET ?? DUMMY_CLIENT_SECRET;
34
+ const tenant = process.env.IAM_MICROSOFT_OAUTH_TENANT_ID ?? DUMMY_TENANT;
35
+ const callbackURL = process.env.IAM_MICROSOFT_OAUTH_CALLBACK_URL ?? DUMMY_CALLBACK_URL;
36
+ const redirectURL = process.env.IAM_MICROSOFT_OAUTH_REDIRECT_URL;
37
+ super({
38
+ clientID,
39
+ clientSecret,
40
+ callbackURL,
41
+ tenant,
42
+ scope: ['user.read'],
43
+ addUPNAsEmail: true,
44
+ });
45
+ this.userService = userService;
46
+ this.logger = new common_1.Logger(MicrosoftOAuthStrategy_1.name);
47
+ const microsoftOauth = { clientID, clientSecret, tenant, callbackURL, redirectURL };
48
+ if (!(0, microsoft_oauth_helper_1.isMicrosoftOAuthConfigured)(microsoftOauth)) {
49
+ this.logger.debug('Microsoft OAuth strategy is not configured');
50
+ }
51
+ }
52
+ async validate(_accessToken, _refreshToken, profile, done) {
53
+ const { id, displayName, emails, photos } = profile;
54
+ const loginAccessCode = (0, uuid_1.v4)();
55
+ const email = emails?.[0]?.value || profile._json?.mail || profile._json?.userPrincipalName;
56
+ const user = {
57
+ provider: 'microsoft',
58
+ providerId: id,
59
+ email: email,
60
+ name: displayName,
61
+ picture: photos?.[0]?.value || null,
62
+ accessCode: loginAccessCode,
63
+ };
64
+ await this.userService.resolveUserOnOauthMicrosoft({
65
+ ...user,
66
+ accessToken: _accessToken,
67
+ refreshToken: null
68
+ });
69
+ done(null, user);
70
+ }
71
+ };
72
+ exports.MicrosoftOAuthStrategy = MicrosoftOAuthStrategy;
73
+ exports.MicrosoftOAuthStrategy = MicrosoftOAuthStrategy = MicrosoftOAuthStrategy_1 = __decorate([
74
+ (0, common_1.Injectable)(),
75
+ __metadata("design:paramtypes", [user_service_1.UserService])
76
+ ], MicrosoftOAuthStrategy);
77
+ //# sourceMappingURL=microsoft-oauth.strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microsoft-oauth.strategy.js","sourceRoot":"","sources":["../../src/passport-strategies/microsoft-oauth.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,+CAA+D;AAC/D,2DAA8C;AAC9C,8EAA4G;AAC5G,+BAAkC;AAClC,2DAAuD;AAEvD,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAC1C,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAClD,MAAM,YAAY,GAAG,QAAQ,CAAC;AAC9B,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAGzC,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,IAAA,oBAAS,EAAC,WAAW,CAAC;CAAI,CAAA;AAAtD,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,mBAAU,GAAE;GACA,mBAAmB,CAAmC;AAG5D,IAAM,sBAAsB,8BAA5B,MAAM,sBAAuB,SAAQ,IAAA,2BAAgB,EAAC,6BAAQ,EAAE,WAAW,CAAC;IAGjF,YAA6B,WAAwB;QAEnD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,eAAe,CAAC;QAC9E,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,mBAAmB,CAAC;QAC1F,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,YAAY,CAAC;QACzE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,kBAAkB,CAAC;QACvF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC;QAEjE,KAAK,CAAC;YACJ,QAAQ;YACR,YAAY;YACZ,WAAW;YACX,MAAM;YACN,KAAK,EAAE,CAAC,WAAW,CAAC;YACpB,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;QAfwB,gBAAW,GAAX,WAAW,CAAa;QAFpC,WAAM,GAAG,IAAI,eAAM,CAAC,wBAAsB,CAAC,IAAI,CAAC,CAAC;QAmBhE,MAAM,cAAc,GAA+B,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;QAChH,IAAI,CAAC,IAAA,mDAA0B,EAAC,cAAc,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,YAAoB,EAAE,aAAqB,EAAE,OAAY,EAAE,IAAS;QACjF,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAGpD,MAAM,eAAe,GAAW,IAAA,SAAI,GAAE,CAAC;QAGvC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,iBAAiB,CAAC;QAE5F,MAAM,IAAI,GAAG;YACX,QAAQ,EAAE,WAAW;YACrB,UAAU,EAAE,EAAE;YACd,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;YACnC,UAAU,EAAE,eAAe;SAC5B,CAAC;QAGF,MAAM,IAAI,CAAC,WAAW,CAAC,2BAA2B,CAAC;YAC/C,GAAG,IAAI;YACP,WAAW,EAAE,YAAY;YACzB,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnB,CAAC;CACF,CAAA;AArDY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;qCAI+B,0BAAW;GAH1C,sBAAsB,CAqDlC","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport { AuthGuard, PassportStrategy } from '@nestjs/passport';\nimport { Strategy } from 'passport-microsoft';\nimport { MicrosoftAuthConfiguration, isMicrosoftOAuthConfigured } from 'src/helpers/microsoft-oauth.helper';\nimport { v4 as uuid } from 'uuid';\nimport { UserService } from '../services/user.service';\n\nconst DUMMY_CLIENT_ID = 'DUMMY_CLIENT_ID';\nconst DUMMY_CLIENT_SECRET = 'DUMMY_CLIENT_SECRET';\nconst DUMMY_TENANT = 'common';\nconst DUMMY_CALLBACK_URL = 'DUMMY_CALLBACK_URL';\n\n@Injectable()\nexport class MicrosoftOauthGuard extends AuthGuard('microsoft') { }\n\n@Injectable()\nexport class MicrosoftOAuthStrategy extends PassportStrategy(Strategy, 'microsoft') {\n private readonly logger = new Logger(MicrosoftOAuthStrategy.name);\n\n constructor(private readonly userService: UserService) {\n // Reading configuration from environment variables (Static approach like Google)\n const clientID = process.env.IAM_MICROSOFT_OAUTH_CLIENT_ID ?? DUMMY_CLIENT_ID;\n const clientSecret = process.env.IAM_MICROSOFT_OAUTH_CLIENT_SECRET ?? DUMMY_CLIENT_SECRET;\n const tenant = process.env.IAM_MICROSOFT_OAUTH_TENANT_ID ?? DUMMY_TENANT;\n const callbackURL = process.env.IAM_MICROSOFT_OAUTH_CALLBACK_URL ?? DUMMY_CALLBACK_URL;\n const redirectURL = process.env.IAM_MICROSOFT_OAUTH_REDIRECT_URL;\n\n super({\n clientID,\n clientSecret,\n callbackURL,\n tenant,\n scope: ['user.read'],\n addUPNAsEmail: true,\n });\n\n const microsoftOauth: MicrosoftAuthConfiguration = { clientID, clientSecret, tenant, callbackURL, redirectURL };\n if (!isMicrosoftOAuthConfigured(microsoftOauth)) {\n this.logger.debug('Microsoft OAuth strategy is not configured');\n }\n }\n\n async validate(_accessToken: string, _refreshToken: string, profile: any, done: any): Promise<any> {\n const { id, displayName, emails, photos } = profile;\n\n // generate a unique access code. \n const loginAccessCode: string = uuid();\n\n // Handle email fallback logic within the standard validate flow\n const email = emails?.[0]?.value || profile._json?.mail || profile._json?.userPrincipalName;\n\n const user = {\n provider: 'microsoft',\n providerId: id,\n email: email,\n name: displayName,\n picture: photos?.[0]?.value || null,\n accessCode: loginAccessCode,\n };\n\n // store the access code and the access token in the database. \n await this.userService.resolveUserOnOauthMicrosoft({ \n ...user, \n accessToken: _accessToken, \n refreshToken: null \n });\n\n done(null, user);\n }\n}"]}
@@ -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": false,
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"
@@ -4,17 +4,33 @@ import { UserApiKey } from '../entities/user-api-key.entity';
4
4
  import { ActiveUserData } from '../interfaces/active-user-data.interface';
5
5
  import { UserApiKeyRepository } from '../repository/user-api-key.repository';
6
6
  import { PermissionMetadataService } from '../services/permission-metadata.service';
7
+ import { AuthenticationService } from './authentication.service';
8
+ import { UserRepository } from '../repository/user.repository';
7
9
  export declare class ApiKeyService {
8
10
  private readonly apiKeyRepository;
9
11
  private readonly permissionMetadataService;
12
+ private readonly authenticationService;
13
+ private readonly userRepository;
10
14
  private readonly logger;
11
- constructor(apiKeyRepository: UserApiKeyRepository, permissionMetadataService: PermissionMetadataService);
15
+ constructor(apiKeyRepository: UserApiKeyRepository, permissionMetadataService: PermissionMetadataService, authenticationService: AuthenticationService, userRepository: UserRepository);
12
16
  generate(userId: number, dto: CreateApiKeyDto): Promise<{
13
17
  apiKey: string;
14
18
  record: UserApiKey;
15
19
  }>;
16
20
  validate(rawKey: string): Promise<ActiveUserData>;
17
21
  updateKey(id: number, userId: number, dto: UpdateApiKeyDto): Promise<void>;
22
+ apiKeyMe(apiKey: string): Promise<{
23
+ accessToken: string;
24
+ refreshToken: string;
25
+ user: {
26
+ email: string;
27
+ mobile: string;
28
+ username: string;
29
+ forcePasswordChange: boolean;
30
+ id: number;
31
+ roles: string[];
32
+ };
33
+ }>;
18
34
  private hash;
19
35
  }
20
36
  //# sourceMappingURL=api-key.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-key.service.d.ts","sourceRoot":"","sources":["../../src/services/api-key.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,qBACa,aAAa;IAIlB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAJ9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;gBAGpC,gBAAgB,EAAE,oBAAoB,EACtC,yBAAyB,EAAE,yBAAyB;IAGnE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;IA+B/F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkCjD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhF,OAAO,CAAC,IAAI;CAGf"}
1
+ {"version":3,"file":"api-key.service.d.ts","sourceRoot":"","sources":["../../src/services/api-key.service.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,qBACa,aAAa;IAIlB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAC1C,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc;IANnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;gBAGpC,gBAAgB,EAAE,oBAAoB,EACtC,yBAAyB,EAAE,yBAAyB,EACpD,qBAAqB,EAAE,qBAAqB,EAC5C,cAAc,EAAE,cAAc;IAG7C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAE;IA+BlG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAG,cAAc,CAAE;IAkCpD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB1E,QAAQ,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;IAoC7B,OAAO,CAAC,IAAI;CAGf"}
@@ -13,14 +13,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.ApiKeyService = void 0;
14
14
  const common_1 = require("@nestjs/common");
15
15
  const crypto_1 = require("crypto");
16
+ const error_messages_1 = require("../constants/error-messages");
16
17
  const user_api_key_entity_1 = require("../entities/user-api-key.entity");
17
18
  const user_entity_1 = require("../entities/user.entity");
18
19
  const user_api_key_repository_1 = require("../repository/user-api-key.repository");
19
20
  const permission_metadata_service_1 = require("./permission-metadata.service");
21
+ const authentication_service_1 = require("./authentication.service");
22
+ const user_repository_1 = require("../repository/user.repository");
20
23
  let ApiKeyService = ApiKeyService_1 = class ApiKeyService {
21
- constructor(apiKeyRepository, permissionMetadataService) {
24
+ constructor(apiKeyRepository, permissionMetadataService, authenticationService, userRepository) {
22
25
  this.apiKeyRepository = apiKeyRepository;
23
26
  this.permissionMetadataService = permissionMetadataService;
27
+ this.authenticationService = authenticationService;
28
+ this.userRepository = userRepository;
24
29
  this.logger = new common_1.Logger(ApiKeyService_1.name);
25
30
  }
26
31
  async generate(userId, dto) {
@@ -85,6 +90,35 @@ let ApiKeyService = ApiKeyService_1 = class ApiKeyService {
85
90
  .where('id = :id', { id })
86
91
  .execute();
87
92
  }
93
+ async apiKeyMe(apiKey) {
94
+ const hasedKey = this.hash(apiKey);
95
+ const apiKeyRecord = await this.apiKeyRepository.findOne({
96
+ where: {
97
+ hashedKey: hasedKey,
98
+ },
99
+ relations: {
100
+ user: {
101
+ roles: true
102
+ }
103
+ }
104
+ });
105
+ if (!apiKeyRecord) {
106
+ throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_CREDENTIALS);
107
+ }
108
+ const user = apiKeyRecord.user;
109
+ const tokens = await this.authenticationService.generateTokens(user);
110
+ return {
111
+ user: {
112
+ email: user.email,
113
+ mobile: user.mobile,
114
+ username: user.username,
115
+ forcePasswordChange: user.forcePasswordChange,
116
+ id: user.id,
117
+ roles: user.roles.map((role) => role.name)
118
+ },
119
+ ...tokens
120
+ };
121
+ }
88
122
  hash(rawKey) {
89
123
  return (0, crypto_1.createHash)('sha256').update(rawKey).digest('hex');
90
124
  }
@@ -93,6 +127,8 @@ exports.ApiKeyService = ApiKeyService;
93
127
  exports.ApiKeyService = ApiKeyService = ApiKeyService_1 = __decorate([
94
128
  (0, common_1.Injectable)(),
95
129
  __metadata("design:paramtypes", [user_api_key_repository_1.UserApiKeyRepository,
96
- permission_metadata_service_1.PermissionMetadataService])
130
+ permission_metadata_service_1.PermissionMetadataService,
131
+ authentication_service_1.AuthenticationService,
132
+ user_repository_1.UserRepository])
97
133
  ], ApiKeyService);
98
134
  //# sourceMappingURL=api-key.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-key.service.js","sourceRoot":"","sources":["../../src/services/api-key.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ForbiddenException,\n Injectable,\n Logger,\n NotFoundException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport { createHash, randomBytes } from 'crypto';\nimport { CreateApiKeyDto } from 'src/dtos/create-api-key.dto';\nimport { UpdateApiKeyDto } from 'src/dtos/update-api-key.dto';\nimport { UserApiKey } from 'src/entities/user-api-key.entity';\nimport { User } from 'src/entities/user.entity';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { UserApiKeyRepository } from 'src/repository/user-api-key.repository';\nimport { PermissionMetadataService } from 'src/services/permission-metadata.service';\n\n@Injectable()\nexport class ApiKeyService {\n private readonly logger = new Logger(ApiKeyService.name);\n\n constructor(\n private readonly apiKeyRepository: UserApiKeyRepository,\n private readonly permissionMetadataService: PermissionMetadataService,\n ) {}\n\n async generate(userId: number, dto: CreateApiKeyDto): Promise<{ apiKey: string; record: UserApiKey }> {\n const user = await this.apiKeyRepository.manager.findOne(User, {\n where: { id: userId },\n select: ['id', 'isAllowedToGenerateApiKeys'],\n });\n\n if (!user?.isAllowedToGenerateApiKeys) {\n throw new ForbiddenException('You are not allowed to generate API keys');\n }\n\n const rawKey = 'sldx_' + randomBytes(32).toString('hex');\n const hashedKey = this.hash(rawKey);\n const maskedKey = 'sldx_****' + rawKey.slice(-4);\n\n const record = this.apiKeyRepository.create({\n name: dto.name,\n hashedKey,\n maskedKey,\n isActive: true,\n expiresAt: dto.expiresAt ? new Date(dto.expiresAt) : null,\n user,\n });\n\n await this.apiKeyRepository.save(record);\n\n // Strip hashedKey from the returned record — maskedKey is all the UI needs\n delete (record as any).hashedKey;\n\n return { apiKey: rawKey, record };\n }\n\n async validate(rawKey: string): Promise<ActiveUserData> {\n const hashedKey = this.hash(rawKey);\n\n // Bypass security rules for auth validation — must find the key regardless of caller context\n const keyRecord = await this.apiKeyRepository.findOne({\n where: { hashedKey, isActive: true },\n relations: ['user', 'user.roles'],\n });\n\n if (!keyRecord) {\n throw new UnauthorizedException();\n }\n\n if (keyRecord.expiresAt && keyRecord.expiresAt < new Date()) {\n throw new UnauthorizedException('API key expired');\n }\n\n // Fire-and-forget — does not need security rule context\n this.apiKeyRepository.update(keyRecord.id, { lastUsedAt: new Date() }).catch((err) => {\n this.logger.warn(`Failed to update lastUsedAt for key ${keyRecord.id}: ${err.message}`);\n });\n\n const roles = (keyRecord.user.roles ?? []).map((r) => r.name);\n const permissions = await this.permissionMetadataService.findAllUsingRoles(roles);\n\n return {\n sub: keyRecord.user.id,\n username: keyRecord.user.username,\n email: keyRecord.user.email,\n roles,\n permissions: permissions.map((p) => p.name),\n };\n }\n\n async updateKey(id: number, userId: number, dto: UpdateApiKeyDto): Promise<void> {\n const keyRecord = await this.apiKeyRepository.findOne({\n where: { id, user: { id: userId } },\n });\n\n if (!keyRecord) {\n throw new NotFoundException('API key not found');\n }\n\n await this.apiKeyRepository.manager\n .createQueryBuilder()\n .update(UserApiKey)\n .set({ isActive: dto.isActive })\n .where('id = :id', { id })\n .execute();\n }\n\n private hash(rawKey: string): string {\n return createHash('sha256').update(rawKey).digest('hex');\n }\n}\n"]}
1
+ {"version":3,"file":"api-key.service.js","sourceRoot":"","sources":["../../src/services/api-key.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ForbiddenException,\n Injectable,\n Logger,\n NotFoundException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport { createHash, randomBytes } from 'crypto';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { CreateApiKeyDto } from 'src/dtos/create-api-key.dto';\nimport { UpdateApiKeyDto } from 'src/dtos/update-api-key.dto';\nimport { UserApiKey } from 'src/entities/user-api-key.entity';\nimport { User } from 'src/entities/user.entity';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { UserApiKeyRepository } from 'src/repository/user-api-key.repository';\nimport { PermissionMetadataService } from 'src/services/permission-metadata.service';\nimport { AuthenticationService } from './authentication.service';\nimport { UserRepository } from 'src/repository/user.repository';\n\n@Injectable()\nexport class ApiKeyService {\n private readonly logger = new Logger(ApiKeyService.name);\n\n constructor(\n private readonly apiKeyRepository: UserApiKeyRepository,\n private readonly permissionMetadataService: PermissionMetadataService,\n private readonly authenticationService: AuthenticationService,\n private readonly userRepository: UserRepository,\n ) {}\n\n async generate(userId: number, dto: CreateApiKeyDto): Promise < { apiKey: string; record: UserApiKey } > {\n const user = await this.apiKeyRepository.manager.findOne(User, {\n where: { id: userId },\n select: ['id', 'isAllowedToGenerateApiKeys'],\n });\n\n if(!user?.isAllowedToGenerateApiKeys) {\n throw new ForbiddenException('You are not allowed to generate API keys');\n }\n\n const rawKey = 'sldx_' + randomBytes(32).toString('hex');\n const hashedKey = this.hash(rawKey);\n const maskedKey = 'sldx_****' + rawKey.slice(-4);\n\n const record = this.apiKeyRepository.create({\n name: dto.name,\n hashedKey,\n maskedKey,\n isActive: true,\n expiresAt: dto.expiresAt ? new Date(dto.expiresAt) : null,\n user,\n });\n\n await this.apiKeyRepository.save(record);\n\n // Strip hashedKey from the returned record — maskedKey is all the UI needs\n delete(record as any).hashedKey;\n\n return { apiKey: rawKey, record };\n }\n\n async validate(rawKey: string): Promise < ActiveUserData > {\n const hashedKey = this.hash(rawKey);\n\n // Bypass security rules for auth validation — must find the key regardless of caller context\n const keyRecord = await this.apiKeyRepository.findOne({\n where: { hashedKey, isActive: true },\n relations: ['user', 'user.roles'],\n });\n\n if(!keyRecord) {\n throw new UnauthorizedException();\n }\n\n if(keyRecord.expiresAt && keyRecord.expiresAt < new Date()) {\n throw new UnauthorizedException('API key expired');\n }\n\n // Fire-and-forget — does not need security rule context\n this.apiKeyRepository.update(keyRecord.id, { lastUsedAt: new Date() }).catch((err) => {\n this.logger.warn(`Failed to update lastUsedAt for key ${keyRecord.id}: ${err.message}`);\n });\n\n const roles = (keyRecord.user.roles ?? []).map((r) => r.name);\n const permissions = await this.permissionMetadataService.findAllUsingRoles(roles);\n\n return {\n sub: keyRecord.user.id,\n username: keyRecord.user.username,\n email: keyRecord.user.email,\n roles,\n permissions: permissions.map((p) => p.name),\n };\n }\n\n async updateKey(id: number, userId: number, dto: UpdateApiKeyDto): Promise<void> {\n const keyRecord = await this.apiKeyRepository.findOne({\n where: { id, user: { id: userId } },\n });\n\n if (!keyRecord) {\n throw new NotFoundException('API key not found');\n }\n\n await this.apiKeyRepository.manager\n .createQueryBuilder()\n .update(UserApiKey)\n .set({ isActive: dto.isActive })\n .where('id = :id', { id })\n .execute();\n }\n\n\n async apiKeyMe(apiKey: string) {\n\n const hasedKey = this.hash(apiKey);\n const apiKeyRecord = await this.apiKeyRepository.findOne({\n where: {\n hashedKey: hasedKey,\n },\n relations: {\n user: {\n roles: true\n }\n }\n });\n\n if (!apiKeyRecord) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n const user = apiKeyRecord.user;\n\n const tokens = await this.authenticationService.generateTokens(user);\n\n\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role) => role.name)\n },\n ...tokens\n }\n }\n\n private hash(rawKey: string): string {\n return createHash('sha256').update(rawKey).digest('hex');\n }\n}\n"]}