@researchdatabox/redbox-core 0.0.0-bootstrap.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Attachment.d.ts +17 -0
- package/dist/Attachment.d.ts.map +1 -0
- package/dist/Attachment.js +40 -0
- package/dist/CoreController.d.ts +202 -0
- package/dist/CoreController.d.ts.map +1 -0
- package/dist/CoreController.js +688 -0
- package/dist/CoreService.d.ts +95 -0
- package/dist/CoreService.d.ts.map +1 -0
- package/dist/CoreService.js +295 -0
- package/dist/Datastream.d.ts +11 -0
- package/dist/Datastream.d.ts.map +1 -0
- package/dist/Datastream.js +38 -0
- package/dist/DatastreamService.d.ts +19 -0
- package/dist/DatastreamService.d.ts.map +1 -0
- package/dist/DatastreamService.js +3 -0
- package/dist/DatastreamServiceResponse.d.ts +12 -0
- package/dist/DatastreamServiceResponse.d.ts.map +1 -0
- package/dist/DatastreamServiceResponse.js +37 -0
- package/dist/IntegrationAuditParams.d.ts.map +1 -0
- package/dist/Logger.d.ts +16 -0
- package/dist/Logger.d.ts.map +1 -0
- package/dist/Logger.js +3 -0
- package/dist/QueueService.d.ts +9 -0
- package/dist/QueueService.d.ts.map +1 -0
- package/dist/QueueService.js +21 -0
- package/dist/RecordAuditParams.d.ts +6 -0
- package/dist/RecordAuditParams.d.ts.map +1 -0
- package/dist/RecordAuditParams.js +10 -0
- package/dist/RecordsService.d.ts +39 -0
- package/dist/RecordsService.d.ts.map +1 -0
- package/dist/RecordsService.js +3 -0
- package/dist/SearchService.d.ts +8 -0
- package/dist/SearchService.d.ts.map +1 -0
- package/dist/SearchService.js +3 -0
- package/dist/StorageService.d.ts +27 -0
- package/dist/StorageService.d.ts.map +1 -0
- package/dist/StorageService.js +3 -0
- package/dist/StorageServiceResponse.d.ts +16 -0
- package/dist/StorageServiceResponse.d.ts.map +1 -0
- package/dist/StorageServiceResponse.js +41 -0
- package/dist/bootstrap.d.ts +32 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +172 -0
- package/dist/config/action.config.d.ts +13 -0
- package/dist/config/action.config.d.ts.map +1 -0
- package/dist/config/action.config.js +9 -0
- package/dist/config/agendaQueue.config.d.ts +49 -0
- package/dist/config/agendaQueue.config.d.ts.map +1 -0
- package/dist/config/agendaQueue.config.js +71 -0
- package/dist/config/api.config.d.ts +9 -0
- package/dist/config/api.config.d.ts.map +1 -0
- package/dist/config/api.config.js +11 -0
- package/dist/config/appmode.config.d.ts +12 -0
- package/dist/config/appmode.config.d.ts.map +1 -0
- package/dist/config/appmode.config.js +12 -0
- package/dist/config/auth.config.d.ts +15 -0
- package/dist/config/auth.config.d.ts.map +1 -0
- package/dist/config/auth.config.js +81 -0
- package/dist/config/autoreload.config.d.ts +18 -0
- package/dist/config/autoreload.config.d.ts.map +1 -0
- package/dist/config/autoreload.config.js +21 -0
- package/dist/config/blueprints.config.d.ts +28 -0
- package/dist/config/blueprints.config.d.ts.map +1 -0
- package/dist/config/blueprints.config.js +15 -0
- package/dist/config/bootstrap.config.d.ts +15 -0
- package/dist/config/bootstrap.config.d.ts.map +1 -0
- package/dist/config/bootstrap.config.js +12 -0
- package/dist/config/branding.config.d.ts +19 -0
- package/dist/config/branding.config.d.ts.map +1 -0
- package/dist/config/branding.config.js +109 -0
- package/dist/config/brandingConfigurationDefaults.config.d.ts +134 -0
- package/dist/config/brandingConfigurationDefaults.config.d.ts.map +1 -0
- package/dist/config/brandingConfigurationDefaults.config.js +283 -0
- package/dist/config/companion.config.d.ts +41 -0
- package/dist/config/companion.config.d.ts.map +1 -0
- package/dist/config/companion.config.js +61 -0
- package/dist/config/cors.config.d.ts +22 -0
- package/dist/config/cors.config.d.ts.map +1 -0
- package/dist/config/cors.config.js +11 -0
- package/dist/config/crontab.config.d.ts +22 -0
- package/dist/config/crontab.config.d.ts.map +1 -0
- package/dist/config/crontab.config.js +18 -0
- package/dist/config/csp.config.d.ts +53 -0
- package/dist/config/csp.config.d.ts.map +1 -0
- package/dist/config/csp.config.js +32 -0
- package/dist/config/custom.config.d.ts +16 -0
- package/dist/config/custom.config.d.ts.map +1 -0
- package/dist/config/custom.config.js +22 -0
- package/dist/config/custom_cache.config.d.ts +14 -0
- package/dist/config/custom_cache.config.d.ts.map +1 -0
- package/dist/config/custom_cache.config.js +13 -0
- package/dist/config/dashboardtype.config.d.ts +45 -0
- package/dist/config/dashboardtype.config.d.ts.map +1 -0
- package/dist/config/dashboardtype.config.js +98 -0
- package/dist/config/datacite.config.d.ts +51 -0
- package/dist/config/datacite.config.d.ts.map +1 -0
- package/dist/config/datacite.config.js +44 -0
- package/dist/config/datapubs.config.d.ts +72 -0
- package/dist/config/datapubs.config.d.ts.map +1 -0
- package/dist/config/datapubs.config.js +74 -0
- package/dist/config/datastores.config.d.ts +20 -0
- package/dist/config/datastores.config.d.ts.map +1 -0
- package/dist/config/datastores.config.js +21 -0
- package/dist/config/dompurify.config.d.ts +65 -0
- package/dist/config/dompurify.config.d.ts.map +1 -0
- package/dist/config/dompurify.config.js +181 -0
- package/dist/config/dynamicasset.config.d.ts +13 -0
- package/dist/config/dynamicasset.config.d.ts.map +1 -0
- package/dist/config/dynamicasset.config.js +18 -0
- package/dist/config/dynamicconfig.config.d.ts +12 -0
- package/dist/config/dynamicconfig.config.d.ts.map +1 -0
- package/dist/config/dynamicconfig.config.js +13 -0
- package/dist/config/emailnotification.config.d.ts +49 -0
- package/dist/config/emailnotification.config.d.ts.map +1 -0
- package/dist/config/emailnotification.config.js +37 -0
- package/dist/config/figshareAPI.config.d.ts +116 -0
- package/dist/config/figshareAPI.config.d.ts.map +1 -0
- package/dist/config/figshareAPI.config.js +857 -0
- package/dist/config/figshareAPIEnv.config.d.ts +11 -0
- package/dist/config/figshareAPIEnv.config.d.ts.map +1 -0
- package/dist/config/figshareAPIEnv.config.js +13 -0
- package/dist/config/figshareDev.config.d.ts.map +1 -0
- package/dist/config/figshareRedboxFORMapping.config.d.ts +15 -0
- package/dist/config/figshareRedboxFORMapping.config.d.ts.map +1 -0
- package/dist/config/figshareRedboxFORMapping.config.js +7458 -0
- package/dist/config/form.config.d.ts +20 -0
- package/dist/config/form.config.d.ts.map +1 -0
- package/dist/config/form.config.js +11 -0
- package/dist/config/globals.config.d.ts +20 -0
- package/dist/config/globals.config.d.ts.map +1 -0
- package/dist/config/globals.config.js +52 -0
- package/dist/config/http.config.d.ts +57 -0
- package/dist/config/http.config.d.ts.map +1 -0
- package/dist/config/http.config.js +462 -0
- package/dist/config/i18n.config.d.ts +38 -0
- package/dist/config/i18n.config.d.ts.map +1 -0
- package/dist/config/i18n.config.js +30 -0
- package/dist/config/index.d.ts +306 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +240 -0
- package/dist/config/jsonld.config.d.ts +19 -0
- package/dist/config/jsonld.config.d.ts.map +1 -0
- package/dist/config/jsonld.config.js +33 -0
- package/dist/config/log.config.d.ts +20 -0
- package/dist/config/log.config.d.ts.map +1 -0
- package/dist/config/log.config.js +157 -0
- package/dist/config/lognamespace.config.d.ts +13 -0
- package/dist/config/lognamespace.config.d.ts.map +1 -0
- package/dist/config/lognamespace.config.js +17 -0
- package/dist/config/mint.config.d.ts +23 -0
- package/dist/config/mint.config.d.ts.map +1 -0
- package/dist/config/mint.config.js +20 -0
- package/dist/config/models.config.d.ts +37 -0
- package/dist/config/models.config.d.ts.map +1 -0
- package/dist/config/models.config.js +23 -0
- package/dist/config/namedQuery.config.d.ts +26 -0
- package/dist/config/namedQuery.config.d.ts.map +1 -0
- package/dist/config/namedQuery.config.js +358 -0
- package/dist/config/ng2.config.d.ts +11 -0
- package/dist/config/ng2.config.d.ts.map +1 -0
- package/dist/config/ng2.config.js +12 -0
- package/dist/config/orcid.config.d.ts +12 -0
- package/dist/config/orcid.config.d.ts.map +1 -0
- package/dist/config/orcid.config.js +13 -0
- package/dist/config/orm.config.d.ts +12 -0
- package/dist/config/orm.config.d.ts.map +1 -0
- package/dist/config/orm.config.js +13 -0
- package/dist/config/peopleSearch.config.d.ts +14 -0
- package/dist/config/peopleSearch.config.d.ts.map +1 -0
- package/dist/config/peopleSearch.config.js +15 -0
- package/dist/config/policies.config.d.ts +18 -0
- package/dist/config/policies.config.d.ts.map +1 -0
- package/dist/config/policies.config.js +65 -0
- package/dist/config/queue.config.d.ts +12 -0
- package/dist/config/queue.config.d.ts.map +1 -0
- package/dist/config/queue.config.js +13 -0
- package/dist/config/raid.config.d.ts +66 -0
- package/dist/config/raid.config.d.ts.map +1 -0
- package/dist/config/raid.config.js +272 -0
- package/dist/config/record.config.d.ts +74 -0
- package/dist/config/record.config.d.ts.map +1 -0
- package/dist/config/record.config.js +104 -0
- package/dist/config/recordtype.config.d.ts +66 -0
- package/dist/config/recordtype.config.d.ts.map +1 -0
- package/dist/config/recordtype.config.js +660 -0
- package/dist/config/redboxSession.config.d.ts +29 -0
- package/dist/config/redboxSession.config.d.ts.map +1 -0
- package/dist/config/redboxSession.config.js +14 -0
- package/dist/config/redboxToCkan.config.d.ts +17 -0
- package/dist/config/redboxToCkan.config.d.ts.map +1 -0
- package/dist/config/redboxToCkan.config.js +18 -0
- package/dist/config/relatedObjectsFormDefinition.config.d.ts.map +1 -0
- package/dist/config/report.config.d.ts +46 -0
- package/dist/config/report.config.d.ts.map +1 -0
- package/dist/config/report.config.js +54 -0
- package/dist/config/reusableContributorFormDefinitions.config.d.ts +3 -0
- package/dist/config/reusableContributorFormDefinitions.config.d.ts.map +1 -0
- package/dist/config/reusableContributorFormDefinitions.config.js +408 -0
- package/dist/config/reusableFormDefinitions.config.d.ts +16 -0
- package/dist/config/reusableFormDefinitions.config.d.ts.map +1 -0
- package/dist/config/reusableFormDefinitions.config.js +41 -0
- package/dist/config/reusableRelatedObjectsFormDefinitions.config.d.ts +22 -0
- package/dist/config/reusableRelatedObjectsFormDefinitions.config.d.ts.map +1 -0
- package/dist/config/reusableRelatedObjectsFormDefinitions.config.js +291 -0
- package/dist/config/reusableViewFormDefinitions.config.d.ts +3 -0
- package/dist/config/reusableViewFormDefinitions.config.d.ts.map +1 -0
- package/dist/config/reusableViewFormDefinitions.config.js +140 -0
- package/dist/config/routes.config.d.ts +21 -0
- package/dist/config/routes.config.d.ts.map +1 -0
- package/dist/config/routes.config.js +389 -0
- package/dist/config/search.config.d.ts +9 -0
- package/dist/config/search.config.d.ts.map +1 -0
- package/dist/config/search.config.js +11 -0
- package/dist/config/security.config.d.ts +22 -0
- package/dist/config/security.config.d.ts.map +1 -0
- package/dist/config/security.config.js +14 -0
- package/dist/config/session.config.d.ts +37 -0
- package/dist/config/session.config.d.ts.map +1 -0
- package/dist/config/session.config.js +11 -0
- package/dist/config/sockets.config.d.ts +17 -0
- package/dist/config/sockets.config.d.ts.map +1 -0
- package/dist/config/sockets.config.js +12 -0
- package/dist/config/solr.config.d.ts +73 -0
- package/dist/config/solr.config.d.ts.map +1 -0
- package/dist/config/solr.config.js +79 -0
- package/dist/config/static_assets.config.d.ts +10 -0
- package/dist/config/static_assets.config.d.ts.map +1 -0
- package/dist/config/static_assets.config.js +12 -0
- package/dist/config/storage.config.d.ts +42 -0
- package/dist/config/storage.config.d.ts.map +1 -0
- package/dist/config/storage.config.js +30 -0
- package/dist/config/typescript.config.d.ts +12 -0
- package/dist/config/typescript.config.d.ts.map +1 -0
- package/dist/config/typescript.config.js +13 -0
- package/dist/config/validators.config.d.ts +13 -0
- package/dist/config/validators.config.d.ts.map +1 -0
- package/dist/config/validators.config.js +15 -0
- package/dist/config/views.config.d.ts +20 -0
- package/dist/config/views.config.d.ts.map +1 -0
- package/dist/config/views.config.js +20 -0
- package/dist/config/vocab.config.d.ts +58 -0
- package/dist/config/vocab.config.d.ts.map +1 -0
- package/dist/config/vocab.config.js +58 -0
- package/dist/config/webpack.config.d.ts +16 -0
- package/dist/config/webpack.config.d.ts.map +1 -0
- package/dist/config/webpack.config.js +153 -0
- package/dist/config/workflow.config.d.ts +76 -0
- package/dist/config/workflow.config.d.ts.map +1 -0
- package/dist/config/workflow.config.js +339 -0
- package/dist/config/workspacetype.config.d.ts +23 -0
- package/dist/config/workspacetype.config.d.ts.map +1 -0
- package/dist/config/workspacetype.config.js +19 -0
- package/dist/configmodels/AdminSidebarConfig.d.ts +352 -0
- package/dist/configmodels/AdminSidebarConfig.d.ts.map +1 -0
- package/dist/configmodels/AdminSidebarConfig.js +163 -0
- package/dist/configmodels/AppConfig.interface.d.ts +4 -0
- package/dist/configmodels/AppConfig.interface.d.ts.map +1 -0
- package/dist/configmodels/AppConfig.interface.js +10 -0
- package/dist/configmodels/AuthorizedDomainsEmails.d.ts +43 -0
- package/dist/configmodels/AuthorizedDomainsEmails.d.ts.map +1 -0
- package/dist/configmodels/AuthorizedDomainsEmails.js +49 -0
- package/dist/configmodels/ConfigModels.d.ts +22 -0
- package/dist/configmodels/ConfigModels.d.ts.map +1 -0
- package/dist/configmodels/ConfigModels.js +98 -0
- package/dist/configmodels/DoiPublishing.d.ts.map +1 -0
- package/dist/configmodels/FigsharePublishing.d.ts.map +1 -0
- package/dist/configmodels/HomePanelConfig.d.ts +244 -0
- package/dist/configmodels/HomePanelConfig.d.ts.map +1 -0
- package/dist/configmodels/HomePanelConfig.js +132 -0
- package/dist/configmodels/MenuConfig.d.ts +203 -0
- package/dist/configmodels/MenuConfig.d.ts.map +1 -0
- package/dist/configmodels/MenuConfig.js +158 -0
- package/dist/configmodels/SystemMessage.d.ts +24 -0
- package/dist/configmodels/SystemMessage.d.ts.map +1 -0
- package/dist/configmodels/SystemMessage.js +30 -0
- package/dist/controllers/ActionController.d.ts +21 -0
- package/dist/controllers/ActionController.d.ts.map +1 -0
- package/dist/controllers/ActionController.js +41 -0
- package/dist/controllers/AdminController.d.ts +45 -0
- package/dist/controllers/AdminController.d.ts.map +1 -0
- package/dist/controllers/AdminController.js +498 -0
- package/dist/controllers/AppConfigController.d.ts +25 -0
- package/dist/controllers/AppConfigController.d.ts.map +1 -0
- package/dist/controllers/AppConfigController.js +90 -0
- package/dist/controllers/AsynchController.d.ts +30 -0
- package/dist/controllers/AsynchController.d.ts.map +1 -0
- package/dist/controllers/AsynchController.js +146 -0
- package/dist/controllers/BrandingAppController.d.ts +21 -0
- package/dist/controllers/BrandingAppController.d.ts.map +1 -0
- package/dist/controllers/BrandingAppController.js +144 -0
- package/dist/controllers/BrandingController.d.ts +64 -0
- package/dist/controllers/BrandingController.d.ts.map +1 -0
- package/dist/controllers/BrandingController.js +256 -0
- package/dist/controllers/DynamicAssetController.d.ts +67 -0
- package/dist/controllers/DynamicAssetController.d.ts.map +1 -0
- package/dist/controllers/DynamicAssetController.js +225 -0
- package/dist/controllers/EmailController.d.ts +35 -0
- package/dist/controllers/EmailController.d.ts.map +1 -0
- package/dist/controllers/EmailController.js +138 -0
- package/dist/controllers/ExportController.d.ts +22 -0
- package/dist/controllers/ExportController.d.ts.map +1 -0
- package/dist/controllers/ExportController.js +73 -0
- package/dist/controllers/FormVocabularyController.d.ts +12 -0
- package/dist/controllers/FormVocabularyController.d.ts.map +1 -0
- package/dist/controllers/FormVocabularyController.js +218 -0
- package/dist/controllers/RecordAuditController.d.ts +25 -0
- package/dist/controllers/RecordAuditController.d.ts.map +1 -0
- package/dist/controllers/RecordAuditController.js +74 -0
- package/dist/controllers/RecordController.d.ts +114 -0
- package/dist/controllers/RecordController.d.ts.map +1 -0
- package/dist/controllers/RecordController.js +1614 -0
- package/dist/controllers/RenderViewController.d.ts +14 -0
- package/dist/controllers/RenderViewController.d.ts.map +1 -0
- package/dist/controllers/RenderViewController.js +30 -0
- package/dist/controllers/ReportController.d.ts +25 -0
- package/dist/controllers/ReportController.d.ts.map +1 -0
- package/dist/controllers/ReportController.js +80 -0
- package/dist/controllers/ReportsController.d.ts +22 -0
- package/dist/controllers/ReportsController.d.ts.map +1 -0
- package/dist/controllers/ReportsController.js +37 -0
- package/dist/controllers/TranslationController.d.ts +27 -0
- package/dist/controllers/TranslationController.d.ts.map +1 -0
- package/dist/controllers/TranslationController.js +245 -0
- package/dist/controllers/UserController.d.ts +50 -0
- package/dist/controllers/UserController.d.ts.map +1 -0
- package/dist/controllers/UserController.js +518 -0
- package/dist/controllers/VocabController.d.ts +43 -0
- package/dist/controllers/VocabController.d.ts.map +1 -0
- package/dist/controllers/VocabController.js +190 -0
- package/dist/controllers/VocabularyController.d.ts +23 -0
- package/dist/controllers/VocabularyController.d.ts.map +1 -0
- package/dist/controllers/VocabularyController.js +344 -0
- package/dist/controllers/WorkspaceAsyncController.d.ts +18 -0
- package/dist/controllers/WorkspaceAsyncController.d.ts.map +1 -0
- package/dist/controllers/WorkspaceAsyncController.js +63 -0
- package/dist/controllers/WorkspaceTypesController.d.ts +19 -0
- package/dist/controllers/WorkspaceTypesController.d.ts.map +1 -0
- package/dist/controllers/WorkspaceTypesController.js +96 -0
- package/dist/controllers/index.d.ts +8 -0
- package/dist/controllers/index.d.ts.map +1 -0
- package/dist/controllers/index.js +159 -0
- package/dist/controllers/webservice/AdminController.d.ts +20 -0
- package/dist/controllers/webservice/AdminController.d.ts.map +1 -0
- package/dist/controllers/webservice/AdminController.js +83 -0
- package/dist/controllers/webservice/AppConfigController.d.ts +25 -0
- package/dist/controllers/webservice/AppConfigController.d.ts.map +1 -0
- package/dist/controllers/webservice/AppConfigController.js +72 -0
- package/dist/controllers/webservice/BrandingController.d.ts +13 -0
- package/dist/controllers/webservice/BrandingController.d.ts.map +1 -0
- package/dist/controllers/webservice/BrandingController.js +147 -0
- package/dist/controllers/webservice/ExportController.d.ts +22 -0
- package/dist/controllers/webservice/ExportController.d.ts.map +1 -0
- package/dist/controllers/webservice/ExportController.js +67 -0
- package/dist/controllers/webservice/FormManagementController.d.ts +24 -0
- package/dist/controllers/webservice/FormManagementController.d.ts.map +1 -0
- package/dist/controllers/webservice/FormManagementController.js +79 -0
- package/dist/controllers/webservice/IntegrationAuditController.d.ts.map +1 -0
- package/dist/controllers/webservice/RecordController.d.ts +65 -0
- package/dist/controllers/webservice/RecordController.d.ts.map +1 -0
- package/dist/controllers/webservice/RecordController.js +1348 -0
- package/dist/controllers/webservice/RecordTypeController.d.ts +24 -0
- package/dist/controllers/webservice/RecordTypeController.d.ts.map +1 -0
- package/dist/controllers/webservice/RecordTypeController.js +70 -0
- package/dist/controllers/webservice/ReportController.d.ts +22 -0
- package/dist/controllers/webservice/ReportController.d.ts.map +1 -0
- package/dist/controllers/webservice/ReportController.js +74 -0
- package/dist/controllers/webservice/SearchController.d.ts +28 -0
- package/dist/controllers/webservice/SearchController.d.ts.map +1 -0
- package/dist/controllers/webservice/SearchController.js +123 -0
- package/dist/controllers/webservice/TranslationController.d.ts +18 -0
- package/dist/controllers/webservice/TranslationController.d.ts.map +1 -0
- package/dist/controllers/webservice/TranslationController.js +226 -0
- package/dist/controllers/webservice/UserManagementController.d.ts +38 -0
- package/dist/controllers/webservice/UserManagementController.d.ts.map +1 -0
- package/dist/controllers/webservice/UserManagementController.js +608 -0
- package/dist/controllers/webservice/VocabularyController.d.ts +18 -0
- package/dist/controllers/webservice/VocabularyController.d.ts.map +1 -0
- package/dist/controllers/webservice/VocabularyController.js +172 -0
- package/dist/decorator/PopulateExportedMethods.decorator.d.ts +4 -0
- package/dist/decorator/PopulateExportedMethods.decorator.d.ts.map +1 -0
- package/dist/decorator/PopulateExportedMethods.decorator.js +22 -0
- package/dist/decorator/index.d.ts +2 -0
- package/dist/decorator/index.d.ts.map +1 -0
- package/dist/decorator/index.js +6 -0
- package/dist/decorators/Associations.d.ts +4 -0
- package/dist/decorators/Associations.d.ts.map +1 -0
- package/dist/decorators/Associations.js +12 -0
- package/dist/decorators/Attr.d.ts +4 -0
- package/dist/decorators/Attr.d.ts.map +1 -0
- package/dist/decorators/Attr.js +34 -0
- package/dist/decorators/Entity.d.ts +3 -0
- package/dist/decorators/Entity.d.ts.map +1 -0
- package/dist/decorators/Entity.js +29 -0
- package/dist/decorators/Lifecycle.d.ts +10 -0
- package/dist/decorators/Lifecycle.d.ts.map +1 -0
- package/dist/decorators/Lifecycle.js +26 -0
- package/dist/decorators/index.d.ts +8 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +35 -0
- package/dist/decorators/registry.d.ts +8 -0
- package/dist/decorators/registry.d.ts.map +1 -0
- package/dist/decorators/registry.js +68 -0
- package/dist/decorators/types.d.ts +81 -0
- package/dist/decorators/types.d.ts.map +1 -0
- package/dist/decorators/types.js +4 -0
- package/dist/decorators/utils.d.ts +5 -0
- package/dist/decorators/utils.d.ts.map +1 -0
- package/dist/decorators/utils.js +68 -0
- package/dist/form-config/dataPublication-1.0-draft.d.ts.map +1 -0
- package/dist/form-config/dataPublication-1.0-embargoed.d.ts.map +1 -0
- package/dist/form-config/dataPublication-1.0-published.d.ts.map +1 -0
- package/dist/form-config/dataPublication-1.0-queued.d.ts.map +1 -0
- package/dist/form-config/dataPublication-1.0-retired.d.ts.map +1 -0
- package/dist/form-config/dataRecord-1.0-draft.d.ts +4 -0
- package/dist/form-config/dataRecord-1.0-draft.d.ts.map +1 -0
- package/dist/form-config/dataRecord-1.0-draft.js +1042 -0
- package/dist/form-config/default-1.0-draft.d.ts +4 -0
- package/dist/form-config/default-1.0-draft.d.ts.map +1 -0
- package/dist/form-config/default-1.0-draft.js +1132 -0
- package/dist/form-config/generated-view-only.d.ts +12 -0
- package/dist/form-config/generated-view-only.d.ts.map +1 -0
- package/dist/form-config/generated-view-only.js +169 -0
- package/dist/form-config/index.d.ts +3 -0
- package/dist/form-config/index.d.ts.map +1 -0
- package/dist/form-config/index.js +15 -0
- package/dist/hooks/defineRedboxHook.d.ts +31 -0
- package/dist/hooks/defineRedboxHook.d.ts.map +1 -0
- package/dist/hooks/defineRedboxHook.js +47 -0
- package/dist/hooks/index.d.ts +9 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +13 -0
- package/dist/hooks/webpack.d.ts +27 -0
- package/dist/hooks/webpack.d.ts.map +1 -0
- package/dist/hooks/webpack.js +82 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +116 -0
- package/dist/loader/bootstrapShimRuntime.d.ts +8 -0
- package/dist/loader/bootstrapShimRuntime.d.ts.map +1 -0
- package/dist/loader/bootstrapShimRuntime.js +83 -0
- package/dist/loader/index.d.ts +93 -0
- package/dist/loader/index.d.ts.map +1 -0
- package/dist/loader/index.js +767 -0
- package/dist/middleware/redboxSession.d.ts +6 -0
- package/dist/middleware/redboxSession.d.ts.map +1 -0
- package/dist/middleware/redboxSession.js +60 -0
- package/dist/model/APIActionResponse.d.ts +6 -0
- package/dist/model/APIActionResponse.d.ts.map +1 -0
- package/dist/model/APIActionResponse.js +13 -0
- package/dist/model/APIErrorResponse.d.ts +6 -0
- package/dist/model/APIErrorResponse.d.ts.map +1 -0
- package/dist/model/APIErrorResponse.js +13 -0
- package/dist/model/APIHarvestResponse.d.ts +9 -0
- package/dist/model/APIHarvestResponse.d.ts.map +1 -0
- package/dist/model/APIHarvestResponse.js +19 -0
- package/dist/model/APIObjectActionResponse.d.ts +7 -0
- package/dist/model/APIObjectActionResponse.d.ts.map +1 -0
- package/dist/model/APIObjectActionResponse.js +15 -0
- package/dist/model/BuildResponse.d.ts +47 -0
- package/dist/model/BuildResponse.d.ts.map +1 -0
- package/dist/model/BuildResponse.js +5 -0
- package/dist/model/DashboardTypeResponseModel.d.ts +6 -0
- package/dist/model/DashboardTypeResponseModel.d.ts.map +1 -0
- package/dist/model/DashboardTypeResponseModel.js +13 -0
- package/dist/model/ListAPIResponse.d.ts +7 -0
- package/dist/model/ListAPIResponse.d.ts.map +1 -0
- package/dist/model/ListAPIResponse.js +12 -0
- package/dist/model/ListAPISummary.d.ts +7 -0
- package/dist/model/ListAPISummary.d.ts.map +1 -0
- package/dist/model/ListAPISummary.js +12 -0
- package/dist/model/RBValidationError.d.ts +62 -0
- package/dist/model/RBValidationError.d.ts.map +1 -0
- package/dist/model/RBValidationError.js +98 -0
- package/dist/model/RecordTypeResponseModel.d.ts +10 -0
- package/dist/model/RecordTypeResponseModel.d.ts.map +1 -0
- package/dist/model/RecordTypeResponseModel.js +19 -0
- package/dist/model/RequestDetails.d.ts +27 -0
- package/dist/model/RequestDetails.d.ts.map +1 -0
- package/dist/model/RequestDetails.js +53 -0
- package/dist/model/SolrDocument.d.ts +17 -0
- package/dist/model/SolrDocument.d.ts.map +1 -0
- package/dist/model/SolrDocument.js +30 -0
- package/dist/model/api/APIResponseVersion2.d.ts +107 -0
- package/dist/model/api/APIResponseVersion2.d.ts.map +1 -0
- package/dist/model/api/APIResponseVersion2.js +3 -0
- package/dist/model/api/APIVersions.d.ts +9 -0
- package/dist/model/api/APIVersions.d.ts.map +1 -0
- package/dist/model/api/APIVersions.js +11 -0
- package/dist/model/api/CreateUserAPIResponse.d.ts +9 -0
- package/dist/model/api/CreateUserAPIResponse.d.ts.map +1 -0
- package/dist/model/api/CreateUserAPIResponse.js +13 -0
- package/dist/model/api/FigshareArticleCreate.d.ts +11 -0
- package/dist/model/api/FigshareArticleCreate.d.ts.map +1 -0
- package/dist/model/api/FigshareArticleCreate.js +16 -0
- package/dist/model/api/FigshareArticleEmbargo.d.ts +11 -0
- package/dist/model/api/FigshareArticleEmbargo.d.ts.map +1 -0
- package/dist/model/api/FigshareArticleEmbargo.js +23 -0
- package/dist/model/api/FigshareArticleUpdate.d.ts +13 -0
- package/dist/model/api/FigshareArticleUpdate.d.ts.map +1 -0
- package/dist/model/api/FigshareArticleUpdate.js +20 -0
- package/dist/model/api/UserAPITokenAPIResponse.d.ts +6 -0
- package/dist/model/api/UserAPITokenAPIResponse.d.ts.map +1 -0
- package/dist/model/api/UserAPITokenAPIResponse.js +10 -0
- package/dist/model/api/index.d.ts +8 -0
- package/dist/model/api/index.d.ts.map +1 -0
- package/dist/model/api/index.js +16 -0
- package/dist/model/config/ReportConfig.d.ts +50 -0
- package/dist/model/config/ReportConfig.d.ts.map +1 -0
- package/dist/model/config/ReportConfig.js +58 -0
- package/dist/model/config/SolrConfig.d.ts +72 -0
- package/dist/model/config/SolrConfig.d.ts.map +1 -0
- package/dist/model/config/SolrConfig.js +41 -0
- package/dist/model/config/VocabQueryConfig.d.ts +30 -0
- package/dist/model/config/VocabQueryConfig.d.ts.map +1 -0
- package/dist/model/config/VocabQueryConfig.js +32 -0
- package/dist/model/config/index.d.ts +4 -0
- package/dist/model/config/index.d.ts.map +1 -0
- package/dist/model/config/index.js +20 -0
- package/dist/model/index.d.ts +16 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +45 -0
- package/dist/model/storage/AppConfigModel.d.ts +9 -0
- package/dist/model/storage/AppConfigModel.d.ts.map +1 -0
- package/dist/model/storage/AppConfigModel.js +3 -0
- package/dist/model/storage/AsynchProgressModel.d.ts +18 -0
- package/dist/model/storage/AsynchProgressModel.d.ts.map +1 -0
- package/dist/model/storage/AsynchProgressModel.js +3 -0
- package/dist/model/storage/BrandingModel.d.ts +24 -0
- package/dist/model/storage/BrandingModel.d.ts.map +1 -0
- package/dist/model/storage/BrandingModel.js +60 -0
- package/dist/model/storage/CacheEntryModel.d.ts +6 -0
- package/dist/model/storage/CacheEntryModel.d.ts.map +1 -0
- package/dist/model/storage/CacheEntryModel.js +3 -0
- package/dist/model/storage/CounterModel.d.ts +7 -0
- package/dist/model/storage/CounterModel.d.ts.map +1 -0
- package/dist/model/storage/CounterModel.js +3 -0
- package/dist/model/storage/DashboardTypeModel.d.ts +9 -0
- package/dist/model/storage/DashboardTypeModel.d.ts.map +1 -0
- package/dist/model/storage/DashboardTypeModel.js +3 -0
- package/dist/model/storage/DeletedRecordModel.d.ts +7 -0
- package/dist/model/storage/DeletedRecordModel.d.ts.map +1 -0
- package/dist/model/storage/DeletedRecordModel.js +3 -0
- package/dist/model/storage/IntegrationAuditModel.d.ts.map +1 -0
- package/dist/model/storage/NamedQueryModel.d.ts +13 -0
- package/dist/model/storage/NamedQueryModel.d.ts.map +1 -0
- package/dist/model/storage/NamedQueryModel.js +17 -0
- package/dist/model/storage/RecordAuditModel.d.ts +15 -0
- package/dist/model/storage/RecordAuditModel.d.ts.map +1 -0
- package/dist/model/storage/RecordAuditModel.js +28 -0
- package/dist/model/storage/RecordModel.d.ts +42 -0
- package/dist/model/storage/RecordModel.d.ts.map +1 -0
- package/dist/model/storage/RecordModel.js +3 -0
- package/dist/model/storage/RecordTypeModel.d.ts +36 -0
- package/dist/model/storage/RecordTypeModel.d.ts.map +1 -0
- package/dist/model/storage/RecordTypeModel.js +43 -0
- package/dist/model/storage/ReportModel.d.ts +5 -0
- package/dist/model/storage/ReportModel.d.ts.map +1 -0
- package/dist/model/storage/ReportModel.js +3 -0
- package/dist/model/storage/RoleModel.d.ts +9 -0
- package/dist/model/storage/RoleModel.d.ts.map +1 -0
- package/dist/model/storage/RoleModel.js +12 -0
- package/dist/model/storage/UserAuditModel.d.ts +9 -0
- package/dist/model/storage/UserAuditModel.d.ts.map +1 -0
- package/dist/model/storage/UserAuditModel.js +3 -0
- package/dist/model/storage/UserLinkModel.d.ts +14 -0
- package/dist/model/storage/UserLinkModel.d.ts.map +1 -0
- package/dist/model/storage/UserLinkModel.js +18 -0
- package/dist/model/storage/UserModel.d.ts +25 -0
- package/dist/model/storage/UserModel.d.ts.map +1 -0
- package/dist/model/storage/UserModel.js +26 -0
- package/dist/model/storage/WorkflowStepModel.d.ts +11 -0
- package/dist/model/storage/WorkflowStepModel.d.ts.map +1 -0
- package/dist/model/storage/WorkflowStepModel.js +3 -0
- package/dist/model/storage/WorkspaceAppModel.d.ts +8 -0
- package/dist/model/storage/WorkspaceAppModel.d.ts.map +1 -0
- package/dist/model/storage/WorkspaceAppModel.js +3 -0
- package/dist/model/storage/index.d.ts +18 -0
- package/dist/model/storage/index.d.ts.map +1 -0
- package/dist/model/storage/index.js +19 -0
- package/dist/policies/brandingAndPortal.d.ts +9 -0
- package/dist/policies/brandingAndPortal.d.ts.map +1 -0
- package/dist/policies/brandingAndPortal.js +34 -0
- package/dist/policies/checkAuth.d.ts +9 -0
- package/dist/policies/checkAuth.d.ts.map +1 -0
- package/dist/policies/checkAuth.js +64 -0
- package/dist/policies/checkBrandingValid.d.ts +9 -0
- package/dist/policies/checkBrandingValid.d.ts.map +1 -0
- package/dist/policies/checkBrandingValid.js +40 -0
- package/dist/policies/companionAttachmentUploadAuth.d.ts +9 -0
- package/dist/policies/companionAttachmentUploadAuth.d.ts.map +1 -0
- package/dist/policies/companionAttachmentUploadAuth.js +221 -0
- package/dist/policies/contentSecurityPolicy.d.ts +23 -0
- package/dist/policies/contentSecurityPolicy.d.ts.map +1 -0
- package/dist/policies/contentSecurityPolicy.js +135 -0
- package/dist/policies/disallowedHeadRequestHandler.d.ts +8 -0
- package/dist/policies/disallowedHeadRequestHandler.d.ts.map +1 -0
- package/dist/policies/disallowedHeadRequestHandler.js +17 -0
- package/dist/policies/i18nLanguages.d.ts +8 -0
- package/dist/policies/i18nLanguages.d.ts.map +1 -0
- package/dist/policies/i18nLanguages.js +56 -0
- package/dist/policies/index.d.ts +52 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +70 -0
- package/dist/policies/isAuthenticated.d.ts +9 -0
- package/dist/policies/isAuthenticated.d.ts.map +1 -0
- package/dist/policies/isAuthenticated.js +19 -0
- package/dist/policies/isWebServiceAuthenticated.d.ts +9 -0
- package/dist/policies/isWebServiceAuthenticated.d.ts.map +1 -0
- package/dist/policies/isWebServiceAuthenticated.js +25 -0
- package/dist/policies/menuResolver.d.ts +11 -0
- package/dist/policies/menuResolver.d.ts.map +1 -0
- package/dist/policies/menuResolver.js +58 -0
- package/dist/policies/noCache.d.ts +9 -0
- package/dist/policies/noCache.d.ts.map +1 -0
- package/dist/policies/noCache.js +34 -0
- package/dist/policies/prepWs.d.ts +9 -0
- package/dist/policies/prepWs.d.ts.map +1 -0
- package/dist/policies/prepWs.js +23 -0
- package/dist/policies/sessionAuth.d.ts +11 -0
- package/dist/policies/sessionAuth.d.ts.map +1 -0
- package/dist/policies/sessionAuth.js +23 -0
- package/dist/policies/setLang.d.ts +8 -0
- package/dist/policies/setLang.d.ts.map +1 -0
- package/dist/policies/setLang.js +13 -0
- package/dist/responses/badRequest.d.ts +22 -0
- package/dist/responses/badRequest.d.ts.map +1 -0
- package/dist/responses/badRequest.js +66 -0
- package/dist/responses/created.d.ts +22 -0
- package/dist/responses/created.d.ts.map +1 -0
- package/dist/responses/created.js +55 -0
- package/dist/responses/forbidden.d.ts +22 -0
- package/dist/responses/forbidden.d.ts.map +1 -0
- package/dist/responses/forbidden.js +66 -0
- package/dist/responses/index.d.ts +6 -0
- package/dist/responses/index.d.ts.map +1 -0
- package/dist/responses/index.js +22 -0
- package/dist/responses/ok.d.ts +26 -0
- package/dist/responses/ok.d.ts.map +1 -0
- package/dist/responses/ok.js +59 -0
- package/dist/responses/serverError.d.ts +22 -0
- package/dist/responses/serverError.d.ts.map +1 -0
- package/dist/responses/serverError.js +66 -0
- package/dist/sails.d.ts +238 -0
- package/dist/sails.d.ts.map +1 -0
- package/dist/sails.js +3 -0
- package/dist/services/AgendaQueueService.d.ts +58 -0
- package/dist/services/AgendaQueueService.d.ts.map +1 -0
- package/dist/services/AgendaQueueService.js +225 -0
- package/dist/services/AppConfigService.d.ts +59 -0
- package/dist/services/AppConfigService.d.ts.map +1 -0
- package/dist/services/AppConfigService.js +273 -0
- package/dist/services/AsynchsService.d.ts +20 -0
- package/dist/services/AsynchsService.d.ts.map +1 -0
- package/dist/services/AsynchsService.js +64 -0
- package/dist/services/BrandingLogoService.d.ts +47 -0
- package/dist/services/BrandingLogoService.d.ts.map +1 -0
- package/dist/services/BrandingLogoService.js +212 -0
- package/dist/services/BrandingService.d.ts +70 -0
- package/dist/services/BrandingService.d.ts.map +1 -0
- package/dist/services/BrandingService.js +332 -0
- package/dist/services/CacheService.d.ts +25 -0
- package/dist/services/CacheService.d.ts.map +1 -0
- package/dist/services/CacheService.js +153 -0
- package/dist/services/ConfigService.d.ts +23 -0
- package/dist/services/ConfigService.d.ts.map +1 -0
- package/dist/services/ConfigService.js +379 -0
- package/dist/services/ContrastService.d.ts +77 -0
- package/dist/services/ContrastService.d.ts.map +1 -0
- package/dist/services/ContrastService.js +218 -0
- package/dist/services/DashboardTypesService.d.ts +98 -0
- package/dist/services/DashboardTypesService.d.ts.map +1 -0
- package/dist/services/DashboardTypesService.js +291 -0
- package/dist/services/DoiService.d.ts +36 -0
- package/dist/services/DoiService.d.ts.map +1 -0
- package/dist/services/DoiService.js +494 -0
- package/dist/services/DomSanitizerService.d.ts +105 -0
- package/dist/services/DomSanitizerService.d.ts.map +1 -0
- package/dist/services/DomSanitizerService.js +506 -0
- package/dist/services/EmailService.d.ts +185 -0
- package/dist/services/EmailService.d.ts.map +1 -0
- package/dist/services/EmailService.js +527 -0
- package/dist/services/FigshareService.d.ts +75 -0
- package/dist/services/FigshareService.d.ts.map +1 -0
- package/dist/services/FigshareService.js +2193 -0
- package/dist/services/FormRecordConsistencyService.d.ts +156 -0
- package/dist/services/FormRecordConsistencyService.d.ts.map +1 -0
- package/dist/services/FormRecordConsistencyService.js +516 -0
- package/dist/services/FormsService.d.ts +65 -0
- package/dist/services/FormsService.d.ts.map +1 -0
- package/dist/services/FormsService.js +580 -0
- package/dist/services/I18nEntriesService.d.ts +80 -0
- package/dist/services/I18nEntriesService.d.ts.map +1 -0
- package/dist/services/I18nEntriesService.js +469 -0
- package/dist/services/IntegrationAuditService.d.ts.map +1 -0
- package/dist/services/NamedQueryService.d.ts +87 -0
- package/dist/services/NamedQueryService.d.ts.map +1 -0
- package/dist/services/NamedQueryService.js +396 -0
- package/dist/services/NavigationService.d.ts +115 -0
- package/dist/services/NavigationService.d.ts.map +1 -0
- package/dist/services/NavigationService.js +553 -0
- package/dist/services/OniService.d.ts +77 -0
- package/dist/services/OniService.d.ts.map +1 -0
- package/dist/services/OniService.js +753 -0
- package/dist/services/OrcidService.d.ts +30 -0
- package/dist/services/OrcidService.d.ts.map +1 -0
- package/dist/services/OrcidService.js +126 -0
- package/dist/services/PathRulesService.d.ts +57 -0
- package/dist/services/PathRulesService.d.ts.map +1 -0
- package/dist/services/PathRulesService.js +129 -0
- package/dist/services/RDMPService.d.ts +102 -0
- package/dist/services/RDMPService.d.ts.map +1 -0
- package/dist/services/RDMPService.js +767 -0
- package/dist/services/RaidService.d.ts +83 -0
- package/dist/services/RaidService.d.ts.map +1 -0
- package/dist/services/RaidService.js +556 -0
- package/dist/services/RecordTypesService.d.ts +27 -0
- package/dist/services/RecordTypesService.d.ts.map +1 -0
- package/dist/services/RecordTypesService.js +106 -0
- package/dist/services/RecordsService.d.ts +129 -0
- package/dist/services/RecordsService.d.ts.map +1 -0
- package/dist/services/RecordsService.js +1477 -0
- package/dist/services/ReportsService.d.ts +99 -0
- package/dist/services/ReportsService.d.ts.map +1 -0
- package/dist/services/ReportsService.js +475 -0
- package/dist/services/RolesService.d.ts +41 -0
- package/dist/services/RolesService.d.ts.map +1 -0
- package/dist/services/RolesService.js +171 -0
- package/dist/services/RvaImportService.d.ts +56 -0
- package/dist/services/RvaImportService.d.ts.map +1 -0
- package/dist/services/RvaImportService.js +410 -0
- package/dist/services/SassCompilerService.d.ts +26 -0
- package/dist/services/SassCompilerService.d.ts.map +1 -0
- package/dist/services/SassCompilerService.js +201 -0
- package/dist/services/SolrSearchService.d.ts +52 -0
- package/dist/services/SolrSearchService.d.ts.map +1 -0
- package/dist/services/SolrSearchService.js +463 -0
- package/dist/services/StandardDatastreamService.d.ts +66 -0
- package/dist/services/StandardDatastreamService.d.ts.map +1 -0
- package/dist/services/StandardDatastreamService.js +297 -0
- package/dist/services/StorageManagerService.d.ts +90 -0
- package/dist/services/StorageManagerService.d.ts.map +1 -0
- package/dist/services/StorageManagerService.js +234 -0
- package/dist/services/TemplateService.d.ts +65 -0
- package/dist/services/TemplateService.d.ts.map +1 -0
- package/dist/services/TemplateService.js +208 -0
- package/dist/services/TranslationService.d.ts +38 -0
- package/dist/services/TranslationService.d.ts.map +1 -0
- package/dist/services/TranslationService.js +358 -0
- package/dist/services/TriggerService.d.ts +72 -0
- package/dist/services/TriggerService.d.ts.map +1 -0
- package/dist/services/TriggerService.js +554 -0
- package/dist/services/UsersService.d.ts +174 -0
- package/dist/services/UsersService.d.ts.map +1 -0
- package/dist/services/UsersService.js +2108 -0
- package/dist/services/ViewUtilsService.d.ts +36 -0
- package/dist/services/ViewUtilsService.d.ts.map +1 -0
- package/dist/services/ViewUtilsService.js +120 -0
- package/dist/services/VocabService.d.ts +81 -0
- package/dist/services/VocabService.d.ts.map +1 -0
- package/dist/services/VocabService.js +424 -0
- package/dist/services/VocabularyService.d.ts +115 -0
- package/dist/services/VocabularyService.d.ts.map +1 -0
- package/dist/services/VocabularyService.js +752 -0
- package/dist/services/WorkflowStepsService.d.ts +29 -0
- package/dist/services/WorkflowStepsService.d.ts.map +1 -0
- package/dist/services/WorkflowStepsService.js +110 -0
- package/dist/services/WorkspaceAsyncService.d.ts +34 -0
- package/dist/services/WorkspaceAsyncService.d.ts.map +1 -0
- package/dist/services/WorkspaceAsyncService.js +68 -0
- package/dist/services/WorkspaceService.d.ts +67 -0
- package/dist/services/WorkspaceService.d.ts.map +1 -0
- package/dist/services/WorkspaceService.js +148 -0
- package/dist/services/WorkspaceTypesService.d.ts +33 -0
- package/dist/services/WorkspaceTypesService.d.ts.map +1 -0
- package/dist/services/WorkspaceTypesService.js +89 -0
- package/dist/services/doi-v2/audit.d.ts.map +1 -0
- package/dist/services/doi-v2/bindings.d.ts.map +1 -0
- package/dist/services/doi-v2/config.d.ts.map +1 -0
- package/dist/services/doi-v2/context.d.ts.map +1 -0
- package/dist/services/doi-v2/http.d.ts.map +1 -0
- package/dist/services/doi-v2/payload.d.ts.map +1 -0
- package/dist/services/doi-v2/profiles.d.ts.map +1 -0
- package/dist/services/doi-v2/runtime.d.ts.map +1 -0
- package/dist/services/doi-v2/types.d.ts.map +1 -0
- package/dist/services/figshare-v2/assets.d.ts.map +1 -0
- package/dist/services/figshare-v2/bindings.d.ts.map +1 -0
- package/dist/services/figshare-v2/config.d.ts.map +1 -0
- package/dist/services/figshare-v2/context.d.ts.map +1 -0
- package/dist/services/figshare-v2/embargo.d.ts.map +1 -0
- package/dist/services/figshare-v2/http.d.ts.map +1 -0
- package/dist/services/figshare-v2/metadata.d.ts.map +1 -0
- package/dist/services/figshare-v2/observability.d.ts.map +1 -0
- package/dist/services/figshare-v2/plan.d.ts.map +1 -0
- package/dist/services/figshare-v2/publish.d.ts.map +1 -0
- package/dist/services/figshare-v2/queue.d.ts.map +1 -0
- package/dist/services/figshare-v2/runtime.d.ts.map +1 -0
- package/dist/services/figshare-v2/types.d.ts.map +1 -0
- package/dist/services/figshare-v2/workflow.d.ts.map +1 -0
- package/dist/services/figshare-v2/writeback.d.ts.map +1 -0
- package/dist/services/index.d.ts +136 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +276 -0
- package/dist/shims/index.d.ts +9 -0
- package/dist/shims/index.d.ts.map +1 -0
- package/dist/shims/index.js +15 -0
- package/dist/shims/momentShim.d.ts +7 -0
- package/dist/shims/momentShim.d.ts.map +1 -0
- package/dist/shims/momentShim.js +69 -0
- package/dist/transformers/ExportJSONTransformer.d.ts +16 -0
- package/dist/transformers/ExportJSONTransformer.d.ts.map +1 -0
- package/dist/transformers/ExportJSONTransformer.js +90 -0
- package/dist/utilities/ContextVariableUtils.d.ts +8 -0
- package/dist/utilities/ContextVariableUtils.d.ts.map +1 -0
- package/dist/utilities/ContextVariableUtils.js +91 -0
- package/dist/utilities/TransactionUtils.d.ts +7 -0
- package/dist/utilities/TransactionUtils.d.ts.map +1 -0
- package/dist/utilities/TransactionUtils.js +25 -0
- package/dist/visitor/attachment-fields.visitor.d.ts +37 -0
- package/dist/visitor/attachment-fields.visitor.d.ts.map +1 -0
- package/dist/visitor/attachment-fields.visitor.js +93 -0
- package/dist/visitor/client.visitor.d.ts +211 -0
- package/dist/visitor/client.visitor.d.ts.map +1 -0
- package/dist/visitor/client.visitor.js +865 -0
- package/dist/visitor/construct.visitor.d.ts +219 -0
- package/dist/visitor/construct.visitor.d.ts.map +1 -0
- package/dist/visitor/construct.visitor.js +1499 -0
- package/dist/visitor/context-variables.visitor.d.ts +51 -0
- package/dist/visitor/context-variables.visitor.d.ts.map +1 -0
- package/dist/visitor/context-variables.visitor.js +192 -0
- package/dist/visitor/data-value.visitor.d.ts +159 -0
- package/dist/visitor/data-value.visitor.d.ts.map +1 -0
- package/dist/visitor/data-value.visitor.js +310 -0
- package/dist/visitor/json-type-def.visitor.d.ts +155 -0
- package/dist/visitor/json-type-def.visitor.d.ts.map +1 -0
- package/dist/visitor/json-type-def.visitor.js +384 -0
- package/dist/visitor/migrate-config-v4-v5.visitor.d.ts +244 -0
- package/dist/visitor/migrate-config-v4-v5.visitor.d.ts.map +1 -0
- package/dist/visitor/migrate-config-v4-v5.visitor.js +2941 -0
- package/dist/visitor/template.visitor.d.ts +163 -0
- package/dist/visitor/template.visitor.d.ts.map +1 -0
- package/dist/visitor/template.visitor.js +397 -0
- package/dist/visitor/validator.visitor.d.ts +123 -0
- package/dist/visitor/validator.visitor.d.ts.map +1 -0
- package/dist/visitor/validator.visitor.js +480 -0
- package/dist/visitor/visitor-helpers.d.ts +15 -0
- package/dist/visitor/visitor-helpers.d.ts.map +1 -0
- package/dist/visitor/visitor-helpers.js +191 -0
- package/dist/visitor/vocab-inline.visitor.d.ts +33 -0
- package/dist/visitor/vocab-inline.visitor.d.ts.map +1 -0
- package/dist/visitor/vocab-inline.visitor.js +173 -0
- package/dist/waterline-models/AppConfig.d.ts +19 -0
- package/dist/waterline-models/AppConfig.d.ts.map +1 -0
- package/dist/waterline-models/AppConfig.js +38 -0
- package/dist/waterline-models/AsynchProgress.d.ts +37 -0
- package/dist/waterline-models/AsynchProgress.d.ts.map +1 -0
- package/dist/waterline-models/AsynchProgress.js +83 -0
- package/dist/waterline-models/BrandingConfig.d.ts +28 -0
- package/dist/waterline-models/BrandingConfig.d.ts.map +1 -0
- package/dist/waterline-models/BrandingConfig.js +132 -0
- package/dist/waterline-models/BrandingConfigHistory.d.ts +25 -0
- package/dist/waterline-models/BrandingConfigHistory.d.ts.map +1 -0
- package/dist/waterline-models/BrandingConfigHistory.js +66 -0
- package/dist/waterline-models/CacheEntry.d.ts +18 -0
- package/dist/waterline-models/CacheEntry.d.ts.map +1 -0
- package/dist/waterline-models/CacheEntry.js +38 -0
- package/dist/waterline-models/Counter.d.ts +19 -0
- package/dist/waterline-models/Counter.d.ts.map +1 -0
- package/dist/waterline-models/Counter.js +38 -0
- package/dist/waterline-models/DashboardType.d.ts +23 -0
- package/dist/waterline-models/DashboardType.d.ts.map +1 -0
- package/dist/waterline-models/DashboardType.js +53 -0
- package/dist/waterline-models/Form.d.ts +21 -0
- package/dist/waterline-models/Form.d.ts.map +1 -0
- package/dist/waterline-models/Form.js +38 -0
- package/dist/waterline-models/I18nBundle.d.ts +29 -0
- package/dist/waterline-models/I18nBundle.d.ts.map +1 -0
- package/dist/waterline-models/I18nBundle.js +85 -0
- package/dist/waterline-models/I18nTranslation.d.ts +32 -0
- package/dist/waterline-models/I18nTranslation.d.ts.map +1 -0
- package/dist/waterline-models/I18nTranslation.js +110 -0
- package/dist/waterline-models/NamedQuery.d.ts +29 -0
- package/dist/waterline-models/NamedQuery.d.ts.map +1 -0
- package/dist/waterline-models/NamedQuery.js +68 -0
- package/dist/waterline-models/PathRule.d.ts +26 -0
- package/dist/waterline-models/PathRule.d.ts.map +1 -0
- package/dist/waterline-models/PathRule.js +53 -0
- package/dist/waterline-models/RBReport.d.ts +38 -0
- package/dist/waterline-models/RBReport.d.ts.map +1 -0
- package/dist/waterline-models/RBReport.js +73 -0
- package/dist/waterline-models/RecordType.d.ts +37 -0
- package/dist/waterline-models/RecordType.d.ts.map +1 -0
- package/dist/waterline-models/RecordType.js +88 -0
- package/dist/waterline-models/Role.d.ts +19 -0
- package/dist/waterline-models/Role.d.ts.map +1 -0
- package/dist/waterline-models/Role.js +38 -0
- package/dist/waterline-models/ThemeConfig.d.ts +16 -0
- package/dist/waterline-models/ThemeConfig.d.ts.map +1 -0
- package/dist/waterline-models/ThemeConfig.js +33 -0
- package/dist/waterline-models/User.d.ts +50 -0
- package/dist/waterline-models/User.d.ts.map +1 -0
- package/dist/waterline-models/User.js +151 -0
- package/dist/waterline-models/UserAudit.d.ts +18 -0
- package/dist/waterline-models/UserAudit.d.ts.map +1 -0
- package/dist/waterline-models/UserAudit.js +38 -0
- package/dist/waterline-models/UserLink.d.ts +30 -0
- package/dist/waterline-models/UserLink.d.ts.map +1 -0
- package/dist/waterline-models/UserLink.js +62 -0
- package/dist/waterline-models/Vocabulary.d.ts +38 -0
- package/dist/waterline-models/Vocabulary.d.ts.map +1 -0
- package/dist/waterline-models/Vocabulary.js +183 -0
- package/dist/waterline-models/VocabularyEntry.d.ts +33 -0
- package/dist/waterline-models/VocabularyEntry.d.ts.map +1 -0
- package/dist/waterline-models/VocabularyEntry.js +210 -0
- package/dist/waterline-models/WorkflowStep.d.ts +25 -0
- package/dist/waterline-models/WorkflowStep.d.ts.map +1 -0
- package/dist/waterline-models/WorkflowStep.js +53 -0
- package/dist/waterline-models/WorkspaceApp.d.ts +19 -0
- package/dist/waterline-models/WorkspaceApp.d.ts.map +1 -0
- package/dist/waterline-models/WorkspaceApp.js +50 -0
- package/dist/waterline-models/WorkspaceAsync.d.ts +32 -0
- package/dist/waterline-models/WorkspaceAsync.d.ts.map +1 -0
- package/dist/waterline-models/WorkspaceAsync.js +73 -0
- package/dist/waterline-models/WorkspaceType.d.ts +25 -0
- package/dist/waterline-models/WorkspaceType.d.ts.map +1 -0
- package/dist/waterline-models/WorkspaceType.js +53 -0
- package/dist/waterline-models/index.d.ts +53 -0
- package/dist/waterline-models/index.d.ts.map +1 -0
- package/dist/waterline-models/index.js +99 -0
- package/dist/waterline-models/types.d.ts +8 -0
- package/dist/waterline-models/types.d.ts.map +1 -0
- package/dist/waterline-models/types.js +3 -0
- package/package.json +150 -0
- package/redbox-loader-templates/bootstrap-shim.js.hbs +17 -0
- package/redbox-loader-templates/form-config-index.js.hbs +11 -0
|
@@ -0,0 +1,2108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2017 Queensland Cyber Infrastructure Foundation (http://www.qcif.edu.au/)
|
|
3
|
+
//
|
|
4
|
+
// GNU GENERAL PUBLIC LICENSE
|
|
5
|
+
// Version 2, June 1991
|
|
6
|
+
//
|
|
7
|
+
// This program is free software; you can redistribute it and/or modify
|
|
8
|
+
// it under the terms of the GNU General Public License as published by
|
|
9
|
+
// the Free Software Foundation; either version 2 of the License, or
|
|
10
|
+
// (at your option) any later version.
|
|
11
|
+
//
|
|
12
|
+
// This program is distributed in the hope that it will be useful,
|
|
13
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
// GNU General Public License for more details.
|
|
16
|
+
//
|
|
17
|
+
// You should have received a copy of the GNU General Public License along
|
|
18
|
+
// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
19
|
+
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
37
|
+
var ownKeys = function(o) {
|
|
38
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
39
|
+
var ar = [];
|
|
40
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
41
|
+
return ar;
|
|
42
|
+
};
|
|
43
|
+
return ownKeys(o);
|
|
44
|
+
};
|
|
45
|
+
return function (mod) {
|
|
46
|
+
if (mod && mod.__esModule) return mod;
|
|
47
|
+
var result = {};
|
|
48
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
49
|
+
__setModuleDefault(result, mod);
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
})();
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.Services = void 0;
|
|
55
|
+
const rxjs_1 = require("rxjs");
|
|
56
|
+
const operators_1 = require("rxjs/operators");
|
|
57
|
+
const rxjs_2 = require("rxjs");
|
|
58
|
+
const CoreService_1 = require("../CoreService");
|
|
59
|
+
const crypto = __importStar(require("crypto"));
|
|
60
|
+
var Services;
|
|
61
|
+
(function (Services) {
|
|
62
|
+
const DEFAULT_AAF_ATTRIBUTES_FIELD = 'https://aaf.edu.au/attributes';
|
|
63
|
+
const DEFAULT_AAF_USERNAME_FIELD = 'sub';
|
|
64
|
+
/**
|
|
65
|
+
* Use services...
|
|
66
|
+
*
|
|
67
|
+
*
|
|
68
|
+
* Author: <a href='https://github.com/shilob' target='_blank'>Shilo Banihit</a>
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
class Users extends CoreService_1.Services.Core.Service {
|
|
72
|
+
_exportedMethods = [
|
|
73
|
+
'bootstrap',
|
|
74
|
+
'updateUserRoles',
|
|
75
|
+
'updateUserDetails',
|
|
76
|
+
'getUserWithId',
|
|
77
|
+
'getUserWithUsername',
|
|
78
|
+
'addLocalUser',
|
|
79
|
+
'setUserKey',
|
|
80
|
+
'hasRole',
|
|
81
|
+
'findUsersWithName',
|
|
82
|
+
'findUsersWithEmail',
|
|
83
|
+
'findUsersWithQuery',
|
|
84
|
+
'findAndAssignAccessToRecords',
|
|
85
|
+
'getUsers',
|
|
86
|
+
'getUsersForBrand',
|
|
87
|
+
'getEffectiveUser',
|
|
88
|
+
'getLinkedAccounts',
|
|
89
|
+
'searchLinkCandidates',
|
|
90
|
+
'linkAccounts',
|
|
91
|
+
'addUserAuditEvent',
|
|
92
|
+
'checkAuthorizedEmail',
|
|
93
|
+
'enrichUsersWithEffectiveDisabledState',
|
|
94
|
+
'disableUser',
|
|
95
|
+
'enableUser',
|
|
96
|
+
'getUserAudit',
|
|
97
|
+
];
|
|
98
|
+
searchService;
|
|
99
|
+
getAuthConfig(brandName) {
|
|
100
|
+
return ConfigService.getBrand(brandName, 'auth') ?? {};
|
|
101
|
+
}
|
|
102
|
+
normalizeAccountLinkState(user) {
|
|
103
|
+
if (user != null && _.isEmpty(user.accountLinkState)) {
|
|
104
|
+
user.accountLinkState = 'active';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
hasRoleInBrand(user, brandId) {
|
|
108
|
+
if (user == null || _.isEmpty(brandId)) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
return _.some(user.roles ?? [], (role) => {
|
|
112
|
+
const roleObj = role;
|
|
113
|
+
const branding = roleObj.branding;
|
|
114
|
+
const roleBrandId = _.isObject(branding) ? String(branding.id ?? '') : String(branding ?? '');
|
|
115
|
+
return roleBrandId === brandId;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
getRolesForBrand(user, brandId) {
|
|
119
|
+
if (user == null || _.isEmpty(brandId)) {
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
return _.filter(user.roles ?? [], (role) => {
|
|
123
|
+
const roleObj = role;
|
|
124
|
+
const branding = roleObj.branding;
|
|
125
|
+
const roleBrandId = _.isObject(branding) ? String(branding.id ?? '') : String(branding ?? '');
|
|
126
|
+
return roleBrandId === brandId;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
toLinkedUserSummary(user, linkedAt) {
|
|
130
|
+
this.normalizeAccountLinkState(user);
|
|
131
|
+
return {
|
|
132
|
+
id: String(user.id ?? ''),
|
|
133
|
+
username: String(user.username ?? ''),
|
|
134
|
+
name: String(user.name ?? ''),
|
|
135
|
+
email: String(user.email ?? ''),
|
|
136
|
+
type: String(user.type ?? ''),
|
|
137
|
+
accountLinkState: String(user.accountLinkState ?? 'active'),
|
|
138
|
+
linkedAt,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async resolveLinkedUserCandidate(user) {
|
|
142
|
+
if (_.isEmpty(user)) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const resolved = await (0, rxjs_1.firstValueFrom)(this.getEffectiveUser(user));
|
|
146
|
+
return resolved ?? user;
|
|
147
|
+
}
|
|
148
|
+
async rewriteLinkedRecordAuthorizations(primaryUser, secondaryUser, actor, defaultBrandId) {
|
|
149
|
+
const secondaryUsername = String(secondaryUser.username ?? '');
|
|
150
|
+
const secondaryEmail = String(secondaryUser.email ?? '').toLowerCase();
|
|
151
|
+
const records = await Record.find({
|
|
152
|
+
or: [
|
|
153
|
+
{ 'authorization.edit': secondaryUsername },
|
|
154
|
+
{ 'authorization.view': secondaryUsername },
|
|
155
|
+
{ 'authorization.editPending': secondaryEmail },
|
|
156
|
+
{ 'authorization.viewPending': secondaryEmail }
|
|
157
|
+
]
|
|
158
|
+
}).meta({
|
|
159
|
+
enableExperimentalDeepTargets: true
|
|
160
|
+
});
|
|
161
|
+
let rewrittenCount = 0;
|
|
162
|
+
for (const record of records) {
|
|
163
|
+
const recordObj = _.cloneDeep(record);
|
|
164
|
+
const authorization = (recordObj.authorization ?? {});
|
|
165
|
+
authorization.edit = _.uniq((authorization.edit ?? []));
|
|
166
|
+
authorization.view = _.uniq((authorization.view ?? []));
|
|
167
|
+
authorization.editPending = (authorization.editPending ?? []).map(email => String(email).toLowerCase());
|
|
168
|
+
authorization.viewPending = (authorization.viewPending ?? []).map(email => String(email).toLowerCase());
|
|
169
|
+
recordObj.authorization = authorization;
|
|
170
|
+
let changed = false;
|
|
171
|
+
const nextEdit = _.map(authorization.edit, username => username === secondaryUsername ? String(primaryUser.username ?? '') : username);
|
|
172
|
+
const nextView = _.map(authorization.view, username => username === secondaryUsername ? String(primaryUser.username ?? '') : username);
|
|
173
|
+
if (!_.isEqual(nextEdit, authorization.edit)) {
|
|
174
|
+
authorization.edit = _.uniq(nextEdit);
|
|
175
|
+
changed = true;
|
|
176
|
+
}
|
|
177
|
+
if (!_.isEqual(nextView, authorization.view)) {
|
|
178
|
+
authorization.view = _.uniq(nextView);
|
|
179
|
+
changed = true;
|
|
180
|
+
}
|
|
181
|
+
if (_.includes(authorization.editPending, secondaryEmail)) {
|
|
182
|
+
authorization.editPending = _.without(authorization.editPending, secondaryEmail);
|
|
183
|
+
authorization.edit = _.uniq([...authorization.edit, String(primaryUser.username ?? '')]);
|
|
184
|
+
RecordsService.provideUserAccessAndRemovePendingAccess(String(recordObj.redboxOid ?? ''), primaryUser.username, secondaryEmail);
|
|
185
|
+
changed = true;
|
|
186
|
+
}
|
|
187
|
+
if (_.includes(authorization.viewPending, secondaryEmail)) {
|
|
188
|
+
authorization.viewPending = _.without(authorization.viewPending, secondaryEmail);
|
|
189
|
+
authorization.view = _.uniq([...authorization.view, String(primaryUser.username ?? '')]);
|
|
190
|
+
RecordsService.provideUserAccessAndRemovePendingAccess(String(recordObj.redboxOid ?? ''), primaryUser.username, secondaryEmail);
|
|
191
|
+
changed = true;
|
|
192
|
+
}
|
|
193
|
+
if (changed) {
|
|
194
|
+
const metaMetadata = (recordObj.metaMetadata ?? {});
|
|
195
|
+
const brandId = String(metaMetadata.brandId ?? defaultBrandId ?? '');
|
|
196
|
+
const brand = !_.isEmpty(brandId) ? BrandingService.getBrandById(brandId) : BrandingService.getDefault();
|
|
197
|
+
await RecordsService.updateMeta(brand, String(recordObj.redboxOid ?? ''), recordObj, { username: actor }, false, false);
|
|
198
|
+
rewrittenCount++;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return rewrittenCount;
|
|
202
|
+
}
|
|
203
|
+
async resolveEffectiveDisabledState(user) {
|
|
204
|
+
if (user.loginDisabled === true) {
|
|
205
|
+
return { effectiveLoginDisabled: true };
|
|
206
|
+
}
|
|
207
|
+
if (!_.isEmpty(user.linkedPrimaryUserId)) {
|
|
208
|
+
const primaryUser = await (0, rxjs_1.firstValueFrom)(this.getUserWithId(String(user.linkedPrimaryUserId)));
|
|
209
|
+
if (primaryUser != null && primaryUser.loginDisabled === true) {
|
|
210
|
+
return {
|
|
211
|
+
effectiveLoginDisabled: true,
|
|
212
|
+
disabledByPrimaryUserId: String(primaryUser.id ?? ''),
|
|
213
|
+
disabledByPrimaryUsername: String(primaryUser.username ?? '')
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return { effectiveLoginDisabled: false };
|
|
218
|
+
}
|
|
219
|
+
async assertAuthenticationAllowed(user) {
|
|
220
|
+
const state = await this.resolveEffectiveDisabledState(user);
|
|
221
|
+
if (state.effectiveLoginDisabled) {
|
|
222
|
+
throw new Error('Account is disabled');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async enrichUsersWithEffectiveDisabledState(users) {
|
|
226
|
+
const primaryIds = _.uniq(_.compact(_.map(users, (u) => !_.isEmpty(u.linkedPrimaryUserId) ? String(u.linkedPrimaryUserId) : null)));
|
|
227
|
+
const primaryUsers = _.isEmpty(primaryIds) ? [] : await User.find({ id: primaryIds });
|
|
228
|
+
const primaryUsersById = _.keyBy(primaryUsers, (u) => String(u.id ?? ''));
|
|
229
|
+
return _.map(users, (user) => {
|
|
230
|
+
if (user.loginDisabled === true) {
|
|
231
|
+
user.effectiveLoginDisabled = true;
|
|
232
|
+
}
|
|
233
|
+
else if (!_.isEmpty(user.linkedPrimaryUserId)) {
|
|
234
|
+
const primary = primaryUsersById[String(user.linkedPrimaryUserId)];
|
|
235
|
+
if (primary != null && primary.loginDisabled === true) {
|
|
236
|
+
user.effectiveLoginDisabled = true;
|
|
237
|
+
user.disabledByPrimaryUserId = String(primary.id ?? '');
|
|
238
|
+
user.disabledByPrimaryUsername = String(primary.username ?? '');
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
user.effectiveLoginDisabled = false;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
user.effectiveLoginDisabled = false;
|
|
246
|
+
}
|
|
247
|
+
return user;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
async disableUser(userId, actor, brandId) {
|
|
251
|
+
const user = await User.findOne({ id: userId });
|
|
252
|
+
if (user == null) {
|
|
253
|
+
throw new Error('User not found');
|
|
254
|
+
}
|
|
255
|
+
if (String(user.accountLinkState ?? 'active') === 'linked-alias') {
|
|
256
|
+
throw new Error('Cannot disable a linked alias user. Disable the primary account instead.');
|
|
257
|
+
}
|
|
258
|
+
await User.update({ id: userId }).set({ loginDisabled: true });
|
|
259
|
+
await this.addUserAuditEvent({ username: actor }, 'disable-user', { userId, brandId });
|
|
260
|
+
}
|
|
261
|
+
async enableUser(userId, actor, brandId) {
|
|
262
|
+
const user = await User.findOne({ id: userId });
|
|
263
|
+
if (user == null) {
|
|
264
|
+
throw new Error('User not found');
|
|
265
|
+
}
|
|
266
|
+
if (String(user.accountLinkState ?? 'active') === 'linked-alias') {
|
|
267
|
+
throw new Error('Cannot enable a linked alias user. Enable the primary account instead.');
|
|
268
|
+
}
|
|
269
|
+
await User.update({ id: userId }).set({ loginDisabled: false });
|
|
270
|
+
await this.addUserAuditEvent({ username: actor }, 'enable-user', { userId, brandId });
|
|
271
|
+
}
|
|
272
|
+
toAuditActor(user) {
|
|
273
|
+
const userObj = _.isObject(user) ? user : {};
|
|
274
|
+
const actor = {
|
|
275
|
+
username: String(userObj.username ?? '')
|
|
276
|
+
};
|
|
277
|
+
if (!_.isEmpty(userObj.name)) {
|
|
278
|
+
actor.name = String(userObj.name);
|
|
279
|
+
}
|
|
280
|
+
if (!_.isEmpty(userObj.email)) {
|
|
281
|
+
actor.email = String(userObj.email);
|
|
282
|
+
}
|
|
283
|
+
return actor;
|
|
284
|
+
}
|
|
285
|
+
toAuditContextString(additionalContext) {
|
|
286
|
+
if (_.isNil(additionalContext)) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
if (_.isString(additionalContext)) {
|
|
290
|
+
return additionalContext;
|
|
291
|
+
}
|
|
292
|
+
const stringified = this.stringifyObject(additionalContext);
|
|
293
|
+
return _.isString(stringified) ? stringified : null;
|
|
294
|
+
}
|
|
295
|
+
shouldRedactAuditKey(key) {
|
|
296
|
+
const normalizedKey = _.toLower(key);
|
|
297
|
+
return normalizedKey === 'cookie'
|
|
298
|
+
|| normalizedKey === 'authorization'
|
|
299
|
+
|| normalizedKey.startsWith('x-forwarded-')
|
|
300
|
+
|| normalizedKey.includes('password');
|
|
301
|
+
}
|
|
302
|
+
redactHeaderPairs(value) {
|
|
303
|
+
const redactedPairs = [...value];
|
|
304
|
+
for (let index = 0; index < redactedPairs.length - 1; index += 2) {
|
|
305
|
+
const headerName = redactedPairs[index];
|
|
306
|
+
if (_.isString(headerName) && this.shouldRedactAuditKey(headerName)) {
|
|
307
|
+
redactedPairs[index + 1] = '[REDACTED]';
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return redactedPairs;
|
|
311
|
+
}
|
|
312
|
+
redactAuditValue(value, contextKey) {
|
|
313
|
+
if (_.isArray(value)) {
|
|
314
|
+
if (_.toLower(contextKey ?? '') === 'rawheaders') {
|
|
315
|
+
return this.redactHeaderPairs(value);
|
|
316
|
+
}
|
|
317
|
+
return _.map(value, (item) => this.redactAuditValue(item));
|
|
318
|
+
}
|
|
319
|
+
if (_.isPlainObject(value)) {
|
|
320
|
+
if (_.toLower(contextKey ?? '') === 'cookies') {
|
|
321
|
+
return _.mapValues(value, () => '[REDACTED]');
|
|
322
|
+
}
|
|
323
|
+
return _.reduce(value, (acc, nestedValue, nestedKey) => {
|
|
324
|
+
acc[nestedKey] = this.shouldRedactAuditKey(nestedKey) ? '[REDACTED]' : this.redactAuditValue(nestedValue, nestedKey);
|
|
325
|
+
return acc;
|
|
326
|
+
}, {});
|
|
327
|
+
}
|
|
328
|
+
return value;
|
|
329
|
+
}
|
|
330
|
+
sanitizeAuditDebugContext(action, parsedAdditionalContext, rawAdditionalContext, parseError) {
|
|
331
|
+
if (!_.includes(['login', 'logout'], action)) {
|
|
332
|
+
return { parsedAdditionalContext, rawAdditionalContext };
|
|
333
|
+
}
|
|
334
|
+
const redactedParsed = this.redactAuditValue(parsedAdditionalContext);
|
|
335
|
+
if (parseError) {
|
|
336
|
+
return {
|
|
337
|
+
parsedAdditionalContext: null,
|
|
338
|
+
rawAdditionalContext: rawAdditionalContext == null ? null : '[REDACTED_UNPARSEABLE_AUDIT_CONTEXT]'
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
parsedAdditionalContext: redactedParsed,
|
|
343
|
+
rawAdditionalContext: redactedParsed == null ? null : JSON.stringify(redactedParsed)
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
parseUserAuditContext(action, additionalContext) {
|
|
347
|
+
const rawAdditionalContext = this.toAuditContextString(additionalContext);
|
|
348
|
+
if (_.isNil(rawAdditionalContext)) {
|
|
349
|
+
return {
|
|
350
|
+
parsedAdditionalContext: null,
|
|
351
|
+
rawAdditionalContext: null,
|
|
352
|
+
parseError: false
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
try {
|
|
356
|
+
const parsedAdditionalContext = JSON.parse(rawAdditionalContext);
|
|
357
|
+
const sanitized = this.sanitizeAuditDebugContext(action, parsedAdditionalContext, rawAdditionalContext, false);
|
|
358
|
+
return {
|
|
359
|
+
parsedAdditionalContext: sanitized.parsedAdditionalContext,
|
|
360
|
+
rawAdditionalContext: sanitized.rawAdditionalContext,
|
|
361
|
+
parseError: false
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
catch (_error) {
|
|
365
|
+
const sanitized = this.sanitizeAuditDebugContext(action, null, rawAdditionalContext, true);
|
|
366
|
+
return {
|
|
367
|
+
parsedAdditionalContext: sanitized.parsedAdditionalContext,
|
|
368
|
+
rawAdditionalContext: sanitized.rawAdditionalContext,
|
|
369
|
+
parseError: true
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
normalizeAuditTimestamp(value) {
|
|
374
|
+
if (value instanceof Date) {
|
|
375
|
+
return value.toISOString();
|
|
376
|
+
}
|
|
377
|
+
if (_.isString(value)) {
|
|
378
|
+
const parsed = new Date(value);
|
|
379
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed.toISOString();
|
|
380
|
+
}
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
timestampSortValue(row) {
|
|
384
|
+
const timestamp = this.normalizeAuditTimestamp(row.createdAt) ?? this.normalizeAuditTimestamp(row.updatedAt);
|
|
385
|
+
if (timestamp == null) {
|
|
386
|
+
return 0;
|
|
387
|
+
}
|
|
388
|
+
return new Date(timestamp).getTime();
|
|
389
|
+
}
|
|
390
|
+
matchesSelectedUserForDirectAudit(selectedUser, row) {
|
|
391
|
+
const rowUser = _.isObject(row.user) ? row.user : {};
|
|
392
|
+
const selectedUserId = String(selectedUser.id ?? '');
|
|
393
|
+
const selectedUsername = _.toLower(String(selectedUser.username ?? ''));
|
|
394
|
+
return String(rowUser.id ?? '') === selectedUserId || _.toLower(String(rowUser.username ?? '')) === selectedUsername;
|
|
395
|
+
}
|
|
396
|
+
matchesSelectedUserForAdminAudit(selectedUser, action, parsedAdditionalContext) {
|
|
397
|
+
if (!_.isPlainObject(parsedAdditionalContext)) {
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
const context = parsedAdditionalContext;
|
|
401
|
+
const selectedUserId = String(selectedUser.id ?? '');
|
|
402
|
+
if (_.includes(['disable-user', 'enable-user'], action)) {
|
|
403
|
+
return String(context.userId ?? '') === selectedUserId;
|
|
404
|
+
}
|
|
405
|
+
if (action === 'link-accounts') {
|
|
406
|
+
return String(context.primaryUserId ?? '') === selectedUserId || String(context.secondaryUserId ?? '') === selectedUserId;
|
|
407
|
+
}
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
getUserAuditDetails(selectedUser, action, parsedAdditionalContext) {
|
|
411
|
+
switch (action) {
|
|
412
|
+
case 'login':
|
|
413
|
+
return 'User logged in';
|
|
414
|
+
case 'logout':
|
|
415
|
+
return 'User logged out';
|
|
416
|
+
case 'disable-user':
|
|
417
|
+
return 'Admin disabled this account';
|
|
418
|
+
case 'enable-user':
|
|
419
|
+
return 'Admin enabled this account';
|
|
420
|
+
case 'link-accounts': {
|
|
421
|
+
if (!_.isPlainObject(parsedAdditionalContext)) {
|
|
422
|
+
return 'Account linking event';
|
|
423
|
+
}
|
|
424
|
+
const context = parsedAdditionalContext;
|
|
425
|
+
if (String(context.primaryUserId ?? '') === String(selectedUser.id ?? '')) {
|
|
426
|
+
return 'This account was chosen as the primary account during account linking';
|
|
427
|
+
}
|
|
428
|
+
if (String(context.secondaryUserId ?? '') === String(selectedUser.id ?? '')) {
|
|
429
|
+
return 'This account was linked as a secondary alias to another account';
|
|
430
|
+
}
|
|
431
|
+
return 'Account linking event';
|
|
432
|
+
}
|
|
433
|
+
default:
|
|
434
|
+
return String(action ?? '');
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
normalizeUserAuditRecord(selectedUser, row) {
|
|
438
|
+
const action = String(row.action ?? '');
|
|
439
|
+
const parsedContext = row.auditContext ?? this.parseUserAuditContext(action, row.additionalContext);
|
|
440
|
+
return {
|
|
441
|
+
id: String(row.id ?? ''),
|
|
442
|
+
timestamp: this.normalizeAuditTimestamp(row.createdAt) ?? this.normalizeAuditTimestamp(row.updatedAt),
|
|
443
|
+
action,
|
|
444
|
+
actor: this.toAuditActor(row.user),
|
|
445
|
+
details: this.getUserAuditDetails(selectedUser, action, parsedContext.parsedAdditionalContext),
|
|
446
|
+
parsedAdditionalContext: parsedContext.parsedAdditionalContext,
|
|
447
|
+
rawAdditionalContext: parsedContext.rawAdditionalContext,
|
|
448
|
+
parseError: parsedContext.parseError
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
async fetchDirectUserAuditRows(selectedUser) {
|
|
452
|
+
const directAuditActions = ['login', 'logout'];
|
|
453
|
+
try {
|
|
454
|
+
const rows = await UserAudit.find({
|
|
455
|
+
action: directAuditActions,
|
|
456
|
+
or: [
|
|
457
|
+
{ 'user.id': String(selectedUser.id ?? '') },
|
|
458
|
+
{ 'user.username': String(selectedUser.username ?? '') }
|
|
459
|
+
]
|
|
460
|
+
}).meta({
|
|
461
|
+
enableExperimentalDeepTargets: true
|
|
462
|
+
});
|
|
463
|
+
return rows;
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
sails.log.error('Failed to query direct user audit rows with deep targets enabled.');
|
|
467
|
+
sails.log.error(error);
|
|
468
|
+
throw new Error(`Unable to fetch direct audit records for user ${String(selectedUser.id ?? '')} without an unbounded fallback query.`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
async getUserAudit(userId) {
|
|
472
|
+
const selectedUser = await User.findOne({ id: userId });
|
|
473
|
+
if (selectedUser == null) {
|
|
474
|
+
throw new Error('User not found');
|
|
475
|
+
}
|
|
476
|
+
const selectedUserRecord = selectedUser;
|
|
477
|
+
const selectedUserId = String(selectedUserRecord.id ?? '');
|
|
478
|
+
const adminAuditContextFilters = [
|
|
479
|
+
`"userId":${JSON.stringify(selectedUserId)}`,
|
|
480
|
+
`"primaryUserId":${JSON.stringify(selectedUserId)}`,
|
|
481
|
+
`"secondaryUserId":${JSON.stringify(selectedUserId)}`
|
|
482
|
+
];
|
|
483
|
+
const directRows = await this.fetchDirectUserAuditRows(selectedUserRecord);
|
|
484
|
+
const adminRows = await UserAudit.find({
|
|
485
|
+
action: ['disable-user', 'enable-user', 'link-accounts'],
|
|
486
|
+
or: _.map(adminAuditContextFilters, (contextFilter) => ({
|
|
487
|
+
additionalContext: { contains: contextFilter }
|
|
488
|
+
}))
|
|
489
|
+
});
|
|
490
|
+
const matchingDirectRows = _.filter(directRows, (row) => this.matchesSelectedUserForDirectAudit(selectedUserRecord, row));
|
|
491
|
+
const matchingAdminRows = _.chain(adminRows)
|
|
492
|
+
.map((row) => {
|
|
493
|
+
const auditContext = this.parseUserAuditContext(String(row.action ?? ''), row.additionalContext);
|
|
494
|
+
return {
|
|
495
|
+
...row,
|
|
496
|
+
auditContext
|
|
497
|
+
};
|
|
498
|
+
})
|
|
499
|
+
.filter((row) => {
|
|
500
|
+
return this.matchesSelectedUserForAdminAudit(selectedUserRecord, String(row.action ?? ''), row.auditContext?.parsedAdditionalContext);
|
|
501
|
+
})
|
|
502
|
+
.value();
|
|
503
|
+
const mergedRows = _.values(_.keyBy([...matchingDirectRows, ...matchingAdminRows], (row) => String(row.id ?? '')));
|
|
504
|
+
const sortedRows = _.orderBy(mergedRows, (row) => this.timestampSortValue(row), 'desc');
|
|
505
|
+
const maxRows = 100;
|
|
506
|
+
const truncated = sortedRows.length > maxRows;
|
|
507
|
+
const limitedRows = sortedRows.slice(0, maxRows);
|
|
508
|
+
return {
|
|
509
|
+
records: _.map(limitedRows, (row) => this.normalizeUserAuditRecord(selectedUserRecord, row)),
|
|
510
|
+
summary: {
|
|
511
|
+
returnedCount: limitedRows.length,
|
|
512
|
+
truncated
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
localAuthInit() {
|
|
517
|
+
// users the default brand's configuration on startup
|
|
518
|
+
// TODO: consider moving late initializing this if possible
|
|
519
|
+
const defAuthConfig = this.getAuthConfig(BrandingService.getDefault().name);
|
|
520
|
+
const usernameField = defAuthConfig.local?.usernameField ?? 'username';
|
|
521
|
+
const passwordField = defAuthConfig.local?.passwordField ?? 'password';
|
|
522
|
+
//
|
|
523
|
+
// --------- Passport --------------
|
|
524
|
+
//
|
|
525
|
+
sails.config.passport = require('passport');
|
|
526
|
+
const LocalStrategy = require('passport-local').Strategy;
|
|
527
|
+
let bcrypt;
|
|
528
|
+
try {
|
|
529
|
+
bcrypt = require('bcrypt');
|
|
530
|
+
}
|
|
531
|
+
catch (_err) {
|
|
532
|
+
bcrypt = require('bcryptjs');
|
|
533
|
+
}
|
|
534
|
+
const passport = sails.config.passport;
|
|
535
|
+
const that = this;
|
|
536
|
+
passport.serializeUser(function (user, done) {
|
|
537
|
+
done(null, user.id);
|
|
538
|
+
});
|
|
539
|
+
passport.deserializeUser(function (id, done) {
|
|
540
|
+
User.findOne({
|
|
541
|
+
id: id
|
|
542
|
+
}).populate('roles').exec(function (err, user) {
|
|
543
|
+
if (err != null || _.isEmpty(user)) {
|
|
544
|
+
done(err, user);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
that.resolveLinkedUserCandidate(user)
|
|
548
|
+
.then((resolvedUser) => done(null, resolvedUser))
|
|
549
|
+
.catch((resolveErr) => done(resolveErr));
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
//
|
|
553
|
+
// Local Strategy
|
|
554
|
+
//
|
|
555
|
+
passport.use('local', new LocalStrategy({
|
|
556
|
+
usernameField: usernameField,
|
|
557
|
+
passwordField: passwordField
|
|
558
|
+
}, function (username, password, done) {
|
|
559
|
+
User.findOne({
|
|
560
|
+
username: username
|
|
561
|
+
}).populate('roles').exec(function (err, foundUser) {
|
|
562
|
+
if (err) {
|
|
563
|
+
return done(err);
|
|
564
|
+
}
|
|
565
|
+
if (!foundUser) {
|
|
566
|
+
return done(null, false, {
|
|
567
|
+
message: 'Incorrect username/password'
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
const foundUserObj = foundUser;
|
|
571
|
+
const passwordHash = String(foundUserObj.password ?? '');
|
|
572
|
+
bcrypt.compare(password, passwordHash, function (err, res) {
|
|
573
|
+
if (!res) {
|
|
574
|
+
return done(null, false, {
|
|
575
|
+
message: 'Incorrect username/password'
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
// Gate disabled users
|
|
579
|
+
that.assertAuthenticationAllowed(foundUserObj).then(() => {
|
|
580
|
+
// foundUser.lastLogin = new Date();
|
|
581
|
+
const configLocal = _.get(defAuthConfig, 'local', {});
|
|
582
|
+
if (that.hasPreSaveTriggerConfigured(configLocal, 'onUpdate')) {
|
|
583
|
+
that.triggerPreSaveTriggers(foundUserObj, configLocal).then((userAdditionalInfo) => {
|
|
584
|
+
const success = that.checkAllTriggersSuccessOrFailure(userAdditionalInfo);
|
|
585
|
+
if (success) {
|
|
586
|
+
User.update({
|
|
587
|
+
username: username
|
|
588
|
+
}).set({
|
|
589
|
+
lastLogin: new Date(),
|
|
590
|
+
additionalAttributes: _.get(userAdditionalInfo, 'additionalAttributes')
|
|
591
|
+
}).exec(function (err, user) {
|
|
592
|
+
if (err) {
|
|
593
|
+
sails.log.error("Error updating user:");
|
|
594
|
+
sails.log.error(err);
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
if (_.isEmpty(user)) {
|
|
598
|
+
sails.log.error("No user found");
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
sails.log.verbose("Done, returning updated user:");
|
|
602
|
+
sails.log.verbose(user);
|
|
603
|
+
return;
|
|
604
|
+
});
|
|
605
|
+
if (that.hasPostSaveTriggerConfigured(configLocal, 'onUpdate')) {
|
|
606
|
+
that.triggerPostSaveTriggers(foundUserObj, configLocal);
|
|
607
|
+
}
|
|
608
|
+
if (that.hasPostSaveSyncTriggerConfigured(configLocal, 'onUpdate')) {
|
|
609
|
+
that.triggerPostSaveSyncTriggers(foundUserObj, configLocal);
|
|
610
|
+
}
|
|
611
|
+
return done(null, userAdditionalInfo, {
|
|
612
|
+
message: 'Logged In Successfully'
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
return done(null, false, {
|
|
617
|
+
message: 'All required conditions for login not met'
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
User.update({
|
|
624
|
+
username: username
|
|
625
|
+
}).set({ lastLogin: new Date() }).exec(function (err, user) {
|
|
626
|
+
if (err) {
|
|
627
|
+
sails.log.error("Error updating user:");
|
|
628
|
+
sails.log.error(err);
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
if (_.isEmpty(user)) {
|
|
632
|
+
sails.log.error("No user found");
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
sails.log.verbose("Done, returning updated user:");
|
|
636
|
+
sails.log.verbose(user);
|
|
637
|
+
return;
|
|
638
|
+
});
|
|
639
|
+
if (that.hasPostSaveTriggerConfigured(configLocal, 'onUpdate')) {
|
|
640
|
+
that.triggerPostSaveTriggers(foundUserObj, configLocal);
|
|
641
|
+
}
|
|
642
|
+
if (that.hasPostSaveSyncTriggerConfigured(configLocal, 'onUpdate')) {
|
|
643
|
+
that.triggerPostSaveSyncTriggers(foundUserObj, configLocal);
|
|
644
|
+
}
|
|
645
|
+
return done(null, foundUserObj, {
|
|
646
|
+
message: 'Logged In Successfully'
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
}).catch((err) => {
|
|
650
|
+
if (err instanceof Error && err.message === 'Account is disabled') {
|
|
651
|
+
return done(null, false, { message: 'Account is disabled' });
|
|
652
|
+
}
|
|
653
|
+
return done(err);
|
|
654
|
+
}); // end assertAuthenticationAllowed gate
|
|
655
|
+
});
|
|
656
|
+
});
|
|
657
|
+
}));
|
|
658
|
+
}
|
|
659
|
+
hasPreSaveTriggerConfigured(config, mode) {
|
|
660
|
+
let hasPreTrigger = false;
|
|
661
|
+
const preSaveHooks = _.get(config, `hooks.${mode}.pre`, null);
|
|
662
|
+
if (Array.isArray(preSaveHooks)) {
|
|
663
|
+
for (const preSaveHook of preSaveHooks) {
|
|
664
|
+
if (_.has(preSaveHook, 'function') && _.has(preSaveHook, 'options')) {
|
|
665
|
+
hasPreTrigger = true;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return hasPreTrigger;
|
|
670
|
+
}
|
|
671
|
+
hasPostSaveTriggerConfigured(config, mode) {
|
|
672
|
+
let hasPreTrigger = false;
|
|
673
|
+
const preSaveHooks = _.get(config, `hooks.${mode}.post`, null);
|
|
674
|
+
if (Array.isArray(preSaveHooks)) {
|
|
675
|
+
for (const preSaveHook of preSaveHooks) {
|
|
676
|
+
if (_.has(preSaveHook, 'function') && _.has(preSaveHook, 'options')) {
|
|
677
|
+
hasPreTrigger = true;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return hasPreTrigger;
|
|
682
|
+
}
|
|
683
|
+
hasPostSaveSyncTriggerConfigured(config, mode) {
|
|
684
|
+
let hasPreTrigger = false;
|
|
685
|
+
const preSaveHooks = _.get(config, `hooks.${mode}.postSync`, null);
|
|
686
|
+
if (Array.isArray(preSaveHooks)) {
|
|
687
|
+
for (const preSaveHook of preSaveHooks) {
|
|
688
|
+
if (_.has(preSaveHook, 'function') && _.has(preSaveHook, 'options')) {
|
|
689
|
+
hasPreTrigger = true;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return hasPreTrigger;
|
|
694
|
+
}
|
|
695
|
+
checkAllTriggersSuccessOrFailure(user) {
|
|
696
|
+
let preTriggersSuccessOrFailure = true;
|
|
697
|
+
const preSaveHooksSuccessOrFailure = _.get(user, 'additionalInfoFound');
|
|
698
|
+
if (_.isArray(preSaveHooksSuccessOrFailure)) {
|
|
699
|
+
for (const preSaveHook of preSaveHooksSuccessOrFailure) {
|
|
700
|
+
const success = _.get(preSaveHook, 'isSuccess');
|
|
701
|
+
if (!success) {
|
|
702
|
+
preTriggersSuccessOrFailure = false;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return preTriggersSuccessOrFailure;
|
|
707
|
+
}
|
|
708
|
+
//Post login and pre update/create user
|
|
709
|
+
async triggerPreSaveTriggers(user, config, mode = 'onUpdate') {
|
|
710
|
+
sails.log.verbose("Triggering pre save triggers for user login: ");
|
|
711
|
+
sails.log.verbose(`hooks.${mode}.pre`);
|
|
712
|
+
sails.log.verbose(JSON.stringify(config));
|
|
713
|
+
const preSaveUpdateHooks = _.get(config, `hooks.${mode}.pre`, null);
|
|
714
|
+
sails.log.debug(preSaveUpdateHooks);
|
|
715
|
+
if (_.isArray(preSaveUpdateHooks)) {
|
|
716
|
+
for (let i = 0; i < preSaveUpdateHooks.length; i++) {
|
|
717
|
+
const preSaveUpdateHook = preSaveUpdateHooks[i];
|
|
718
|
+
const preSaveUpdateHookFunctionString = _.get(preSaveUpdateHook, 'function', null);
|
|
719
|
+
if (preSaveUpdateHookFunctionString != null) {
|
|
720
|
+
try {
|
|
721
|
+
const preSaveUpdateHookFunction = eval(preSaveUpdateHookFunctionString);
|
|
722
|
+
const options = _.get(preSaveUpdateHook, 'options', {});
|
|
723
|
+
let failureMode = String(_.get(preSaveUpdateHook, 'failureMode', ''));
|
|
724
|
+
if (_.isUndefined(failureMode) || (failureMode != 'continue' && failureMode != 'stop')) {
|
|
725
|
+
failureMode = 'continue';
|
|
726
|
+
}
|
|
727
|
+
sails.log.verbose(`Triggering pre save triggers: ${preSaveUpdateHookFunctionString} failureMode ${failureMode}`);
|
|
728
|
+
const hookResponse = preSaveUpdateHookFunction(user, options, failureMode);
|
|
729
|
+
user = await this.resolveHookResponse(hookResponse);
|
|
730
|
+
sails.log.debug(`${preSaveUpdateHookFunctionString} response now is:`);
|
|
731
|
+
try {
|
|
732
|
+
sails.log.verbose(JSON.stringify(user));
|
|
733
|
+
}
|
|
734
|
+
catch (_error) {
|
|
735
|
+
sails.log.verbose(user);
|
|
736
|
+
}
|
|
737
|
+
sails.log.debug(`pre-save sync trigger ${preSaveUpdateHookFunctionString} completed for user: ${_.get(user, 'username')}`);
|
|
738
|
+
}
|
|
739
|
+
catch (err) {
|
|
740
|
+
sails.log.error(`pre-save sync trigger ${preSaveUpdateHookFunctionString} failed to complete`);
|
|
741
|
+
sails.log.error(err);
|
|
742
|
+
throw err;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return user;
|
|
748
|
+
}
|
|
749
|
+
//Post login and post update/create user sync
|
|
750
|
+
async triggerPostSaveSyncTriggers(user, config, mode = 'onUpdate', response = {}) {
|
|
751
|
+
sails.log.verbose("Triggering post save sync triggers ");
|
|
752
|
+
sails.log.verbose(`hooks.${mode}.postSync`);
|
|
753
|
+
sails.log.verbose(JSON.stringify(config));
|
|
754
|
+
const postSaveSyncHooks = _.get(config, `hooks.${mode}.postSync`, null);
|
|
755
|
+
if (_.isArray(postSaveSyncHooks)) {
|
|
756
|
+
for (let i = 0; i < postSaveSyncHooks.length; i++) {
|
|
757
|
+
const postSaveSyncHook = postSaveSyncHooks[i];
|
|
758
|
+
sails.log.debug(postSaveSyncHooks);
|
|
759
|
+
const postSaveSyncHooksFunctionString = _.get(postSaveSyncHook, "function", null);
|
|
760
|
+
if (postSaveSyncHooksFunctionString != null) {
|
|
761
|
+
const postSaveSyncHookFunction = eval(postSaveSyncHooksFunctionString);
|
|
762
|
+
const options = _.get(postSaveSyncHook, "options", {});
|
|
763
|
+
if (_.isFunction(postSaveSyncHookFunction)) {
|
|
764
|
+
try {
|
|
765
|
+
sails.log.debug(`Triggering post-save sync trigger: ${postSaveSyncHooksFunctionString}`);
|
|
766
|
+
const hookResponse = postSaveSyncHookFunction(user, options, response);
|
|
767
|
+
response = await this.resolveHookResponse(hookResponse);
|
|
768
|
+
sails.log.debug(`${postSaveSyncHooksFunctionString} response now is:`);
|
|
769
|
+
sails.log.verbose(JSON.stringify(response));
|
|
770
|
+
sails.log.debug(`post-save sync trigger ${postSaveSyncHooksFunctionString} completed for user: ${_.get(user, 'username')}`);
|
|
771
|
+
}
|
|
772
|
+
catch (err) {
|
|
773
|
+
sails.log.error(`post-save async trigger ${postSaveSyncHooksFunctionString} failed to complete`);
|
|
774
|
+
sails.log.error(err);
|
|
775
|
+
throw err;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
sails.log.error(`Post save function: '${postSaveSyncHooksFunctionString}' did not resolve to a valid function, what I got:`);
|
|
780
|
+
sails.log.error(postSaveSyncHookFunction);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
return response;
|
|
786
|
+
}
|
|
787
|
+
//Post login and post update/create user
|
|
788
|
+
triggerPostSaveTriggers(user, config, mode = 'onUpdate') {
|
|
789
|
+
sails.log.verbose("Triggering post save triggers ");
|
|
790
|
+
sails.log.verbose(`hooks.${mode}.post`);
|
|
791
|
+
sails.log.verbose(JSON.stringify(config));
|
|
792
|
+
const postSaveCreateHooks = _.get(config, `hooks.${mode}.post`, null);
|
|
793
|
+
if (_.isArray(postSaveCreateHooks)) {
|
|
794
|
+
_.each(postSaveCreateHooks, (postSaveCreateHook) => {
|
|
795
|
+
sails.log.debug(postSaveCreateHook);
|
|
796
|
+
const postSaveCreateHookFunctionString = _.get(postSaveCreateHook, "function", null);
|
|
797
|
+
if (postSaveCreateHookFunctionString != null) {
|
|
798
|
+
const postSaveCreateHookFunction = eval(postSaveCreateHookFunctionString);
|
|
799
|
+
const options = _.get(postSaveCreateHook, "options", {});
|
|
800
|
+
if (_.isFunction(postSaveCreateHookFunction)) {
|
|
801
|
+
const hookResponse = postSaveCreateHookFunction(user, options);
|
|
802
|
+
this.resolveHookResponse(hookResponse).then(_result => {
|
|
803
|
+
sails.log.debug(`post-save trigger ${postSaveCreateHookFunctionString} completed for user: ${_.get(user, 'username')}`);
|
|
804
|
+
}).catch(error => {
|
|
805
|
+
sails.log.error(`post-save trigger ${postSaveCreateHookFunctionString} failed to complete`);
|
|
806
|
+
sails.log.error(error);
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
else {
|
|
810
|
+
sails.log.error(`Post save function: '${postSaveCreateHookFunctionString}' did not resolve to a valid function, what I got:`);
|
|
811
|
+
sails.log.error(postSaveCreateHookFunction);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
resolveHookResponse(hookResponse) {
|
|
818
|
+
if ((0, rxjs_2.isObservable)(hookResponse)) {
|
|
819
|
+
return (0, rxjs_1.firstValueFrom)(hookResponse);
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
return Promise.resolve(hookResponse);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
aafAuthInit = () => {
|
|
826
|
+
this.registerSailsHook('on', 'ready', async () => {
|
|
827
|
+
// uses the default brand's configuration once sails is fully ready
|
|
828
|
+
const defaultBrandName = BrandingService.getDefault().name;
|
|
829
|
+
const defAuthConfig = this.getAuthConfig(defaultBrandName);
|
|
830
|
+
//
|
|
831
|
+
// JWT/AAF Strategy
|
|
832
|
+
//
|
|
833
|
+
const that = this;
|
|
834
|
+
sails.log.verbose(`AAF auth init for default brand "${defaultBrandName}" with active providers: ${JSON.stringify(defAuthConfig.active ?? [])}`);
|
|
835
|
+
if (defAuthConfig.active != undefined && defAuthConfig.active.indexOf('aaf') != -1) {
|
|
836
|
+
const JwtStrategy = require('passport-jwt').Strategy, ExtractJwt = require('passport-jwt').ExtractJwt;
|
|
837
|
+
const configuredAafOpts = (defAuthConfig.aaf?.opts ?? {});
|
|
838
|
+
const aafOpts = Object.assign({}, configuredAafOpts);
|
|
839
|
+
aafOpts.passReqToCallback = true;
|
|
840
|
+
// Default JWT options for AAF; allow overrides from config
|
|
841
|
+
const jwtDefaults = {
|
|
842
|
+
issuer: 'https://rapid.aaf.edu.au',
|
|
843
|
+
ignoreNotBefore: true,
|
|
844
|
+
clockTolerance: 120,
|
|
845
|
+
};
|
|
846
|
+
aafOpts.jsonWebTokenOptions = Object.assign({}, jwtDefaults, (configuredAafOpts.jsonWebTokenOptions ?? {}));
|
|
847
|
+
aafOpts.jwtFromRequest = ExtractJwt.fromBodyField('assertion');
|
|
848
|
+
sails.log.verbose(`Registering Passport strategy "aaf-jwt" with option keys: ${JSON.stringify(Object.keys(aafOpts))}`);
|
|
849
|
+
sails.config.passport.use('aaf-jwt', new JwtStrategy(aafOpts, function (req, jwt_payload, done) {
|
|
850
|
+
const brandName = BrandingService.getBrandNameFromReq(req);
|
|
851
|
+
const brand = BrandingService.getBrand(brandName);
|
|
852
|
+
const authConfig = that.getAuthConfig(brand.name);
|
|
853
|
+
const aafAttributes = authConfig.aaf?.attributesField ?? DEFAULT_AAF_ATTRIBUTES_FIELD;
|
|
854
|
+
sails.log.verbose(`Configured roles: ${JSON.stringify(sails.config.auth.roles)}`);
|
|
855
|
+
sails.log.verbose(`AAF default roles: ${JSON.stringify(authConfig.aaf?.defaultRole)}`);
|
|
856
|
+
sails.log.verbose(`Brand roles: ${JSON.stringify(brand.roles)}`);
|
|
857
|
+
const defaultAuthRole = RolesService.getDefAuthenticatedRole(brand);
|
|
858
|
+
let aafDefRoles = [];
|
|
859
|
+
if (defaultAuthRole != undefined) {
|
|
860
|
+
aafDefRoles = _.map(RolesService.getNestedRoles(defaultAuthRole.name, brand.roles), 'id');
|
|
861
|
+
}
|
|
862
|
+
const aafUsernameField = authConfig.aaf?.usernameField ?? DEFAULT_AAF_USERNAME_FIELD;
|
|
863
|
+
const aafUsername = String(jwt_payload[aafUsernameField] ?? '');
|
|
864
|
+
const userName = Buffer.from(aafUsername).toString('base64');
|
|
865
|
+
User.findOne({
|
|
866
|
+
username: userName
|
|
867
|
+
}, function (err, user) {
|
|
868
|
+
sails.log.verbose(`At AAF Strategy verify for brand "${brandName}" using username "${aafUsername}"`);
|
|
869
|
+
sails.log.verbose(`AAF resolved attributes field "${aafAttributes}"`);
|
|
870
|
+
sails.log.verbose(`AAF user lookup result: ${user ? `found user id=${String(user.id ?? 'unknown')}` : 'no user found'}`);
|
|
871
|
+
sails.log.verbose(`AAF verify error: ${err == null ? 'null' : err instanceof Error ? err.message : String(err)}`);
|
|
872
|
+
if (err) {
|
|
873
|
+
return done(err, false);
|
|
874
|
+
}
|
|
875
|
+
if (user) {
|
|
876
|
+
const userObj = user;
|
|
877
|
+
// Gate disabled users
|
|
878
|
+
that.assertAuthenticationAllowed(userObj).then(() => {
|
|
879
|
+
const attrs = (jwt_payload[aafAttributes] ?? {});
|
|
880
|
+
userObj.lastLogin = new Date();
|
|
881
|
+
userObj.name = String(attrs.cn ?? '');
|
|
882
|
+
userObj.email = String(attrs.mail ?? '').toLowerCase();
|
|
883
|
+
userObj.displayname = _.isNil(attrs.displayname) ? undefined : String(attrs.displayname);
|
|
884
|
+
userObj.cn = _.isNil(attrs.cn) ? undefined : String(attrs.cn);
|
|
885
|
+
userObj.edupersonscopedaffiliation = _.isNil(attrs.edupersonscopedaffiliation) ? undefined : String(attrs.edupersonscopedaffiliation);
|
|
886
|
+
userObj.edupersontargetedid = _.isNil(attrs.edupersontargetedid) ? undefined : String(attrs.edupersontargetedid);
|
|
887
|
+
userObj.edupersonprincipalname = _.isNil(attrs.edupersonprincipalname) ? undefined : String(attrs.edupersonprincipalname);
|
|
888
|
+
userObj.givenname = _.isNil(attrs.givenname) ? undefined : String(attrs.givenname);
|
|
889
|
+
userObj.surname = _.isNil(attrs.surname) ? undefined : String(attrs.surname);
|
|
890
|
+
const configAAF = _.get(defAuthConfig, 'aaf', {});
|
|
891
|
+
if (that.hasPreSaveTriggerConfigured(configAAF, 'onUpdate')) {
|
|
892
|
+
that.triggerPreSaveTriggers(userObj, configAAF).then((userAdditionalInfo) => {
|
|
893
|
+
const success = that.checkAllTriggersSuccessOrFailure(userAdditionalInfo);
|
|
894
|
+
if (success) {
|
|
895
|
+
User.update({
|
|
896
|
+
username: _.get(userAdditionalInfo, 'username')
|
|
897
|
+
}).set(userAdditionalInfo).exec(function (err, user) {
|
|
898
|
+
if (err) {
|
|
899
|
+
sails.log.error("Error updating user:");
|
|
900
|
+
sails.log.error(err);
|
|
901
|
+
return done(err, false, { message: "Error updating user" });
|
|
902
|
+
}
|
|
903
|
+
if (_.isEmpty(user)) {
|
|
904
|
+
sails.log.error("No user found");
|
|
905
|
+
return done("No user found", false, { message: "No user found" });
|
|
906
|
+
}
|
|
907
|
+
if (that.hasPostSaveTriggerConfigured(configAAF, 'onUpdate')) {
|
|
908
|
+
that.triggerPostSaveTriggers(user, configAAF);
|
|
909
|
+
}
|
|
910
|
+
if (that.hasPostSaveSyncTriggerConfigured(configAAF, 'onUpdate')) {
|
|
911
|
+
that.triggerPostSaveSyncTriggers(user, configAAF);
|
|
912
|
+
}
|
|
913
|
+
sails.log.verbose("Done, returning updated user:");
|
|
914
|
+
sails.log.verbose(user);
|
|
915
|
+
const updatedUsers = user;
|
|
916
|
+
that.resolveLinkedUserCandidate(updatedUsers[0])
|
|
917
|
+
.then((resolvedUser) => done(null, resolvedUser, {
|
|
918
|
+
message: 'Logged In Successfully'
|
|
919
|
+
}))
|
|
920
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
921
|
+
return;
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
return done('All required conditions for login not met', false, { message: 'All required conditions for login not met' });
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
else {
|
|
930
|
+
User.update({
|
|
931
|
+
username: userObj.username
|
|
932
|
+
}).set(userObj).exec(function (err, user) {
|
|
933
|
+
if (err) {
|
|
934
|
+
sails.log.error("Error updating user:");
|
|
935
|
+
sails.log.error(err);
|
|
936
|
+
return done(err, false, { message: "Error updating user" });
|
|
937
|
+
}
|
|
938
|
+
if (_.isEmpty(user)) {
|
|
939
|
+
sails.log.error("No user found");
|
|
940
|
+
return done("No user found", false, { message: "No user found" });
|
|
941
|
+
}
|
|
942
|
+
if (that.hasPostSaveTriggerConfigured(configAAF, 'onUpdate')) {
|
|
943
|
+
that.triggerPostSaveTriggers(user, configAAF);
|
|
944
|
+
}
|
|
945
|
+
if (that.hasPostSaveSyncTriggerConfigured(configAAF, 'onUpdate')) {
|
|
946
|
+
that.triggerPostSaveSyncTriggers(user, configAAF);
|
|
947
|
+
}
|
|
948
|
+
sails.log.verbose("Done, returning updated user:");
|
|
949
|
+
sails.log.verbose(user);
|
|
950
|
+
const updatedUsers = user;
|
|
951
|
+
that.resolveLinkedUserCandidate(updatedUsers[0])
|
|
952
|
+
.then((resolvedUser) => done(null, resolvedUser, {
|
|
953
|
+
message: 'Logged In Successfully'
|
|
954
|
+
}))
|
|
955
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
956
|
+
return;
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
}).catch((err) => {
|
|
960
|
+
if (err instanceof Error && err.message === 'Account is disabled') {
|
|
961
|
+
return done(null, false, { message: 'Account is disabled' });
|
|
962
|
+
}
|
|
963
|
+
return done(err);
|
|
964
|
+
}); // end AAF disabled gate
|
|
965
|
+
}
|
|
966
|
+
else {
|
|
967
|
+
sails.log.verbose("At AAF Strategy verify, creating new user...");
|
|
968
|
+
// first time login, create with default role
|
|
969
|
+
const attrs = (jwt_payload[aafAttributes] ?? {});
|
|
970
|
+
const normalizedUsername = String(userName);
|
|
971
|
+
const normalizedEmail = String(attrs.mail ?? '').toLowerCase();
|
|
972
|
+
const normalizedCn = _.isNil(attrs.cn) ? undefined : String(attrs.cn);
|
|
973
|
+
const normalizedDisplayName = _.isNil(attrs.displayname) ? undefined : String(attrs.displayname);
|
|
974
|
+
const normalizedEduPersonScopedAffiliation = _.isNil(attrs.edupersonscopedaffiliation) ? undefined : String(attrs.edupersonscopedaffiliation);
|
|
975
|
+
const normalizedEduPersonTargetedId = _.isNil(attrs.edupersontargetedid) ? undefined : String(attrs.edupersontargetedid);
|
|
976
|
+
const normalizedEduPersonPrincipalName = _.isNil(attrs.edupersonprincipalname) ? undefined : String(attrs.edupersonprincipalname);
|
|
977
|
+
const normalizedGivenName = _.isNil(attrs.givenname) ? undefined : String(attrs.givenname);
|
|
978
|
+
const normalizedSurname = _.isNil(attrs.surname) ? undefined : String(attrs.surname);
|
|
979
|
+
const normalizedFullName = [normalizedGivenName, normalizedSurname]
|
|
980
|
+
.filter((value) => !_.isNil(value) && value.trim().length > 0)
|
|
981
|
+
.join(' ');
|
|
982
|
+
const normalizedName = normalizedCn ?? normalizedDisplayName ?? (normalizedFullName.length > 0 ? normalizedFullName : undefined) ?? normalizedUsername;
|
|
983
|
+
let userToCreate = {
|
|
984
|
+
username: normalizedUsername,
|
|
985
|
+
name: normalizedName,
|
|
986
|
+
email: normalizedEmail,
|
|
987
|
+
displayname: normalizedDisplayName,
|
|
988
|
+
cn: normalizedCn,
|
|
989
|
+
edupersonscopedaffiliation: normalizedEduPersonScopedAffiliation,
|
|
990
|
+
edupersontargetedid: normalizedEduPersonTargetedId,
|
|
991
|
+
edupersonprincipalname: normalizedEduPersonPrincipalName,
|
|
992
|
+
givenname: normalizedGivenName,
|
|
993
|
+
surname: normalizedSurname,
|
|
994
|
+
type: 'aaf',
|
|
995
|
+
roles: aafDefRoles,
|
|
996
|
+
lastLogin: new Date()
|
|
997
|
+
};
|
|
998
|
+
sails.log.verbose(`AAF prepared user create request for brand "${brandName}" and username "${aafUsername}"`);
|
|
999
|
+
const emailAuthorizedCheck = that.checkAuthorizedEmail(String(userToCreate.email ?? ''), brandName, 'aaf');
|
|
1000
|
+
if (!emailAuthorizedCheck) {
|
|
1001
|
+
return done("authorized-email-denied", false);
|
|
1002
|
+
}
|
|
1003
|
+
const configAAF = _.get(defAuthConfig, 'aaf', {});
|
|
1004
|
+
if (that.hasPreSaveTriggerConfigured(configAAF, 'onCreate')) {
|
|
1005
|
+
that.triggerPreSaveTriggers(userToCreate, configAAF, 'onCreate').then((userAdditionalInfo) => {
|
|
1006
|
+
const success = that.checkAllTriggersSuccessOrFailure(userAdditionalInfo);
|
|
1007
|
+
if (success) {
|
|
1008
|
+
userToCreate = userAdditionalInfo;
|
|
1009
|
+
User.create(userToCreate).exec(function (err, newUser) {
|
|
1010
|
+
if (err) {
|
|
1011
|
+
sails.log.error("Error creating new user:");
|
|
1012
|
+
sails.log.error(err);
|
|
1013
|
+
return done(err, false);
|
|
1014
|
+
}
|
|
1015
|
+
if (that.hasPostSaveTriggerConfigured(configAAF, 'onCreate')) {
|
|
1016
|
+
that.triggerPostSaveTriggers(newUser, configAAF, 'onCreate');
|
|
1017
|
+
}
|
|
1018
|
+
if (that.hasPostSaveSyncTriggerConfigured(configAAF, 'onCreate')) {
|
|
1019
|
+
that.triggerPostSaveSyncTriggers(newUser, configAAF, 'onCreate');
|
|
1020
|
+
}
|
|
1021
|
+
sails.log.verbose("Done, returning new user:");
|
|
1022
|
+
sails.log.verbose(newUser);
|
|
1023
|
+
that.resolveLinkedUserCandidate(newUser)
|
|
1024
|
+
.then((resolvedUser) => done(null, resolvedUser))
|
|
1025
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
1026
|
+
return;
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
else {
|
|
1030
|
+
return done(null, false, { message: 'All required conditions for login not met' });
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
else {
|
|
1035
|
+
User.create(userToCreate).exec(function (err, newUser) {
|
|
1036
|
+
if (err) {
|
|
1037
|
+
sails.log.error("Error creating new user:");
|
|
1038
|
+
sails.log.error(err);
|
|
1039
|
+
return done(err, false);
|
|
1040
|
+
}
|
|
1041
|
+
if (that.hasPostSaveTriggerConfigured(configAAF, 'onCreate')) {
|
|
1042
|
+
that.triggerPostSaveTriggers(newUser, configAAF, 'onCreate');
|
|
1043
|
+
}
|
|
1044
|
+
if (that.hasPostSaveSyncTriggerConfigured(configAAF, 'onCreate')) {
|
|
1045
|
+
that.triggerPostSaveSyncTriggers(newUser, configAAF, 'onCreate');
|
|
1046
|
+
}
|
|
1047
|
+
sails.log.verbose("Done, returning new user:");
|
|
1048
|
+
sails.log.verbose(newUser);
|
|
1049
|
+
that.resolveLinkedUserCandidate(newUser)
|
|
1050
|
+
.then((resolvedUser) => done(null, resolvedUser))
|
|
1051
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
1052
|
+
return;
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
}));
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
sails.log.verbose(`AAF strategy registration skipped because "aaf" is not in active providers.`);
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
};
|
|
1064
|
+
openIdConnectAuth = () => {
|
|
1065
|
+
this.registerSailsHook('on', 'ready', async () => {
|
|
1066
|
+
const defAuthConfig = this.getAuthConfig(BrandingService.getDefault().name);
|
|
1067
|
+
sails.log.verbose(`OIDC, checking if within active array: ${defAuthConfig.active}`);
|
|
1068
|
+
if (defAuthConfig.active != undefined && defAuthConfig.active.indexOf('oidc') != -1) {
|
|
1069
|
+
const that = this;
|
|
1070
|
+
sails.log.verbose(`OIDC is active, configuring....`);
|
|
1071
|
+
let oidcConfigArray = [];
|
|
1072
|
+
if (Array.isArray(defAuthConfig.oidc)) {
|
|
1073
|
+
oidcConfigArray = defAuthConfig.oidc;
|
|
1074
|
+
}
|
|
1075
|
+
else if (_.isObject(defAuthConfig.oidc) && !_.isEmpty(defAuthConfig.oidc)) {
|
|
1076
|
+
oidcConfigArray = [defAuthConfig.oidc];
|
|
1077
|
+
}
|
|
1078
|
+
for (const oidcConfig of oidcConfigArray) {
|
|
1079
|
+
const oidcOpts = oidcConfig.opts;
|
|
1080
|
+
const openIdClient = require('openid-client');
|
|
1081
|
+
const { Strategy } = require('openid-client/passport');
|
|
1082
|
+
let configured = false;
|
|
1083
|
+
let discoverAttemptsCtr = 0;
|
|
1084
|
+
while (!configured && discoverAttemptsCtr < oidcConfig.discoverAttemptsMax) {
|
|
1085
|
+
discoverAttemptsCtr++;
|
|
1086
|
+
try {
|
|
1087
|
+
const clientMetadata = (oidcOpts.client ?? {});
|
|
1088
|
+
const clientId = String(clientMetadata.client_id ?? '');
|
|
1089
|
+
let oidcClientConfig;
|
|
1090
|
+
if (_.isString(oidcOpts.issuer)) {
|
|
1091
|
+
const issuerUrl = String(oidcOpts.issuer).replace(/\/+$/, '');
|
|
1092
|
+
sails.log.verbose(`OIDC, using issuer URL for discovery: ${issuerUrl}`);
|
|
1093
|
+
const discoveryOptions = issuerUrl.startsWith('http://')
|
|
1094
|
+
? { execute: [openIdClient.allowInsecureRequests] }
|
|
1095
|
+
: undefined;
|
|
1096
|
+
oidcClientConfig = await openIdClient.discovery(new URL(issuerUrl), clientId, clientMetadata, undefined, discoveryOptions);
|
|
1097
|
+
}
|
|
1098
|
+
else {
|
|
1099
|
+
sails.log.verbose(`OIDC, using issuer hardcoded configuration:`);
|
|
1100
|
+
sails.log.verbose(JSON.stringify(oidcOpts.issuer));
|
|
1101
|
+
oidcClientConfig = new openIdClient.Configuration(oidcOpts.issuer, clientId, clientMetadata);
|
|
1102
|
+
const configuredIssuer = String(oidcOpts.issuer?.issuer ?? '');
|
|
1103
|
+
if (configuredIssuer.startsWith('http://')) {
|
|
1104
|
+
openIdClient.allowInsecureRequests(oidcClientConfig);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
const serverMetadata = oidcClientConfig.serverMetadata();
|
|
1108
|
+
configured = true;
|
|
1109
|
+
sails.log.verbose(`OIDC, Got issuer config, after ${discoverAttemptsCtr} attempt(s).`);
|
|
1110
|
+
sails.log.verbose(serverMetadata);
|
|
1111
|
+
const verifyCallbackFn = async (req, tokenSet, done) => {
|
|
1112
|
+
try {
|
|
1113
|
+
let userinfo;
|
|
1114
|
+
if (oidcConfig.userInfoSource !== 'tokenset_claims') {
|
|
1115
|
+
const tokenClaims = typeof tokenSet.claims === 'function' ? tokenSet.claims() : {};
|
|
1116
|
+
const accessToken = String(tokenSet.access_token ?? '');
|
|
1117
|
+
const subject = String(_.get(tokenClaims, 'sub', ''));
|
|
1118
|
+
if (!_.isEmpty(accessToken) && !_.isEmpty(subject)) {
|
|
1119
|
+
userinfo = await openIdClient.fetchUserInfo(oidcClientConfig, accessToken, subject);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
that.openIdConnectAuthVerifyCallback(oidcConfig, serverMetadata, req, tokenSet, userinfo, done);
|
|
1123
|
+
}
|
|
1124
|
+
catch (err) {
|
|
1125
|
+
done(err, false);
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
let passportIdentifier = 'oidc';
|
|
1129
|
+
if (!_.isEmpty(oidcConfig.identifier)) {
|
|
1130
|
+
passportIdentifier = `oidc-${oidcConfig.identifier}`;
|
|
1131
|
+
}
|
|
1132
|
+
const strategyOptions = {
|
|
1133
|
+
config: oidcClientConfig,
|
|
1134
|
+
passReqToCallback: true
|
|
1135
|
+
};
|
|
1136
|
+
const callbackUrl = _.get(clientMetadata, 'redirect_uris[0]');
|
|
1137
|
+
if (_.isString(callbackUrl) && !_.isEmpty(callbackUrl)) {
|
|
1138
|
+
strategyOptions.callbackURL = callbackUrl;
|
|
1139
|
+
}
|
|
1140
|
+
const authParams = (oidcOpts.params ?? {});
|
|
1141
|
+
if (_.isString(authParams.scope) && !_.isEmpty(authParams.scope)) {
|
|
1142
|
+
strategyOptions.scope = authParams.scope;
|
|
1143
|
+
}
|
|
1144
|
+
const strategy = new Strategy(strategyOptions, verifyCallbackFn);
|
|
1145
|
+
const additionalAuthParams = _.omit(authParams, ['scope']);
|
|
1146
|
+
if (!_.isEmpty(additionalAuthParams)) {
|
|
1147
|
+
strategy.authorizationRequestParams = () => {
|
|
1148
|
+
const params = new URLSearchParams();
|
|
1149
|
+
for (const [key, value] of Object.entries(additionalAuthParams)) {
|
|
1150
|
+
if (_.isNil(value)) {
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1153
|
+
params.set(key, _.isString(value) ? value : JSON.stringify(value));
|
|
1154
|
+
}
|
|
1155
|
+
return params;
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
sails.config.passport.use(passportIdentifier, strategy);
|
|
1159
|
+
sails.log.info(`OIDC is active, client ${passportIdentifier} configured and ready.`);
|
|
1160
|
+
}
|
|
1161
|
+
catch (e) {
|
|
1162
|
+
sails.log.error(`Failed to discover, attempt# ${discoverAttemptsCtr}:`);
|
|
1163
|
+
sails.log.error(e);
|
|
1164
|
+
await this.sleep(oidcConfig.discoverFailureSleep ?? 1000);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
};
|
|
1171
|
+
openIdConnectAuthVerifyCallback(oidcConfig, issuer, req, tokenSet, userinfo = undefined, done) {
|
|
1172
|
+
const that = this;
|
|
1173
|
+
const session = (req.session ?? {});
|
|
1174
|
+
const query = (req.query ?? {});
|
|
1175
|
+
const logoutFromAuthServer = _.get(oidcConfig, 'logoutFromAuthServer', true);
|
|
1176
|
+
if (logoutFromAuthServer) {
|
|
1177
|
+
session.logoutUrl = issuer.end_session_endpoint;
|
|
1178
|
+
const postLogoutUris = (_.get(oidcConfig.opts, 'client.post_logout_redirect_uris', []) ?? []);
|
|
1179
|
+
if (!_.isEmpty(postLogoutUris)) {
|
|
1180
|
+
session.logoutUrl = `${session.logoutUrl}?post_logout_redirect_uri=${postLogoutUris[0]}`;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
else {
|
|
1184
|
+
session.logoutUrl = sails.config.auth.postLogoutRedir;
|
|
1185
|
+
}
|
|
1186
|
+
req.session = session;
|
|
1187
|
+
if (session.redirUrl != null) {
|
|
1188
|
+
//the session url changes after login so we lose this value if we don't put it on the queru string
|
|
1189
|
+
query.redirUrl = session.redirUrl;
|
|
1190
|
+
req.query = query;
|
|
1191
|
+
}
|
|
1192
|
+
sails.log.verbose(`OIDC login success, tokenset: `);
|
|
1193
|
+
sails.log.verbose(JSON.stringify(tokenSet));
|
|
1194
|
+
sails.log.verbose(`Claims:`);
|
|
1195
|
+
const tokenClaims = typeof tokenSet.claims === 'function' ? tokenSet.claims() : {};
|
|
1196
|
+
sails.log.verbose(JSON.stringify(tokenClaims));
|
|
1197
|
+
if (!_.isUndefined(userinfo)) {
|
|
1198
|
+
sails.log.verbose(`Userinfo:`);
|
|
1199
|
+
sails.log.verbose(JSON.stringify(userinfo));
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
userinfo = tokenClaims;
|
|
1203
|
+
}
|
|
1204
|
+
if (oidcConfig.debugMode === true) {
|
|
1205
|
+
sails.log.info("OIDC debug mode is active, intentionally failing the login, and redirecting to failure page with all details of this login attempt.");
|
|
1206
|
+
const err = {
|
|
1207
|
+
userinfo: userinfo,
|
|
1208
|
+
claims: tokenClaims,
|
|
1209
|
+
tokenSet: tokenSet
|
|
1210
|
+
};
|
|
1211
|
+
session.errorTextRaw = JSON.stringify(err, null, 2);
|
|
1212
|
+
return done(null, false);
|
|
1213
|
+
}
|
|
1214
|
+
const brandName = session.branding ?? BrandingService.getDefault().name;
|
|
1215
|
+
const brand = BrandingService.getBrand(brandName);
|
|
1216
|
+
const claimsMappings = (oidcConfig.claimMappings ?? {});
|
|
1217
|
+
let userName = '';
|
|
1218
|
+
const tmpUserName = String(_.get(userinfo, claimsMappings['username'], ''));
|
|
1219
|
+
const claimsMappingOptions = (oidcConfig.claimMappingOptions ?? {});
|
|
1220
|
+
let usernameToLowercase = false;
|
|
1221
|
+
if (!_.isUndefined(claimsMappingOptions) && !_.isEmpty(claimsMappingOptions)) {
|
|
1222
|
+
usernameToLowercase = !!claimsMappingOptions['usernameToLowercase'];
|
|
1223
|
+
}
|
|
1224
|
+
sails.log.verbose("usernameToLowercase " + usernameToLowercase);
|
|
1225
|
+
if (usernameToLowercase) {
|
|
1226
|
+
userName = tmpUserName.toLowerCase();
|
|
1227
|
+
sails.log.verbose("usernameToLowercase " + userName);
|
|
1228
|
+
}
|
|
1229
|
+
else {
|
|
1230
|
+
userName = tmpUserName;
|
|
1231
|
+
sails.log.verbose(userName);
|
|
1232
|
+
}
|
|
1233
|
+
const defAuthRole = RolesService.getDefAuthenticatedRole(brand);
|
|
1234
|
+
const defAuthRoleName = defAuthRole?.name ?? 'Researcher';
|
|
1235
|
+
const openIdConnectDefRoles = _.map(RolesService.getNestedRoles(defAuthRoleName, brand.roles), 'id');
|
|
1236
|
+
// This can occur when the claim mappings are incorrect or a login was cancelled
|
|
1237
|
+
if (_.isEmpty(userName)) {
|
|
1238
|
+
return done(null, null, {
|
|
1239
|
+
message: 'Rejected as username does not have a value'
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
User.findOne({
|
|
1243
|
+
username: userName
|
|
1244
|
+
}, function (err, user) {
|
|
1245
|
+
sails.log.verbose("At OIDC Strategy verify, payload:");
|
|
1246
|
+
sails.log.verbose(userinfo);
|
|
1247
|
+
sails.log.verbose("User:");
|
|
1248
|
+
sails.log.verbose(user);
|
|
1249
|
+
sails.log.verbose("Error:");
|
|
1250
|
+
sails.log.verbose(err);
|
|
1251
|
+
if (err) {
|
|
1252
|
+
return done(err, false);
|
|
1253
|
+
}
|
|
1254
|
+
if (user) {
|
|
1255
|
+
const userObj = user;
|
|
1256
|
+
// Gate disabled users
|
|
1257
|
+
that.assertAuthenticationAllowed(userObj).then(() => {
|
|
1258
|
+
sails.log.error("At OIDC Strategy verify, updating new user...");
|
|
1259
|
+
userObj.lastLogin = new Date();
|
|
1260
|
+
const additionalAttributesMapping = claimsMappings['additionalAttributes'];
|
|
1261
|
+
userObj.additionalAttributes = that.mapAdditionalAttributes(userinfo, (typeof additionalAttributesMapping === 'object' && additionalAttributesMapping != null
|
|
1262
|
+
? additionalAttributesMapping
|
|
1263
|
+
: {}));
|
|
1264
|
+
userObj.name = String(_.get(userinfo, claimsMappings['name'] ?? '', ''));
|
|
1265
|
+
userObj.email = String(_.get(userinfo, claimsMappings['email'] ?? '', '')).toLowerCase();
|
|
1266
|
+
const displayName = _.get(userinfo, claimsMappings['displayName'] ?? '');
|
|
1267
|
+
const commonName = _.get(userinfo, claimsMappings['cn'] ?? '');
|
|
1268
|
+
const givenName = _.get(userinfo, claimsMappings['givenname'] ?? '');
|
|
1269
|
+
const surname = _.get(userinfo, claimsMappings['surname'] ?? '');
|
|
1270
|
+
userObj.displayname = _.isNil(displayName) ? undefined : String(displayName);
|
|
1271
|
+
userObj.cn = _.isNil(commonName) ? undefined : String(commonName);
|
|
1272
|
+
userObj.givenname = _.isNil(givenName) ? undefined : String(givenName);
|
|
1273
|
+
userObj.surname = _.isNil(surname) ? undefined : String(surname);
|
|
1274
|
+
if (that.hasPreSaveTriggerConfigured(oidcConfig, 'onUpdate')) {
|
|
1275
|
+
that.triggerPreSaveTriggers(userObj, oidcConfig).then((userAdditionalInfo) => {
|
|
1276
|
+
const success = that.checkAllTriggersSuccessOrFailure(userAdditionalInfo);
|
|
1277
|
+
if (success) {
|
|
1278
|
+
User.update({
|
|
1279
|
+
username: _.get(userAdditionalInfo, 'username')
|
|
1280
|
+
}).set(userAdditionalInfo).exec(function (err, user) {
|
|
1281
|
+
if (err) {
|
|
1282
|
+
sails.log.error("Error updating user:");
|
|
1283
|
+
sails.log.error(err);
|
|
1284
|
+
return done(err, false);
|
|
1285
|
+
}
|
|
1286
|
+
if (_.isEmpty(user)) {
|
|
1287
|
+
sails.log.error("No user found");
|
|
1288
|
+
return done("No user found", false);
|
|
1289
|
+
}
|
|
1290
|
+
if (that.hasPostSaveTriggerConfigured(oidcConfig, 'onUpdate')) {
|
|
1291
|
+
that.triggerPostSaveTriggers(user, oidcConfig);
|
|
1292
|
+
}
|
|
1293
|
+
if (that.hasPostSaveSyncTriggerConfigured(oidcConfig, 'onUpdate')) {
|
|
1294
|
+
that.triggerPostSaveSyncTriggers(user, oidcConfig);
|
|
1295
|
+
}
|
|
1296
|
+
const updatedUsers = user;
|
|
1297
|
+
sails.log.verbose(`Done, returning updated user id=${String(updatedUsers[0]?.id ?? 'unknown')}`);
|
|
1298
|
+
that.resolveLinkedUserCandidate(updatedUsers[0])
|
|
1299
|
+
.then((resolvedUser) => done(null, resolvedUser))
|
|
1300
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
1301
|
+
return;
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
else {
|
|
1305
|
+
return done('All required conditions for login not met', false);
|
|
1306
|
+
}
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
else {
|
|
1310
|
+
User.update({
|
|
1311
|
+
username: userObj.username
|
|
1312
|
+
}).set(userObj).exec(function (err, user) {
|
|
1313
|
+
if (err) {
|
|
1314
|
+
sails.log.error("Error updating user:");
|
|
1315
|
+
sails.log.error(err);
|
|
1316
|
+
return done(err, false);
|
|
1317
|
+
}
|
|
1318
|
+
if (_.isEmpty(user)) {
|
|
1319
|
+
sails.log.error("No user found");
|
|
1320
|
+
return done("No user found", false);
|
|
1321
|
+
}
|
|
1322
|
+
if (that.hasPostSaveTriggerConfigured(oidcConfig, 'onUpdate')) {
|
|
1323
|
+
that.triggerPostSaveTriggers(user, oidcConfig);
|
|
1324
|
+
}
|
|
1325
|
+
if (that.hasPostSaveSyncTriggerConfigured(oidcConfig, 'onUpdate')) {
|
|
1326
|
+
that.triggerPostSaveSyncTriggers(user, oidcConfig);
|
|
1327
|
+
}
|
|
1328
|
+
sails.log.verbose("Done, returning updated user:");
|
|
1329
|
+
sails.log.verbose(user);
|
|
1330
|
+
const updatedUsers = user;
|
|
1331
|
+
that.resolveLinkedUserCandidate(updatedUsers[0])
|
|
1332
|
+
.then((resolvedUser) => done(null, resolvedUser))
|
|
1333
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
1334
|
+
return;
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
}).catch((err) => {
|
|
1338
|
+
if (err instanceof Error && err.message === 'Account is disabled') {
|
|
1339
|
+
return done(null, false, { message: 'Account is disabled' });
|
|
1340
|
+
}
|
|
1341
|
+
return done(err);
|
|
1342
|
+
}); // end OIDC disabled gate
|
|
1343
|
+
}
|
|
1344
|
+
else {
|
|
1345
|
+
sails.log.verbose("At OIDC Strategy verify, creating new user...");
|
|
1346
|
+
let userToCreate;
|
|
1347
|
+
try {
|
|
1348
|
+
const additionalAttributesMapping = claimsMappings['additionalAttributes'];
|
|
1349
|
+
const additionalAttributes = that.mapAdditionalAttributes(userinfo, (typeof additionalAttributesMapping === 'object' && additionalAttributesMapping != null
|
|
1350
|
+
? additionalAttributesMapping
|
|
1351
|
+
: {}));
|
|
1352
|
+
// first time login, create with default role
|
|
1353
|
+
userToCreate = {
|
|
1354
|
+
username: userName,
|
|
1355
|
+
name: _.get(userinfo, claimsMappings['name'] ?? ''),
|
|
1356
|
+
email: String(_.get(userinfo, claimsMappings['email'] ?? '', '')).toLowerCase(),
|
|
1357
|
+
displayname: _.get(userinfo, claimsMappings['displayName'] ?? ''),
|
|
1358
|
+
cn: _.get(userinfo, claimsMappings['cn'] ?? ''),
|
|
1359
|
+
givenname: _.get(userinfo, claimsMappings['givenname'] ?? ''),
|
|
1360
|
+
surname: _.get(userinfo, claimsMappings['surname'] ?? ''),
|
|
1361
|
+
type: 'oidc',
|
|
1362
|
+
roles: openIdConnectDefRoles,
|
|
1363
|
+
additionalAttributes: additionalAttributes,
|
|
1364
|
+
lastLogin: new Date()
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
catch (e) {
|
|
1368
|
+
sails.log.error(`Failed to create new user:`);
|
|
1369
|
+
sails.log.error(e);
|
|
1370
|
+
return done(e, false);
|
|
1371
|
+
}
|
|
1372
|
+
sails.log.verbose(`Creating user: `);
|
|
1373
|
+
sails.log.verbose(userToCreate);
|
|
1374
|
+
const emailAuthorizedCheck = that.checkAuthorizedEmail(String(userToCreate.email ?? ''), brandName, 'oidc');
|
|
1375
|
+
if (!emailAuthorizedCheck) {
|
|
1376
|
+
return done("authorized-email-denied", false);
|
|
1377
|
+
}
|
|
1378
|
+
if (that.hasPreSaveTriggerConfigured(oidcConfig, 'onCreate')) {
|
|
1379
|
+
that.triggerPreSaveTriggers(userToCreate, oidcConfig).then((userAdditionalInfo) => {
|
|
1380
|
+
const success = that.checkAllTriggersSuccessOrFailure(userAdditionalInfo);
|
|
1381
|
+
if (success) {
|
|
1382
|
+
User.create(userAdditionalInfo).exec(function (err, newUser) {
|
|
1383
|
+
if (err) {
|
|
1384
|
+
sails.log.error("Error creating new user:");
|
|
1385
|
+
sails.log.error(err);
|
|
1386
|
+
return done(err, false);
|
|
1387
|
+
}
|
|
1388
|
+
if (that.hasPostSaveTriggerConfigured(oidcConfig, 'onCreate')) {
|
|
1389
|
+
that.triggerPostSaveTriggers(newUser, oidcConfig);
|
|
1390
|
+
}
|
|
1391
|
+
if (that.hasPostSaveSyncTriggerConfigured(oidcConfig, 'onCreate')) {
|
|
1392
|
+
that.triggerPostSaveSyncTriggers(newUser, oidcConfig);
|
|
1393
|
+
}
|
|
1394
|
+
sails.log.verbose(`Done, returning new user id=${String(newUser?.id ?? 'unknown')}`);
|
|
1395
|
+
that.resolveLinkedUserCandidate(newUser)
|
|
1396
|
+
.then((resolvedUser) => done(null, resolvedUser))
|
|
1397
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
1398
|
+
return;
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
else {
|
|
1402
|
+
return done('All required conditions for login not met', false);
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
else {
|
|
1407
|
+
User.create(userToCreate).exec(function (err, newUser) {
|
|
1408
|
+
if (err) {
|
|
1409
|
+
sails.log.error("Error creating new user:");
|
|
1410
|
+
sails.log.error(err);
|
|
1411
|
+
return done(err, false);
|
|
1412
|
+
}
|
|
1413
|
+
if (that.hasPostSaveTriggerConfigured(oidcConfig, 'onCreate')) {
|
|
1414
|
+
that.triggerPostSaveTriggers(newUser, oidcConfig);
|
|
1415
|
+
}
|
|
1416
|
+
if (that.hasPostSaveSyncTriggerConfigured(oidcConfig, 'onCreate')) {
|
|
1417
|
+
that.triggerPostSaveSyncTriggers(newUser, oidcConfig);
|
|
1418
|
+
}
|
|
1419
|
+
sails.log.verbose("Done, returning new user:");
|
|
1420
|
+
sails.log.verbose(newUser);
|
|
1421
|
+
that.resolveLinkedUserCandidate(newUser)
|
|
1422
|
+
.then((resolvedUser) => done(null, resolvedUser))
|
|
1423
|
+
.catch((resolveErr) => done(resolveErr, false));
|
|
1424
|
+
return;
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
bearerTokenAuthInit = () => {
|
|
1431
|
+
const BearerStrategy = require('passport-http-bearer').Strategy;
|
|
1432
|
+
const that = this;
|
|
1433
|
+
sails.config.passport.use('bearer', new BearerStrategy(function (token, done) {
|
|
1434
|
+
if (!_.isEmpty(token) && !_.isUndefined(token)) {
|
|
1435
|
+
const tokenHash = crypto.createHash('sha256').update(token).digest('base64');
|
|
1436
|
+
User.findOne({
|
|
1437
|
+
token: tokenHash
|
|
1438
|
+
}).populate('roles').exec(function (err, user) {
|
|
1439
|
+
if (err) {
|
|
1440
|
+
return done(err);
|
|
1441
|
+
}
|
|
1442
|
+
if (!user) {
|
|
1443
|
+
return done(null, false);
|
|
1444
|
+
}
|
|
1445
|
+
// Gate disabled users
|
|
1446
|
+
that.assertAuthenticationAllowed(user).then(() => {
|
|
1447
|
+
that.resolveLinkedUserCandidate(user)
|
|
1448
|
+
.then((resolvedUser) => done(null, resolvedUser, {
|
|
1449
|
+
scope: 'all'
|
|
1450
|
+
}))
|
|
1451
|
+
.catch((resolveErr) => done(resolveErr));
|
|
1452
|
+
}).catch((err) => {
|
|
1453
|
+
if (err instanceof Error && err.message === 'Account is disabled') {
|
|
1454
|
+
return done(null, false);
|
|
1455
|
+
}
|
|
1456
|
+
return done(err);
|
|
1457
|
+
});
|
|
1458
|
+
return;
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
else {
|
|
1462
|
+
// empty token, deny
|
|
1463
|
+
return done(null, false);
|
|
1464
|
+
}
|
|
1465
|
+
}));
|
|
1466
|
+
};
|
|
1467
|
+
initDefAdmin = (defRoles, defAdminRole) => {
|
|
1468
|
+
const authConfig = this.getAuthConfig(BrandingService.getDefault().name);
|
|
1469
|
+
const usernameField = authConfig.local?.usernameField ?? 'username';
|
|
1470
|
+
const passwordField = authConfig.local?.passwordField ?? 'password';
|
|
1471
|
+
const defAdminUsers = (defAdminRole.users ?? []);
|
|
1472
|
+
let defaultUser = _.find(defAdminUsers, (o) => {
|
|
1473
|
+
return o[usernameField] == authConfig.local?.default?.adminUser;
|
|
1474
|
+
});
|
|
1475
|
+
if (defaultUser == null) {
|
|
1476
|
+
defaultUser = {
|
|
1477
|
+
type: 'local',
|
|
1478
|
+
name: 'Local Admin'
|
|
1479
|
+
};
|
|
1480
|
+
defaultUser[usernameField] = authConfig.local?.default?.adminUser;
|
|
1481
|
+
defaultUser[passwordField] = authConfig.local?.default?.adminPw;
|
|
1482
|
+
defaultUser["email"] = authConfig.local?.default?.email;
|
|
1483
|
+
if (authConfig.local?.default?.token) {
|
|
1484
|
+
defaultUser["token"] = crypto.createHash('sha256').update(authConfig.local.default.token).digest('base64');
|
|
1485
|
+
}
|
|
1486
|
+
sails.log.verbose("Default user missing, creating...");
|
|
1487
|
+
return super.getObservable(User.create(defaultUser))
|
|
1488
|
+
.pipe((0, operators_1.mergeMap)(defUser => {
|
|
1489
|
+
// START Sails 1.0 upgrade
|
|
1490
|
+
const defRoleIds = _.map(defRoles, (o) => {
|
|
1491
|
+
return o.id;
|
|
1492
|
+
});
|
|
1493
|
+
const defUserId = defUser.id;
|
|
1494
|
+
let q = User.addToCollection(defUserId, 'roles').members(defRoleIds);
|
|
1495
|
+
// END Sails 1.0 upgrade
|
|
1496
|
+
return super.getObservable(q, 'exec', 'simplecb')
|
|
1497
|
+
.pipe((0, operators_1.mergeMap)(_dUser => {
|
|
1498
|
+
return (0, rxjs_1.from)(defRoles)
|
|
1499
|
+
.pipe((0, operators_1.map)(roleObserved => {
|
|
1500
|
+
const role = roleObserved;
|
|
1501
|
+
// START Sails 1.0 upgrade
|
|
1502
|
+
// role.users.add(defUser.id)
|
|
1503
|
+
const roleId = role.id;
|
|
1504
|
+
q = Role.addToCollection(roleId, 'users').members([defUserId]);
|
|
1505
|
+
// END Sails 1.0 upgrade
|
|
1506
|
+
return super.getObservable(q, 'exec', 'simplecb');
|
|
1507
|
+
}));
|
|
1508
|
+
}), (0, operators_1.last)(), (0, operators_1.mergeMap)(_lastRole => {
|
|
1509
|
+
return (0, rxjs_1.of)({
|
|
1510
|
+
defUser: defUser,
|
|
1511
|
+
defRoles: defRoles
|
|
1512
|
+
});
|
|
1513
|
+
}));
|
|
1514
|
+
}));
|
|
1515
|
+
}
|
|
1516
|
+
else {
|
|
1517
|
+
return (0, rxjs_1.of)({
|
|
1518
|
+
defUser: defaultUser,
|
|
1519
|
+
defRoles: defRoles
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
};
|
|
1523
|
+
mapAdditionalAttributes(profile, attributeMappings) {
|
|
1524
|
+
const additionalAttributes = {};
|
|
1525
|
+
for (const attributeMapping in attributeMappings) {
|
|
1526
|
+
additionalAttributes[attributeMapping] = _.get(profile, attributeMapping);
|
|
1527
|
+
}
|
|
1528
|
+
return additionalAttributes;
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Creates a user audit record
|
|
1532
|
+
*
|
|
1533
|
+
*/
|
|
1534
|
+
addUserAuditEvent = (user, action, additionalContext) => {
|
|
1535
|
+
// ignore audit events for users with no user, which had crashed the app when user has already logged out
|
|
1536
|
+
if (_.isEmpty(user)) {
|
|
1537
|
+
sails.log.verbose('No user to audit, ignoring: ' + action);
|
|
1538
|
+
return (0, rxjs_1.firstValueFrom)((0, rxjs_1.of)(null));
|
|
1539
|
+
}
|
|
1540
|
+
const auditEvent = {};
|
|
1541
|
+
const userObj = user;
|
|
1542
|
+
if (!_.isEmpty(userObj.password)) {
|
|
1543
|
+
delete userObj.password;
|
|
1544
|
+
}
|
|
1545
|
+
userObj.additionalAttributes = this.stringifyObject(userObj.additionalAttributes);
|
|
1546
|
+
auditEvent['user'] = userObj;
|
|
1547
|
+
auditEvent['action'] = action;
|
|
1548
|
+
auditEvent['additionalContext'] = this.stringifyObject(additionalContext);
|
|
1549
|
+
sails.log.verbose('Adding user audit event');
|
|
1550
|
+
sails.log.verbose(auditEvent);
|
|
1551
|
+
return (0, rxjs_1.firstValueFrom)(super.getObservable(UserAudit.create(auditEvent)));
|
|
1552
|
+
};
|
|
1553
|
+
stringifyObject(object) {
|
|
1554
|
+
return JSON.stringify(object, function (key, value) {
|
|
1555
|
+
if (typeof value === 'function') {
|
|
1556
|
+
return 'function-property-not-exported';
|
|
1557
|
+
}
|
|
1558
|
+
else {
|
|
1559
|
+
return value;
|
|
1560
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* @return User: the newly created user
|
|
1565
|
+
*
|
|
1566
|
+
*/
|
|
1567
|
+
addLocalUser = (username, name, email, password) => {
|
|
1568
|
+
const authConfig = this.getAuthConfig(BrandingService.getDefault().name);
|
|
1569
|
+
const usernameField = authConfig.local?.usernameField ?? 'username';
|
|
1570
|
+
const passwordField = authConfig.local?.passwordField ?? 'password';
|
|
1571
|
+
return this.getUserWithUsername(username).pipe((0, operators_1.mergeMap)(user => {
|
|
1572
|
+
if (user) {
|
|
1573
|
+
return (0, rxjs_1.throwError)(new Error(`Username already exists`));
|
|
1574
|
+
}
|
|
1575
|
+
else {
|
|
1576
|
+
return this.findUsersWithEmail(email, null, null).pipe((0, operators_1.mergeMap)(emailCheck => {
|
|
1577
|
+
if (_.size(emailCheck) > 0) {
|
|
1578
|
+
return (0, rxjs_1.throwError)(new Error(`Email already exists, it must be unique`));
|
|
1579
|
+
}
|
|
1580
|
+
else {
|
|
1581
|
+
const newUser = {
|
|
1582
|
+
type: 'local',
|
|
1583
|
+
name: name
|
|
1584
|
+
};
|
|
1585
|
+
if (!_.isEmpty(email)) {
|
|
1586
|
+
newUser["email"] = email;
|
|
1587
|
+
}
|
|
1588
|
+
newUser[usernameField] = username;
|
|
1589
|
+
newUser[passwordField] = password;
|
|
1590
|
+
return super.getObservable(User.create(newUser));
|
|
1591
|
+
}
|
|
1592
|
+
}));
|
|
1593
|
+
}
|
|
1594
|
+
}));
|
|
1595
|
+
};
|
|
1596
|
+
getSearchService() {
|
|
1597
|
+
return sails.services[sails.config.search.serviceName];
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
@return Object {
|
|
1601
|
+
defUser: the default admin user
|
|
1602
|
+
defRoles: the default brand's roles
|
|
1603
|
+
}
|
|
1604
|
+
*/
|
|
1605
|
+
bootstrap = (defRoles) => {
|
|
1606
|
+
sails.log.verbose("Bootstrapping users....");
|
|
1607
|
+
const defAdminRole = RolesService.getAdminFromRoles(defRoles);
|
|
1608
|
+
return (0, rxjs_1.of)(defAdminRole)
|
|
1609
|
+
.pipe((0, operators_1.mergeMap)(defAdminRole => {
|
|
1610
|
+
this.localAuthInit();
|
|
1611
|
+
this.aafAuthInit();
|
|
1612
|
+
this.openIdConnectAuth();
|
|
1613
|
+
this.bearerTokenAuthInit();
|
|
1614
|
+
return this.initDefAdmin(defRoles, defAdminRole);
|
|
1615
|
+
}));
|
|
1616
|
+
};
|
|
1617
|
+
getUserWithUsername = (username) => {
|
|
1618
|
+
return this.getObservable(User.findOne({
|
|
1619
|
+
username: username
|
|
1620
|
+
}).populate('roles'));
|
|
1621
|
+
};
|
|
1622
|
+
getUserWithId = (userid) => {
|
|
1623
|
+
return this.getObservable(User.findOne({
|
|
1624
|
+
id: userid
|
|
1625
|
+
}).populate('roles'));
|
|
1626
|
+
};
|
|
1627
|
+
/**
|
|
1628
|
+
* @return Collection of all users (local and AAF)
|
|
1629
|
+
*/
|
|
1630
|
+
getUsers = () => {
|
|
1631
|
+
return super.getObservable(User.find({}).populate('roles'));
|
|
1632
|
+
};
|
|
1633
|
+
/**
|
|
1634
|
+
* Retrieve all users that hold at least one role for the supplied brand.
|
|
1635
|
+
* @param brand The brand or brand id to scope the search to.
|
|
1636
|
+
*/
|
|
1637
|
+
getUsersForBrand = (brand) => {
|
|
1638
|
+
const brandId = typeof brand === 'string' ? brand : _.get(brand, 'id');
|
|
1639
|
+
if (_.isEmpty(brandId)) {
|
|
1640
|
+
return (0, rxjs_1.of)([]);
|
|
1641
|
+
}
|
|
1642
|
+
return super.getObservable(User.find({}).populate('roles'))
|
|
1643
|
+
.pipe((0, operators_1.mergeMap)(async (users) => {
|
|
1644
|
+
const activeLinks = typeof UserLink !== 'undefined'
|
|
1645
|
+
? await UserLink.find({ brandId: brandId, status: 'active' })
|
|
1646
|
+
: [];
|
|
1647
|
+
const linkedSecondaryIds = new Set(_.map(activeLinks, (link) => String(link.secondaryUserId ?? '')));
|
|
1648
|
+
return _.filter(users, (user) => {
|
|
1649
|
+
return this.hasRoleInBrand(user, String(brandId)) || linkedSecondaryIds.has(String(user.id ?? ''));
|
|
1650
|
+
});
|
|
1651
|
+
}));
|
|
1652
|
+
};
|
|
1653
|
+
getEffectiveUser = (userOrId) => {
|
|
1654
|
+
if (_.isEmpty(userOrId)) {
|
|
1655
|
+
return (0, rxjs_1.of)(null);
|
|
1656
|
+
}
|
|
1657
|
+
if (_.isString(userOrId) || _.isNumber(userOrId)) {
|
|
1658
|
+
return this.getUserWithId(String(userOrId)).pipe((0, operators_1.mergeMap)(user => {
|
|
1659
|
+
if (user != null) {
|
|
1660
|
+
return this.getEffectiveUser(user);
|
|
1661
|
+
}
|
|
1662
|
+
return this.getUserWithUsername(String(userOrId)).pipe((0, operators_1.mergeMap)(userByUsername => {
|
|
1663
|
+
if (userByUsername != null) {
|
|
1664
|
+
return this.getEffectiveUser(userByUsername);
|
|
1665
|
+
}
|
|
1666
|
+
return (0, rxjs_1.of)(null);
|
|
1667
|
+
}));
|
|
1668
|
+
}));
|
|
1669
|
+
}
|
|
1670
|
+
const userObj = userOrId;
|
|
1671
|
+
this.normalizeAccountLinkState(userObj);
|
|
1672
|
+
if (_.isEmpty(userObj.linkedPrimaryUserId)) {
|
|
1673
|
+
return (0, rxjs_1.of)(userObj);
|
|
1674
|
+
}
|
|
1675
|
+
return this.getUserWithId(String(userObj.linkedPrimaryUserId)).pipe((0, operators_1.map)(primaryUser => {
|
|
1676
|
+
if (primaryUser == null) {
|
|
1677
|
+
return userObj;
|
|
1678
|
+
}
|
|
1679
|
+
return primaryUser;
|
|
1680
|
+
}));
|
|
1681
|
+
};
|
|
1682
|
+
getLinkedAccounts = (primaryUserId) => {
|
|
1683
|
+
return (0, rxjs_1.from)((async () => {
|
|
1684
|
+
const primaryUser = await (0, rxjs_1.firstValueFrom)(this.getEffectiveUser(primaryUserId));
|
|
1685
|
+
if (_.isEmpty(primaryUser)) {
|
|
1686
|
+
throw new Error(`No such user with id:${primaryUserId}`);
|
|
1687
|
+
}
|
|
1688
|
+
const primaryUserObj = primaryUser;
|
|
1689
|
+
const links = typeof UserLink !== 'undefined'
|
|
1690
|
+
? await UserLink.find({ primaryUserId: String(primaryUserObj.id ?? ''), status: 'active' })
|
|
1691
|
+
: [];
|
|
1692
|
+
const secondaryIds = _.map(links, (link) => String(link.secondaryUserId ?? ''));
|
|
1693
|
+
const secondaryUsers = _.isEmpty(secondaryIds)
|
|
1694
|
+
? []
|
|
1695
|
+
: await User.find({ id: secondaryIds }).populate('roles');
|
|
1696
|
+
const secondaryUsersById = _.keyBy(secondaryUsers, (user) => String(user.id ?? ''));
|
|
1697
|
+
const linkedAccounts = _.compact(_.map(links, (link) => {
|
|
1698
|
+
const linkObj = link;
|
|
1699
|
+
const secondary = secondaryUsersById[String(linkObj.secondaryUserId ?? '')];
|
|
1700
|
+
if (_.isEmpty(secondary)) {
|
|
1701
|
+
return null;
|
|
1702
|
+
}
|
|
1703
|
+
this.normalizeAccountLinkState(secondary);
|
|
1704
|
+
return this.toLinkedUserSummary(secondary, linkObj.createdAt);
|
|
1705
|
+
}));
|
|
1706
|
+
return {
|
|
1707
|
+
primary: this.toLinkedUserSummary(primaryUserObj),
|
|
1708
|
+
linkedAccounts: linkedAccounts
|
|
1709
|
+
};
|
|
1710
|
+
})());
|
|
1711
|
+
};
|
|
1712
|
+
searchLinkCandidates = (query, brandId, excludeUserId) => {
|
|
1713
|
+
const queryText = _.trim(query);
|
|
1714
|
+
return (0, rxjs_1.from)((async () => {
|
|
1715
|
+
const userWhere = {
|
|
1716
|
+
accountLinkState: 'active',
|
|
1717
|
+
loginDisabled: { '!=': true }
|
|
1718
|
+
};
|
|
1719
|
+
if (!_.isEmpty(excludeUserId)) {
|
|
1720
|
+
userWhere.id = { '!=': String(excludeUserId) };
|
|
1721
|
+
}
|
|
1722
|
+
if (!_.isEmpty(queryText)) {
|
|
1723
|
+
userWhere.or = [
|
|
1724
|
+
{ username: { contains: queryText } },
|
|
1725
|
+
{ name: { contains: queryText } },
|
|
1726
|
+
{ email: { contains: queryText } }
|
|
1727
|
+
];
|
|
1728
|
+
}
|
|
1729
|
+
const users = await User.find(userWhere).populate('roles');
|
|
1730
|
+
const enrichedUsers = await this.enrichUsersWithEffectiveDisabledState(users);
|
|
1731
|
+
let primaryUserIdsWithLinkedAccounts = new Set();
|
|
1732
|
+
if (typeof UserLink !== 'undefined' && !_.isEmpty(enrichedUsers)) {
|
|
1733
|
+
const candidateUserIds = _.map(enrichedUsers, (user) => String(user.id ?? ''));
|
|
1734
|
+
const activeLinks = await UserLink.find({
|
|
1735
|
+
status: 'active',
|
|
1736
|
+
primaryUserId: candidateUserIds
|
|
1737
|
+
});
|
|
1738
|
+
primaryUserIdsWithLinkedAccounts = new Set(_.map(activeLinks, (link) => String(link.primaryUserId ?? '')));
|
|
1739
|
+
}
|
|
1740
|
+
return _.chain(enrichedUsers)
|
|
1741
|
+
.map(user => {
|
|
1742
|
+
this.normalizeAccountLinkState(user);
|
|
1743
|
+
return user;
|
|
1744
|
+
})
|
|
1745
|
+
.filter(user => {
|
|
1746
|
+
if (user.effectiveLoginDisabled === true) {
|
|
1747
|
+
return false;
|
|
1748
|
+
}
|
|
1749
|
+
if (String(user.id ?? '') === String(excludeUserId ?? '')) {
|
|
1750
|
+
return false;
|
|
1751
|
+
}
|
|
1752
|
+
if (String(user.accountLinkState ?? 'active') !== 'active') {
|
|
1753
|
+
return false;
|
|
1754
|
+
}
|
|
1755
|
+
if (primaryUserIdsWithLinkedAccounts.has(String(user.id ?? ''))) {
|
|
1756
|
+
return false;
|
|
1757
|
+
}
|
|
1758
|
+
const hasBrandRole = this.hasRoleInBrand(user, brandId);
|
|
1759
|
+
const hasNoRoles = _.isEmpty(user.roles);
|
|
1760
|
+
if (!hasBrandRole && !hasNoRoles) {
|
|
1761
|
+
return false;
|
|
1762
|
+
}
|
|
1763
|
+
return true;
|
|
1764
|
+
})
|
|
1765
|
+
.map(user => this.toLinkedUserSummary(user))
|
|
1766
|
+
.sortBy(['name', 'username'])
|
|
1767
|
+
.value();
|
|
1768
|
+
})());
|
|
1769
|
+
};
|
|
1770
|
+
linkAccounts = (primaryUserId, secondaryUserId, actor, brandId) => {
|
|
1771
|
+
return (0, rxjs_1.from)((async () => {
|
|
1772
|
+
if (_.isEmpty(primaryUserId) || _.isEmpty(secondaryUserId)) {
|
|
1773
|
+
throw new Error('Both primary and secondary users are required');
|
|
1774
|
+
}
|
|
1775
|
+
const primaryEffective = await (0, rxjs_1.firstValueFrom)(this.getEffectiveUser(primaryUserId));
|
|
1776
|
+
const secondaryUser = await (0, rxjs_1.firstValueFrom)(this.getUserWithId(secondaryUserId));
|
|
1777
|
+
if (_.isEmpty(primaryEffective) || _.isEmpty(secondaryUser)) {
|
|
1778
|
+
throw new Error('Both users must exist before linking');
|
|
1779
|
+
}
|
|
1780
|
+
const primaryUser = primaryEffective;
|
|
1781
|
+
const secondaryUserObj = secondaryUser;
|
|
1782
|
+
this.normalizeAccountLinkState(primaryUser);
|
|
1783
|
+
this.normalizeAccountLinkState(secondaryUserObj);
|
|
1784
|
+
const primaryDisabledState = await this.resolveEffectiveDisabledState(primaryUser);
|
|
1785
|
+
if (primaryDisabledState.effectiveLoginDisabled) {
|
|
1786
|
+
throw new Error('Cannot link accounts: primary user is disabled');
|
|
1787
|
+
}
|
|
1788
|
+
if (String(primaryUser.id ?? '') === String(secondaryUserObj.id ?? '')) {
|
|
1789
|
+
throw new Error('Cannot link a user to itself');
|
|
1790
|
+
}
|
|
1791
|
+
if (String(primaryUser.accountLinkState ?? 'active') === 'linked-alias') {
|
|
1792
|
+
throw new Error('Primary user cannot be a linked alias');
|
|
1793
|
+
}
|
|
1794
|
+
if (!_.isEmpty(secondaryUserObj.linkedPrimaryUserId) && String(secondaryUserObj.linkedPrimaryUserId) !== String(primaryUser.id ?? '')) {
|
|
1795
|
+
throw new Error('Secondary user is already linked to another primary account');
|
|
1796
|
+
}
|
|
1797
|
+
if (!this.hasRoleInBrand(primaryUser, brandId)) {
|
|
1798
|
+
throw new Error('Primary user must already belong to the current brand');
|
|
1799
|
+
}
|
|
1800
|
+
const secondaryBrandRoles = this.getRolesForBrand(secondaryUserObj, brandId);
|
|
1801
|
+
const secondaryForeignRoles = _.filter(secondaryUserObj.roles ?? [], (role) => {
|
|
1802
|
+
const roleObj = role;
|
|
1803
|
+
const branding = roleObj.branding;
|
|
1804
|
+
const roleBrandId = _.isObject(branding) ? String(branding.id ?? '') : String(branding ?? '');
|
|
1805
|
+
return roleBrandId !== brandId;
|
|
1806
|
+
});
|
|
1807
|
+
if (!_.isEmpty(secondaryForeignRoles)) {
|
|
1808
|
+
throw new Error('Secondary user belongs to a different brand and cannot be linked here');
|
|
1809
|
+
}
|
|
1810
|
+
const existingLink = typeof UserLink !== 'undefined'
|
|
1811
|
+
? await UserLink.findOne({ secondaryUserId: String(secondaryUserObj.id ?? ''), status: 'active' })
|
|
1812
|
+
: null;
|
|
1813
|
+
if (!_.isEmpty(existingLink)) {
|
|
1814
|
+
throw new Error('Secondary user is already linked');
|
|
1815
|
+
}
|
|
1816
|
+
const secondaryOwnLinks = typeof UserLink !== 'undefined'
|
|
1817
|
+
? await UserLink.findOne({ primaryUserId: String(secondaryUserObj.id ?? ''), status: 'active' })
|
|
1818
|
+
: null;
|
|
1819
|
+
if (!_.isEmpty(secondaryOwnLinks)) {
|
|
1820
|
+
throw new Error('Secondary user already has linked accounts');
|
|
1821
|
+
}
|
|
1822
|
+
if (typeof UserLink !== 'undefined') {
|
|
1823
|
+
await UserLink.create({
|
|
1824
|
+
primaryUserId: String(primaryUser.id ?? ''),
|
|
1825
|
+
primaryUsername: String(primaryUser.username ?? ''),
|
|
1826
|
+
secondaryUserId: String(secondaryUserObj.id ?? ''),
|
|
1827
|
+
secondaryUsername: String(secondaryUserObj.username ?? ''),
|
|
1828
|
+
brandId: brandId,
|
|
1829
|
+
status: 'active',
|
|
1830
|
+
createdBy: actor
|
|
1831
|
+
});
|
|
1832
|
+
}
|
|
1833
|
+
const primaryBrandRoleIds = new Set(_.map(this.getRolesForBrand(primaryUser, brandId), (role) => String(role.id ?? '')));
|
|
1834
|
+
const secondaryBrandRoleIds = _.map(secondaryBrandRoles, (role) => String(role.id ?? ''));
|
|
1835
|
+
const roleIdsToMerge = _.filter(secondaryBrandRoleIds, roleId => !primaryBrandRoleIds.has(roleId));
|
|
1836
|
+
if (!_.isEmpty(roleIdsToMerge)) {
|
|
1837
|
+
const addRoleQuery = User.addToCollection(String(primaryUser.id ?? ''), 'roles').members(roleIdsToMerge);
|
|
1838
|
+
await (0, rxjs_1.firstValueFrom)(this.getObservable(addRoleQuery, 'exec', 'simplecb'));
|
|
1839
|
+
}
|
|
1840
|
+
const retainedSecondaryRoleIds = _.map(_.filter(secondaryUserObj.roles ?? [], (role) => {
|
|
1841
|
+
const roleObj = role;
|
|
1842
|
+
const branding = roleObj.branding;
|
|
1843
|
+
const roleBrandId = _.isObject(branding) ? String(branding.id ?? '') : String(branding ?? '');
|
|
1844
|
+
return roleBrandId !== brandId;
|
|
1845
|
+
}), (role) => String(role.id ?? ''));
|
|
1846
|
+
const replaceRoleQuery = User.replaceCollection(String(secondaryUserObj.id ?? ''), 'roles').members(retainedSecondaryRoleIds);
|
|
1847
|
+
await (0, rxjs_1.firstValueFrom)(this.getObservable(replaceRoleQuery, 'exec', 'simplecb'));
|
|
1848
|
+
await User.update({ id: String(secondaryUserObj.id ?? '') }).set({
|
|
1849
|
+
token: '',
|
|
1850
|
+
accountLinkState: 'linked-alias',
|
|
1851
|
+
linkedPrimaryUserId: String(primaryUser.id ?? '')
|
|
1852
|
+
});
|
|
1853
|
+
const recordsRewritten = await this.rewriteLinkedRecordAuthorizations(primaryUser, secondaryUserObj, actor, brandId);
|
|
1854
|
+
await this.addUserAuditEvent({ username: actor }, 'link-accounts', {
|
|
1855
|
+
primaryUserId: primaryUser.id,
|
|
1856
|
+
primaryUsername: primaryUser.username,
|
|
1857
|
+
secondaryUserId: secondaryUserObj.id,
|
|
1858
|
+
secondaryUsername: secondaryUserObj.username,
|
|
1859
|
+
brandId: brandId,
|
|
1860
|
+
rolesMerged: roleIdsToMerge.length,
|
|
1861
|
+
recordsRewritten: recordsRewritten
|
|
1862
|
+
});
|
|
1863
|
+
const linkedAccounts = await (0, rxjs_1.firstValueFrom)(this.getLinkedAccounts(primaryUser));
|
|
1864
|
+
return {
|
|
1865
|
+
...linkedAccounts,
|
|
1866
|
+
impact: {
|
|
1867
|
+
recordsRewritten: recordsRewritten,
|
|
1868
|
+
rolesMerged: roleIdsToMerge.length
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1871
|
+
})());
|
|
1872
|
+
};
|
|
1873
|
+
setUserKey = (userid, uuid) => {
|
|
1874
|
+
const uuidHash = _.isEmpty(uuid) ? null : crypto.createHash('sha256').update(uuid).digest('base64');
|
|
1875
|
+
return this.getUserWithId(userid).pipe((0, operators_1.mergeMap)(user => {
|
|
1876
|
+
if (user) {
|
|
1877
|
+
const q = User.update({
|
|
1878
|
+
id: userid
|
|
1879
|
+
}, {
|
|
1880
|
+
token: uuidHash
|
|
1881
|
+
});
|
|
1882
|
+
return this.getObservable(q, 'exec', 'simplecb')
|
|
1883
|
+
.pipe((0, operators_1.map)((updatedUsers) => updatedUsers[0] ?? user));
|
|
1884
|
+
}
|
|
1885
|
+
else {
|
|
1886
|
+
return (0, rxjs_1.throwError)(new Error('No such user with id:' + userid));
|
|
1887
|
+
}
|
|
1888
|
+
}));
|
|
1889
|
+
};
|
|
1890
|
+
updateUserDetails = (userid, name, email, password) => {
|
|
1891
|
+
const authConfig = this.getAuthConfig(BrandingService.getDefault().name);
|
|
1892
|
+
const passwordField = authConfig.local?.passwordField ?? 'password';
|
|
1893
|
+
return this.getUserWithId(userid).pipe((0, operators_1.mergeMap)(user => {
|
|
1894
|
+
if (user) {
|
|
1895
|
+
const update = {
|
|
1896
|
+
name: name
|
|
1897
|
+
};
|
|
1898
|
+
if (!_.isEmpty(email)) {
|
|
1899
|
+
update["email"] = email;
|
|
1900
|
+
}
|
|
1901
|
+
if (!_.isEmpty(password)) {
|
|
1902
|
+
let bcrypt;
|
|
1903
|
+
try {
|
|
1904
|
+
bcrypt = require('bcrypt');
|
|
1905
|
+
}
|
|
1906
|
+
catch (_err) {
|
|
1907
|
+
bcrypt = require('bcryptjs');
|
|
1908
|
+
}
|
|
1909
|
+
const salt = bcrypt.genSaltSync(10);
|
|
1910
|
+
update[passwordField] = bcrypt.hashSync(password, salt);
|
|
1911
|
+
}
|
|
1912
|
+
const q = User.update({
|
|
1913
|
+
id: userid
|
|
1914
|
+
}, update);
|
|
1915
|
+
return this.getObservable(q, 'exec', 'simplecb');
|
|
1916
|
+
}
|
|
1917
|
+
else {
|
|
1918
|
+
return (0, rxjs_1.throwError)(new Error('No such user with id:' + userid));
|
|
1919
|
+
}
|
|
1920
|
+
}));
|
|
1921
|
+
};
|
|
1922
|
+
updateUserRoles = (userid, newRoleIds) => {
|
|
1923
|
+
return this.getUserWithId(userid).pipe((0, operators_1.mergeMap)(user => {
|
|
1924
|
+
if (user) {
|
|
1925
|
+
if (_.isEmpty(newRoleIds) || newRoleIds.length == 0) {
|
|
1926
|
+
return (0, rxjs_1.throwError)(new Error('Please assign at least one role'));
|
|
1927
|
+
}
|
|
1928
|
+
// START Sails 1.0 upgrade
|
|
1929
|
+
const q = User.replaceCollection(user.id, 'roles').members(newRoleIds);
|
|
1930
|
+
// END Sails 1.0 upgrade
|
|
1931
|
+
return this.getObservable(q, 'exec', 'simplecb');
|
|
1932
|
+
}
|
|
1933
|
+
else {
|
|
1934
|
+
return (0, rxjs_1.throwError)(new Error('No such user with id:' + userid));
|
|
1935
|
+
}
|
|
1936
|
+
}));
|
|
1937
|
+
};
|
|
1938
|
+
updateUserAfterLogin(user, done) {
|
|
1939
|
+
const userObj = user;
|
|
1940
|
+
User.update({
|
|
1941
|
+
username: userObj.username
|
|
1942
|
+
}).set(userObj).exec(function (err, user) {
|
|
1943
|
+
if (err) {
|
|
1944
|
+
sails.log.error("Error updating user:");
|
|
1945
|
+
sails.log.error(err);
|
|
1946
|
+
return done(err, false);
|
|
1947
|
+
}
|
|
1948
|
+
if (_.isEmpty(user)) {
|
|
1949
|
+
sails.log.error("No user found");
|
|
1950
|
+
return done("No user found", false);
|
|
1951
|
+
}
|
|
1952
|
+
sails.log.verbose("Done, returning updated user:");
|
|
1953
|
+
sails.log.verbose(user);
|
|
1954
|
+
const updatedUsers = user;
|
|
1955
|
+
return done(null, updatedUsers[0]);
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
hasRole(user, targetRole) {
|
|
1959
|
+
const userObj = user;
|
|
1960
|
+
const targetRoleObj = targetRole;
|
|
1961
|
+
return _.find(userObj.roles, (role) => {
|
|
1962
|
+
return role.id == targetRoleObj.id;
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
findUsersWithName(name, brandId, source = null) {
|
|
1966
|
+
const query = {
|
|
1967
|
+
name: {
|
|
1968
|
+
'contains': name
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1971
|
+
// S2TEST-21
|
|
1972
|
+
return this.findUsersWithQuery(query, brandId, source);
|
|
1973
|
+
}
|
|
1974
|
+
// S2TEST-21
|
|
1975
|
+
findUsersWithEmail(email, brandId, source = null) {
|
|
1976
|
+
const query = {
|
|
1977
|
+
email: {
|
|
1978
|
+
'contains': email
|
|
1979
|
+
}
|
|
1980
|
+
};
|
|
1981
|
+
return this.findUsersWithQuery(query, brandId, source);
|
|
1982
|
+
}
|
|
1983
|
+
// S2TEST-21
|
|
1984
|
+
findUsersWithQuery(query, brandId, source = null) {
|
|
1985
|
+
const queryObj = (query ?? {});
|
|
1986
|
+
if (!_.isEmpty(source) && !_.isUndefined(source) && !_.isNull(source)) {
|
|
1987
|
+
queryObj['type'] = source;
|
|
1988
|
+
}
|
|
1989
|
+
return this.getObservable(User.find(queryObj).populate('roles'))
|
|
1990
|
+
.pipe((0, operators_1.mergeMap)(users => {
|
|
1991
|
+
if (brandId) {
|
|
1992
|
+
_.remove(users, (user) => {
|
|
1993
|
+
const userObj = user;
|
|
1994
|
+
const isInBrand = _.find(userObj.roles, (role) => {
|
|
1995
|
+
return role.branding == brandId;
|
|
1996
|
+
});
|
|
1997
|
+
return !isInBrand;
|
|
1998
|
+
});
|
|
1999
|
+
}
|
|
2000
|
+
return (0, rxjs_1.of)(users);
|
|
2001
|
+
}));
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
*
|
|
2005
|
+
* Find all records that the user is intended to have access to and assign actual access using their userId.
|
|
2006
|
+
* This is used as users or services may want to provide access for a user to a record but due to single sign-on solutions,
|
|
2007
|
+
* we're not able to reliably determine the username before they login to the system for the first time.
|
|
2008
|
+
*
|
|
2009
|
+
**/
|
|
2010
|
+
findAndAssignAccessToRecords(pendingValue, userid) {
|
|
2011
|
+
this.getEffectiveUser(userid).subscribe((effectiveUser) => {
|
|
2012
|
+
const effectiveUsername = _.get(effectiveUser, 'username', userid);
|
|
2013
|
+
Record.find({
|
|
2014
|
+
'or': [{
|
|
2015
|
+
'authorization.editPending': pendingValue
|
|
2016
|
+
}, {
|
|
2017
|
+
'authorization.viewPending': pendingValue
|
|
2018
|
+
}]
|
|
2019
|
+
}).meta({
|
|
2020
|
+
enableExperimentalDeepTargets: true
|
|
2021
|
+
}).then((records) => {
|
|
2022
|
+
const recordsArr = records;
|
|
2023
|
+
if (_.isEmpty(recordsArr)) {
|
|
2024
|
+
sails.log.verbose(`UsersService::findAndAssignAccessToRecords() -> No pending records: ${pendingValue}`);
|
|
2025
|
+
return;
|
|
2026
|
+
}
|
|
2027
|
+
sails.log.verbose(`UsersService::findAndAssignAccessToRecords() -> Found ${recordsArr.length} records to assign permissions`);
|
|
2028
|
+
for (const record of recordsArr) {
|
|
2029
|
+
const recordObj = record;
|
|
2030
|
+
RecordsService.provideUserAccessAndRemovePendingAccess(recordObj.redboxOid, effectiveUsername, pendingValue);
|
|
2031
|
+
}
|
|
2032
|
+
}).catch((error) => {
|
|
2033
|
+
sails.log.warn(`Failed to assign access for user: ${pendingValue}`);
|
|
2034
|
+
sails.log.warn(error);
|
|
2035
|
+
});
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
/**
|
|
2039
|
+
* Check whether an email is authorized.
|
|
2040
|
+
* @param email The email to check.
|
|
2041
|
+
* @param branding The branding name.
|
|
2042
|
+
* @param authType The auth type ('aaf' or 'oidc').
|
|
2043
|
+
* @returns True if email is authorized or authorization check is disabled, otherwise false if email is not allowed.
|
|
2044
|
+
* @private
|
|
2045
|
+
*/
|
|
2046
|
+
checkAuthorizedEmail(email, branding, authType) {
|
|
2047
|
+
// Must pass email.
|
|
2048
|
+
if (!email) {
|
|
2049
|
+
sails.log.error("No email address provided.");
|
|
2050
|
+
return false;
|
|
2051
|
+
}
|
|
2052
|
+
// Assess email address.
|
|
2053
|
+
const emailParts = email.includes('@') ? email.split('@') : [];
|
|
2054
|
+
if (emailParts.length !== 2) {
|
|
2055
|
+
sails.log.error(`Unexpected email format: ${email}.`);
|
|
2056
|
+
return false;
|
|
2057
|
+
}
|
|
2058
|
+
// Get the configuration data.
|
|
2059
|
+
const brandingAwareData = sails.config.brandingAware(branding);
|
|
2060
|
+
const authorizedDomainsEmails = _.get(brandingAwareData, 'authorizedDomainsEmails', {});
|
|
2061
|
+
if (authorizedDomainsEmails.enabled?.toString() !== 'true') {
|
|
2062
|
+
sails.log.warn("Authorized email configuration is disabled.");
|
|
2063
|
+
return true;
|
|
2064
|
+
}
|
|
2065
|
+
const domains = [];
|
|
2066
|
+
const emails = [];
|
|
2067
|
+
if (authType === 'aaf') {
|
|
2068
|
+
domains.push(...(authorizedDomainsEmails.domainsAaf || []));
|
|
2069
|
+
emails.push(...(authorizedDomainsEmails.emailsAaf || []));
|
|
2070
|
+
}
|
|
2071
|
+
else if (authType === 'oidc') {
|
|
2072
|
+
domains.push(...(authorizedDomainsEmails.domainsOidc || []));
|
|
2073
|
+
emails.push(...(authorizedDomainsEmails.emailsOidc || []));
|
|
2074
|
+
}
|
|
2075
|
+
else {
|
|
2076
|
+
sails.log.error(`Authorized domains and emails config problem: any auth type '${authType}'`);
|
|
2077
|
+
return false;
|
|
2078
|
+
}
|
|
2079
|
+
// Check configuration.
|
|
2080
|
+
if (domains.length === 0) {
|
|
2081
|
+
sails.log.verbose(`No authorized email domains configured for ${authType}.`);
|
|
2082
|
+
}
|
|
2083
|
+
if (emails.length === 0) {
|
|
2084
|
+
sails.log.verbose(`No authorized email exceptions configured for ${authType}.`);
|
|
2085
|
+
}
|
|
2086
|
+
if (domains.length === 0 && emails.length === 0) {
|
|
2087
|
+
return true;
|
|
2088
|
+
}
|
|
2089
|
+
// Assess domains and exceptions.
|
|
2090
|
+
const emailDomain = emailParts[1];
|
|
2091
|
+
const isAllowedDomain = domains.indexOf(emailDomain) !== -1;
|
|
2092
|
+
if (isAllowedDomain) {
|
|
2093
|
+
sails.log.verbose(`Authorized email domain: ${emailDomain}`);
|
|
2094
|
+
return true;
|
|
2095
|
+
}
|
|
2096
|
+
const isAllowedException = emails.indexOf(email) !== -1;
|
|
2097
|
+
if (isAllowedException) {
|
|
2098
|
+
sails.log.verbose(`Authorized email exception: ${email}`);
|
|
2099
|
+
return true;
|
|
2100
|
+
}
|
|
2101
|
+
// Checks did not pass, so email is not allowed.
|
|
2102
|
+
sails.log.error(`Email is not authorized to login using ${authType}: ${email}.`);
|
|
2103
|
+
return false;
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
Services.Users = Users;
|
|
2107
|
+
})(Services || (exports.Services = Services = {}));
|
|
2108
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVXNlcnNTZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL1VzZXJzU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEZBQTBGO0FBQzFGLEVBQUU7QUFDRiw2QkFBNkI7QUFDN0IsMEJBQTBCO0FBQzFCLEVBQUU7QUFDRix1RUFBdUU7QUFDdkUsdUVBQXVFO0FBQ3ZFLG9FQUFvRTtBQUNwRSxzQ0FBc0M7QUFDdEMsRUFBRTtBQUNGLGtFQUFrRTtBQUNsRSxpRUFBaUU7QUFDakUsZ0VBQWdFO0FBQ2hFLCtDQUErQztBQUMvQyxFQUFFO0FBQ0YsMEVBQTBFO0FBQzFFLDBFQUEwRTtBQUMxRSw4REFBOEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUU5RCwrQkFBd0U7QUFDeEUsOENBQWdFO0FBRWhFLCtCQUVjO0FBUWQsZ0RBQXNEO0FBRXRELCtDQUFpQztBQUtqQyxJQUFpQixRQUFRLENBcTBFeEI7QUFyMEVELFdBQWlCLFFBQVE7SUFHdkIsTUFBTSw0QkFBNEIsR0FBRywrQkFBK0IsQ0FBQztJQUNyRSxNQUFNLDBCQUEwQixHQUFHLEtBQUssQ0FBQztJQThHekM7Ozs7OztPQU1HO0lBQ0gsTUFBYSxLQUFNLFNBQVEsc0JBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTztRQUUzQixnQkFBZ0IsR0FBYTtZQUM5QyxXQUFXO1lBQ1gsaUJBQWlCO1lBQ2pCLG1CQUFtQjtZQUNuQixlQUFlO1lBQ2YscUJBQXFCO1lBQ3JCLGNBQWM7WUFDZCxZQUFZO1lBQ1osU0FBUztZQUNULG1CQUFtQjtZQUNuQixvQkFBb0I7WUFDcEIsb0JBQW9CO1lBQ3BCLDhCQUE4QjtZQUM5QixVQUFVO1lBQ1Ysa0JBQWtCO1lBQ2xCLGtCQUFrQjtZQUNsQixtQkFBbUI7WUFDbkIsc0JBQXNCO1lBQ3RCLGNBQWM7WUFDZCxtQkFBbUI7WUFDbkIsc0JBQXNCO1lBQ3RCLHVDQUF1QztZQUN2QyxhQUFh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
|