From fb1127e2784706e6dab8e35692a067443d97fcaf Mon Sep 17 00:00:00 2001 From: holycrab13 Date: Fri, 31 Jan 2025 14:33:52 +0100 Subject: [PATCH] write/indexing fixes for group & artifact --- .vscode/settings.json | 3 + public/dist/main.js | 4 +- .../js/page-controller/profile-controller.js | 10 +- public/js/utils/app-json-formatter.js | 14 +- public/js/utils/databus-utils.js | 13 - public/js/utils/jsonld-utils.js | 23 +- public/templates/404.ejs | 2 +- public/templates/artifact.ejs | 3 +- server/app/api/lib/account-writer.js | 282 +----------------- server/app/api/lib/artifact-writer.js | 13 +- server/app/api/lib/databus-resource.js | 102 ------- server/app/api/lib/databus-tractate-suite.js | 7 +- server/app/api/lib/dataid-autocomplete.js | 53 ---- server/app/api/lib/group-writer.js | 12 +- server/app/api/lib/gstore-resource.js | 3 +- server/app/api/lib/publish-artifact.js | 111 ------- server/app/api/lib/publish-group.js | 111 ------- server/app/api/lib/resource-writer.js | 133 +++++---- server/app/api/routes/artifact.js | 30 +- server/app/api/routes/general.js | 55 ++-- server/app/api/routes/group.js | 27 +- server/app/app.js | 47 +-- server/app/common/get-jsonld.js | 7 +- server/app/common/request-rdf.js | 96 +++--- server/app/common/utils/api-error.js | 4 +- server/app/common/utils/jsonld-loader.js | 52 ++++ server/app/common/utils/server-utils.js | 11 +- server/config.json | 2 +- server/init.js | 44 ++- server/www | 12 +- 30 files changed, 343 insertions(+), 943 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 server/app/api/lib/databus-resource.js delete mode 100644 server/app/api/lib/publish-artifact.js delete mode 100644 server/app/api/lib/publish-group.js create mode 100644 server/app/common/utils/jsonld-loader.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..53d1379c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.detectIndentation": true +} \ No newline at end of file diff --git a/public/dist/main.js b/public/dist/main.js index 223e407a..7ca74b6d 100644 --- a/public/dist/main.js +++ b/public/dist/main.js @@ -385,7 +385,7 @@ eval("var DatabusWebappUtils = __webpack_require__(/*! ../utils/databus-webapp-u \**************************************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -eval("const DatabusUtils = __webpack_require__(/*! ../utils/databus-utils */ \"./js/utils/databus-utils.js\");\nconst DatabusWebappUtils = __webpack_require__(/*! ../utils/databus-webapp-utils */ \"./js/utils/databus-webapp-utils.js\");\nconst DatabusAlert = __webpack_require__(/*! ../components/databus-alert/databus-alert */ \"./js/components/databus-alert/databus-alert.js\");\nconst SearchAdapter = __webpack_require__(/*! ../search/search-adapter */ \"./js/search/search-adapter.js\");\nconst DatabusMessages = __webpack_require__(/*! ../utils/databus-messages */ \"./js/utils/databus-messages.js\");\nconst DatabusConstants = __webpack_require__(/*! ../utils/databus-constants */ \"./js/utils/databus-constants.js\");\nconst AppJsonFormatter = __webpack_require__(/*! ../utils/app-json-formatter */ \"./js/utils/app-json-formatter.js\");\n\nfunction ProfileController($scope, $http) {\n\n $scope.profileData = data.profile;\n $scope.auth = data.auth;\n $scope.preferredDatabusUsername = \"\";\n $scope.apiKeys = data.auth.info.apiKeys;\n $scope.createApiKeyName = \"\"\n $scope.createAccountError = \"\";\n $scope.createApiKeyError = \"\";\n $scope.addWebIdUri = \"\";\n $scope.grantAccessUri = \"\";\n $scope.adapters = SearchAdapter.list;\n $scope.utils = new DatabusWebappUtils($scope);\n\n $scope.personUri = `${DATABUS_RESOURCE_BASE_URL}/${$scope.auth.info.accountName}${DatabusConstants.WEBID_THIS}`;\n\n $scope.putProfile = function (accountName) {\n\n var accountJsonLd = AppJsonFormatter.createAccountData(DATABUS_RESOURCE_BASE_URL, \n accountName,\n accountName, \n null, \n null);\n\n $http.post(`/api/register`, accountJsonLd).then(function (result) {\n window.location.reload(true);\n }, function (err) {\n console.log(err);\n $scope.createAccountError = err.data;\n });\n }\n\n\n if ($scope.profileData == undefined) {\n\n $scope.createProfile = function () {\n if (!$scope.auth.authenticated) {\n return;\n }\n\n var accountName = $scope.preferredDatabusUsername;\n\n if (accountName == undefined || !DatabusUtils.isValidAccountName(accountName)) {\n $scope.createAccountError = \"Enter a valid account name.\"\n $scope.showAccountNameHints = true;\n return;\n }\n\n $scope.showAccountNameHints = false;\n $scope.putProfile(accountName);\n }\n\n return;\n }\n\n $scope.removeApiKey = function (key) {\n\n $http.post(`/api/account/api-key/delete?name=${key.keyname}`).then(function (result) {\n $scope.apiKeys = $scope.apiKeys.filter(function (k) {\n return k.keyname != key.keyname;\n });\n\n }, function (err) {\n console.log(err);\n $scope.createApiKeyError = err.data;\n });\n }\n\n $scope.onCreateApiKeyNameChanged = function () {\n var hasError = !DatabusUtils.isValidResourceLabel($scope.createApiKeyName, 3, 20);\n $scope.createApiKeyError = hasError ? \" API key name must have between 3 and 20 characters and match [A-Za-z0-9\\\\s_()\\\\.\\\\,\\\\-]*\" : \"\";\n }\n\n $scope.addApiKey = function () {\n\n $http.post(`/api/account/api-key/create?name=${encodeURIComponent($scope.createApiKeyName)}`).then(function (result) {\n\n if (result.data != null) {\n $scope.apiKeys.push(result.data);\n }\n\n DatabusAlert.alert($scope, true, DatabusMessages.ACCOUNT_API_KEY_CREATED);\n\n }, function (err) {\n console.log(err);\n $scope.createApiKeyError = err.data;\n });\n\n }\n\n $scope.removeSearchExtension = function(uri) {\n $http.post(`/api/account/mods/search-extensions/remove?uri=${encodeURIComponent(uri)}`)\n .then(function (result) {\n console.log(result);\n DatabusAlert.alert($scope, true, result.data);\n\n $scope.profileData.searchExtensions = $scope.profileData.searchExtensions.filter(function (e) {\n return e.endpointUri != uri;\n });\n\n }, function (err) {\n console.log(err);\n DatabusAlert.alert($scope, false, err.data);\n });\n }\n\n $scope.addSearchExtension = function () {\n var uri = $scope.modsSettings.searchExtensionURI;\n var adapter = $scope.modsSettings.searchExtensionAdapter.name;\n\n $http.post(`/api/account/mods/search-extensions/add?uri=${encodeURIComponent(uri)}&adapter=${adapter}`)\n .then(function (result) {\n console.log(result);\n DatabusAlert.alert($scope, true, result.data);\n $scope.profileData.searchExtensions.push({\n endpointUri: uri,\n adapter: adapter\n });\n }, function (err) {\n console.log(err);\n DatabusAlert.alert($scope, false, err.data);\n });\n }\n\n $scope.grantAccess = function () {\n $http.post(`/api/account/access/grant?uri=${encodeURIComponent($scope.grantAccessUri)}`).then(function (result) {\n $scope.profileData.authorizedAccounts.push($scope.grantAccessUri);\n }, function (err) {\n console.log(err);\n $scope.grantAccessError = err.data;\n });\n }\n\n $scope.revokeAccess = function (uri) {\n $http.post(`/api/account/access/revoke?uri=${encodeURIComponent(uri)}`).then(function (result) {\n $scope.profileData.authorizedAccounts = $scope.profileData.webIds.filter(function (value, index, arr) {\n return value != uri;\n });\n }, function (err) {\n console.log(err);\n $scope.grantAccessError = err.data;\n });\n }\n\n $scope.connectWebid = function () {\n\n $http.post(`/api/account/webid/add?uri=${encodeURIComponent($scope.addWebIdUri)}`).then(function (result) {\n $scope.profileData.webIds.push($scope.addWebIdUri);\n DatabusAlert.alert($scope, true, DatabusMessages.ACCOUNT_WEBID_LINKED);\n\n }, function (err) {\n console.log(err);\n $scope.addWebIdError = err.data;\n });\n }\n\n $scope.removeWebId = function (webIdToRemove) {\n\n $http.post(`/api/account/webid/remove?uri=${encodeURIComponent(webIdToRemove)}`).then(function (result) {\n\n $scope.profileData.webIds = $scope.profileData.webIds.filter(function (value, index, arr) {\n return value != webIdToRemove;\n });\n\n }, function (err) {\n console.log(err);\n $scope.addWebIdError = err.data;\n });\n }\n\n\n $scope.saveProfile = async function () {\n\n if (!$scope.auth.authenticated) {\n return;\n }\n\n var accountJsonLd = AppJsonFormatter.createAccountData(DATABUS_RESOURCE_BASE_URL, \n $scope.auth.info.accountName,\n $scope.editData.label, \n $scope.editData.about, \n $scope.editData.imageUrl);\n\n $http.post(`/api/register`, accountJsonLd).then(function (result) {\n DatabusAlert.alert($scope, true, DatabusMessages.ACCOUT_PROFILE_SAVED);\n }, function (err) {\n console.log(err);\n });\n }\n\n // We have profile data in $scope.profileData!\n\n if (!$scope.profileData.isOwn) {\n return;\n }\n\n $scope.modsSettings = {}\n $scope.modsSettings.searchExtensionURI = \"\";\n $scope.modsSettings.searchExtensionAdapter = $scope.adapters[0];\n\n\n $scope.editData = DatabusUtils.createCleanCopy($scope.profileData);\n\n $scope.resetEdits = function () {\n $scope.editData = DatabusUtils.createCleanCopy($scope.profileData);\n }\n\n}\n\nmodule.exports = ProfileController;\n\n//# sourceURL=webpack://databus-webapp/./js/page-controller/profile-controller.js?"); +eval("const DatabusUtils = __webpack_require__(/*! ../utils/databus-utils */ \"./js/utils/databus-utils.js\");\nconst DatabusWebappUtils = __webpack_require__(/*! ../utils/databus-webapp-utils */ \"./js/utils/databus-webapp-utils.js\");\nconst DatabusAlert = __webpack_require__(/*! ../components/databus-alert/databus-alert */ \"./js/components/databus-alert/databus-alert.js\");\nconst SearchAdapter = __webpack_require__(/*! ../search/search-adapter */ \"./js/search/search-adapter.js\");\nconst DatabusMessages = __webpack_require__(/*! ../utils/databus-messages */ \"./js/utils/databus-messages.js\");\nconst DatabusConstants = __webpack_require__(/*! ../utils/databus-constants */ \"./js/utils/databus-constants.js\");\nconst AppJsonFormatter = __webpack_require__(/*! ../utils/app-json-formatter */ \"./js/utils/app-json-formatter.js\");\n\nfunction ProfileController($scope, $http) {\n\n $scope.profileData = data.profile;\n $scope.auth = data.auth;\n $scope.preferredDatabusUsername = \"\";\n $scope.apiKeys = data.auth.info.apiKeys;\n $scope.createApiKeyName = \"\"\n $scope.createAccountError = \"\";\n $scope.createApiKeyError = \"\";\n $scope.addWebIdUri = \"\";\n $scope.grantAccessUri = \"\";\n $scope.adapters = SearchAdapter.list;\n $scope.utils = new DatabusWebappUtils($scope);\n\n $scope.personUri = `${DATABUS_RESOURCE_BASE_URL}/${$scope.auth.info.accountName}${DatabusConstants.WEBID_THIS}`;\n\n $scope.putProfile = function (accountName) {\n\n var accountUri = `${DATABUS_RESOURCE_BASE_URL}/${accountName}`;\n var accountJsonLd = AppJsonFormatter.createAccountData(\n accountUri,\n accountName, \n null, \n null);\n\n $http.post(`/api/register`, accountJsonLd).then(function (result) {\n window.location.reload(true);\n }, function (err) {\n console.log(err);\n $scope.createAccountError = err.data;\n });\n }\n\n\n if ($scope.profileData == undefined) {\n\n $scope.createProfile = function () {\n if (!$scope.auth.authenticated) {\n return;\n }\n\n var accountName = $scope.preferredDatabusUsername;\n\n if (accountName == undefined || !DatabusUtils.isValidAccountName(accountName)) {\n $scope.createAccountError = \"Enter a valid account name.\"\n $scope.showAccountNameHints = true;\n return;\n }\n\n $scope.showAccountNameHints = false;\n $scope.putProfile(accountName);\n }\n\n return;\n }\n\n $scope.removeApiKey = function (key) {\n\n $http.post(`/api/account/api-key/delete?name=${key.keyname}`).then(function (result) {\n $scope.apiKeys = $scope.apiKeys.filter(function (k) {\n return k.keyname != key.keyname;\n });\n\n }, function (err) {\n console.log(err);\n $scope.createApiKeyError = err.data;\n });\n }\n\n $scope.onCreateApiKeyNameChanged = function () {\n var hasError = !DatabusUtils.isValidResourceLabel($scope.createApiKeyName, 3, 20);\n $scope.createApiKeyError = hasError ? \" API key name must have between 3 and 20 characters and match [A-Za-z0-9\\\\s_()\\\\.\\\\,\\\\-]*\" : \"\";\n }\n\n $scope.addApiKey = function () {\n\n $http.post(`/api/account/api-key/create?name=${encodeURIComponent($scope.createApiKeyName)}`).then(function (result) {\n\n if (result.data != null) {\n $scope.apiKeys.push(result.data);\n }\n\n DatabusAlert.alert($scope, true, DatabusMessages.ACCOUNT_API_KEY_CREATED);\n\n }, function (err) {\n console.log(err);\n $scope.createApiKeyError = err.data;\n });\n\n }\n\n $scope.removeSearchExtension = function(uri) {\n $http.post(`/api/account/mods/search-extensions/remove?uri=${encodeURIComponent(uri)}`)\n .then(function (result) {\n console.log(result);\n DatabusAlert.alert($scope, true, result.data);\n\n $scope.profileData.searchExtensions = $scope.profileData.searchExtensions.filter(function (e) {\n return e.endpointUri != uri;\n });\n\n }, function (err) {\n console.log(err);\n DatabusAlert.alert($scope, false, err.data);\n });\n }\n\n $scope.addSearchExtension = function () {\n var uri = $scope.modsSettings.searchExtensionURI;\n var adapter = $scope.modsSettings.searchExtensionAdapter.name;\n\n $http.post(`/api/account/mods/search-extensions/add?uri=${encodeURIComponent(uri)}&adapter=${adapter}`)\n .then(function (result) {\n console.log(result);\n DatabusAlert.alert($scope, true, result.data);\n $scope.profileData.searchExtensions.push({\n endpointUri: uri,\n adapter: adapter\n });\n }, function (err) {\n console.log(err);\n DatabusAlert.alert($scope, false, err.data);\n });\n }\n\n $scope.grantAccess = function () {\n $http.post(`/api/account/access/grant?uri=${encodeURIComponent($scope.grantAccessUri)}`).then(function (result) {\n $scope.profileData.authorizedAccounts.push($scope.grantAccessUri);\n }, function (err) {\n console.log(err);\n $scope.grantAccessError = err.data;\n });\n }\n\n $scope.revokeAccess = function (uri) {\n $http.post(`/api/account/access/revoke?uri=${encodeURIComponent(uri)}`).then(function (result) {\n $scope.profileData.authorizedAccounts = $scope.profileData.webIds.filter(function (value, index, arr) {\n return value != uri;\n });\n }, function (err) {\n console.log(err);\n $scope.grantAccessError = err.data;\n });\n }\n\n $scope.connectWebid = function () {\n\n $http.post(`/api/account/webid/add?uri=${encodeURIComponent($scope.addWebIdUri)}`).then(function (result) {\n $scope.profileData.webIds.push($scope.addWebIdUri);\n DatabusAlert.alert($scope, true, DatabusMessages.ACCOUNT_WEBID_LINKED);\n\n }, function (err) {\n console.log(err);\n $scope.addWebIdError = err.data;\n });\n }\n\n $scope.removeWebId = function (webIdToRemove) {\n\n $http.post(`/api/account/webid/remove?uri=${encodeURIComponent(webIdToRemove)}`).then(function (result) {\n\n $scope.profileData.webIds = $scope.profileData.webIds.filter(function (value, index, arr) {\n return value != webIdToRemove;\n });\n\n }, function (err) {\n console.log(err);\n $scope.addWebIdError = err.data;\n });\n }\n\n\n $scope.saveProfile = async function () {\n\n if (!$scope.auth.authenticated) {\n return;\n }\n\n var accountUri = `${DATABUS_RESOURCE_BASE_URL}/${$scope.auth.info.accountName}`;\n var accountJsonLd = AppJsonFormatter.createAccountData(\n accountUri,\n $scope.editData.label, \n $scope.editData.about, \n $scope.editData.imageUrl);\n\n $http.post(`/api/register`, accountJsonLd).then(function (result) {\n DatabusAlert.alert($scope, true, DatabusMessages.ACCOUT_PROFILE_SAVED);\n }, function (err) {\n console.log(err);\n });\n }\n\n // We have profile data in $scope.profileData!\n\n if (!$scope.profileData.isOwn) {\n return;\n }\n\n $scope.modsSettings = {}\n $scope.modsSettings.searchExtensionURI = \"\";\n $scope.modsSettings.searchExtensionAdapter = $scope.adapters[0];\n\n\n $scope.editData = DatabusUtils.createCleanCopy($scope.profileData);\n\n $scope.resetEdits = function () {\n $scope.editData = DatabusUtils.createCleanCopy($scope.profileData);\n }\n\n}\n\nmodule.exports = ProfileController;\n\n//# sourceURL=webpack://databus-webapp/./js/page-controller/profile-controller.js?"); /***/ }), @@ -505,7 +505,7 @@ eval("const AppJsonFormatter = __webpack_require__(/*! ../utils/app-json-formatt \****************************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -eval("const DatabusConstants = __webpack_require__(/*! ./databus-constants */ \"./js/utils/databus-constants.js\");\nconst DatabusUris = __webpack_require__(/*! ./databus-uris */ \"./js/utils/databus-uris.js\");\nconst DatabusUtils = __webpack_require__(/*! ./databus-utils */ \"./js/utils/databus-utils.js\");\nconst JsonldUtils = __webpack_require__(/*! ./jsonld-utils */ \"./js/utils/jsonld-utils.js\");\n\n/**\n * Translates expanded jsonld into web-app compatible json\n */\nclass AppJsonFormatter {\n\n static createAccountData(resourceBaseUrl, accountName, accountLabel, accountStatus, accountImage) {\n\n var accountUri = `${resourceBaseUrl}/${accountName}`;\n var personUri = `${resourceBaseUrl}/${accountName}${DatabusConstants.WEBID_THIS}`;\n\n var accountJsonLd = {};\n\n var accountGraph = {};\n accountGraph[DatabusUris.JSONLD_ID] = accountUri;\n accountGraph[DatabusUris.JSONLD_TYPE] = DatabusUris.DATABUS_ACCOUNT;\n\n var personGraph = {};\n personGraph[DatabusUris.JSONLD_ID] = personUri;\n personGraph[DatabusUris.JSONLD_TYPE] = DatabusUris.FOAF_PERSON;\n personGraph[DatabusUris.FOAF_NAME] = accountLabel;\n personGraph[DatabusUris.FOAF_ACCOUNT] = JsonldUtils.refTo(accountUri);\n\n if (accountStatus != null) {\n personGraph[DatabusUris.FOAF_STATUS] = accountStatus;\n }\n\n if (accountImage != null) {\n personGraph[DatabusUris.FOAF_IMG] = JsonldUtils.refTo(accountImage);\n }\n\n\n accountJsonLd[DatabusUris.JSONLD_GRAPH] = [\n accountGraph,\n personGraph\n ];\n\n return accountJsonLd;\n }\n\n static formatGroupData(graphs) {\n var result = {};\n\n // ?uri ?title ?abstract ?description\n var groupGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.DATABUS_GROUP);\n\n result.uri = groupGraph[DatabusUris.JSONLD_ID];\n result.title = JsonldUtils.getProperty(groupGraph, DatabusUris.DCT_TITLE);\n result.abstract = JsonldUtils.getProperty(groupGraph, DatabusUris.DCT_ABSTRACT);\n result.description = JsonldUtils.getProperty(groupGraph, DatabusUris.DCT_DESCRIPTION);\n result.name = DatabusUtils.uriToResourceName(result.uri);\n return result;\n }\n\n static formatArtifactData(graphs) {\n var result = {};\n // ?uri ?title ?abstract ?description\n var artifactGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.DATABUS_ARTIFACT);\n\n result.uri = artifactGraph[DatabusUris.JSONLD_ID];\n result.title = JsonldUtils.getProperty(artifactGraph, DatabusUris.DCT_TITLE);\n result.abstract = JsonldUtils.getProperty(artifactGraph, DatabusUris.DCT_ABSTRACT);\n result.description = JsonldUtils.getProperty(artifactGraph, DatabusUris.DCT_DESCRIPTION);\n result.name = DatabusUtils.uriToResourceName(result.uri);\n return result;\n\n\n }\n\n static formatAccountData(graphs) {\n var result = {};\n\n var profileGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.FOAF_PERSONAL_PROFILE_DOCUMENT);\n var personGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.FOAF_PERSON);\n\n result.uri = profileGraph[DatabusUris.JSONLD_ID];\n result.accountName = DatabusUtils.uriToResourceName(result.uri);\n result.label = JsonldUtils.getProperty(personGraph, DatabusUris.FOAF_NAME);\n result.webIds = [];\n result.searchExtensions = [];\n\n var extensionGraphs = JsonldUtils.getTypedGraphs(graphs, DatabusUris.DATABUS_SEARCH_EXTENSION);\n\n for (var extensionGraph of extensionGraphs) {\n result.searchExtensions.push({\n endpointUri: JsonldUtils.getProperty(extensionGraph, DatabusUris.DATABUS_SEARCH_EXTENSION_ENDPOINT),\n adapterName: JsonldUtils.getProperty(extensionGraph, DatabusUris.DATABUS_SEARCH_EXTENSION_ADAPTER),\n });\n }\n\n for (var graph of graphs) {\n\n if (graph[DatabusUris.JSONLD_ID] == personGraph[DatabusUris.JSONLD_ID]) {\n continue;\n }\n\n if (graph[DatabusUris.FOAF_ACCOUNT] != undefined) {\n result.webIds.push(graph[DatabusUris.JSONLD_ID]);\n }\n }\n\n return result;\n }\n\n static formatVersionData(versionGraph) {\n\n\n var version = {};\n version.uri = versionGraph[DatabusUris.JSONLD_ID];\n version.title = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_TITLE);\n version.abstract = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_ABSTRACT);\n version.description = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_DESCRIPTION);\n version.artifact = JsonldUtils.getProperty(versionGraph, DatabusUris.DATABUS_ARTIFACT_PROPERTY);\n version.license = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_LICENSE);\n version.attribution = JsonldUtils.getProperty(versionGraph, DatabusUris.DATABUS_ATTRIBUTION);\n version.wasDerivedFrom = JsonldUtils.getProperty(versionGraph, DatabusUris.PROV_WAS_DERIVED_FROM);\n version.issued = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_ISSUED);\n version.name = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_HAS_VERSION);\n\n return version;\n }\n\n static formatCollectionData(graphs) {\n var collectionGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.DATABUS_COLLECTION);\n\n var result = {};\n\n result.uri = collectionGraph[DatabusUris.JSONLD_ID];\n result.title = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_TITLE);\n result.abstract = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_ABSTRACT);\n result.description = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_DESCRIPTION);\n result.issued = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_ISSUED);\n result.publisher = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_PUBLISHER);\n\n var content = JsonldUtils.getProperty(collectionGraph, DatabusUris.DATABUS_COLLECTION_CONTENT)\n result.content = DatabusUtils.tryParseJson(unescape(content));\n\n return result;\n }\n}\n\nmodule.exports = AppJsonFormatter;\n\n\n//# sourceURL=webpack://databus-webapp/./js/utils/app-json-formatter.js?"); +eval("const DatabusConstants = __webpack_require__(/*! ./databus-constants */ \"./js/utils/databus-constants.js\");\nconst DatabusUris = __webpack_require__(/*! ./databus-uris */ \"./js/utils/databus-uris.js\");\nconst DatabusUtils = __webpack_require__(/*! ./databus-utils */ \"./js/utils/databus-utils.js\");\nconst JsonldUtils = __webpack_require__(/*! ./jsonld-utils */ \"./js/utils/jsonld-utils.js\");\n\n/**\n * Translates expanded jsonld into web-app compatible json\n */\nclass AppJsonFormatter {\n\n static createAccountData(accountUri, accountLabel, accountStatus, accountImage) {\n\n var personUri = `${accountUri}${DatabusConstants.WEBID_THIS}`;\n\n var accountJsonLd = {};\n\n var accountGraph = {};\n accountGraph[DatabusUris.JSONLD_ID] = accountUri;\n accountGraph[DatabusUris.JSONLD_TYPE] = DatabusUris.DATABUS_ACCOUNT;\n\n var personGraph = {};\n personGraph[DatabusUris.JSONLD_ID] = personUri;\n personGraph[DatabusUris.JSONLD_TYPE] = DatabusUris.FOAF_PERSON;\n personGraph[DatabusUris.FOAF_NAME] = accountLabel;\n personGraph[DatabusUris.FOAF_ACCOUNT] = JsonldUtils.refTo(accountUri);\n\n if (accountStatus != null) {\n personGraph[DatabusUris.FOAF_STATUS] = accountStatus;\n }\n\n if (accountImage != null) {\n personGraph[DatabusUris.FOAF_IMG] = JsonldUtils.refTo(accountImage);\n }\n\n\n accountJsonLd[DatabusUris.JSONLD_GRAPH] = [\n accountGraph,\n personGraph\n ];\n\n return accountJsonLd;\n }\n\n static formatGroupData(graphs) {\n var result = {};\n\n // ?uri ?title ?abstract ?description\n var groupGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.DATABUS_GROUP);\n\n result.uri = groupGraph[DatabusUris.JSONLD_ID];\n result.title = JsonldUtils.getProperty(groupGraph, DatabusUris.DCT_TITLE);\n result.abstract = JsonldUtils.getProperty(groupGraph, DatabusUris.DCT_ABSTRACT);\n result.description = JsonldUtils.getProperty(groupGraph, DatabusUris.DCT_DESCRIPTION);\n result.name = DatabusUtils.uriToResourceName(result.uri);\n return result;\n }\n\n static formatArtifactData(graphs) {\n var result = {};\n // ?uri ?title ?abstract ?description\n var artifactGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.DATABUS_ARTIFACT);\n\n result.uri = artifactGraph[DatabusUris.JSONLD_ID];\n result.title = JsonldUtils.getProperty(artifactGraph, DatabusUris.DCT_TITLE);\n result.abstract = JsonldUtils.getProperty(artifactGraph, DatabusUris.DCT_ABSTRACT);\n result.description = JsonldUtils.getProperty(artifactGraph, DatabusUris.DCT_DESCRIPTION);\n result.name = DatabusUtils.uriToResourceName(result.uri);\n return result;\n\n\n }\n\n static formatAccountData(graphs) {\n var result = {};\n\n var profileGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.FOAF_PERSONAL_PROFILE_DOCUMENT);\n var personGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.FOAF_PERSON);\n\n result.uri = profileGraph[DatabusUris.JSONLD_ID];\n result.accountName = DatabusUtils.uriToResourceName(result.uri);\n result.label = JsonldUtils.getProperty(personGraph, DatabusUris.FOAF_NAME);\n result.webIds = [];\n result.searchExtensions = [];\n\n var extensionGraphs = JsonldUtils.getTypedGraphs(graphs, DatabusUris.DATABUS_SEARCH_EXTENSION);\n\n for (var extensionGraph of extensionGraphs) {\n result.searchExtensions.push({\n endpointUri: JsonldUtils.getProperty(extensionGraph, DatabusUris.DATABUS_SEARCH_EXTENSION_ENDPOINT),\n adapterName: JsonldUtils.getProperty(extensionGraph, DatabusUris.DATABUS_SEARCH_EXTENSION_ADAPTER),\n });\n }\n\n for (var graph of graphs) {\n\n if (graph[DatabusUris.JSONLD_ID] == personGraph[DatabusUris.JSONLD_ID]) {\n continue;\n }\n\n if (graph[DatabusUris.FOAF_ACCOUNT] != undefined) {\n result.webIds.push(graph[DatabusUris.JSONLD_ID]);\n }\n }\n\n return result;\n }\n\n static formatVersionData(versionGraph) {\n\n\n var version = {};\n version.uri = versionGraph[DatabusUris.JSONLD_ID];\n version.title = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_TITLE);\n version.abstract = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_ABSTRACT);\n version.description = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_DESCRIPTION);\n version.artifact = JsonldUtils.getProperty(versionGraph, DatabusUris.DATABUS_ARTIFACT_PROPERTY);\n version.license = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_LICENSE);\n version.attribution = JsonldUtils.getProperty(versionGraph, DatabusUris.DATABUS_ATTRIBUTION);\n version.wasDerivedFrom = JsonldUtils.getProperty(versionGraph, DatabusUris.PROV_WAS_DERIVED_FROM);\n version.issued = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_ISSUED);\n version.name = JsonldUtils.getProperty(versionGraph, DatabusUris.DCT_HAS_VERSION);\n\n return version;\n }\n\n static formatCollectionData(graphs) {\n var collectionGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.DATABUS_COLLECTION);\n\n var result = {};\n\n result.uri = collectionGraph[DatabusUris.JSONLD_ID];\n result.title = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_TITLE);\n result.abstract = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_ABSTRACT);\n result.description = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_DESCRIPTION);\n result.issued = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_ISSUED);\n result.publisher = JsonldUtils.getProperty(collectionGraph, DatabusUris.DCT_PUBLISHER);\n\n var content = JsonldUtils.getProperty(collectionGraph, DatabusUris.DATABUS_COLLECTION_CONTENT)\n result.content = DatabusUtils.tryParseJson(unescape(content));\n\n return result;\n }\n}\n\nmodule.exports = AppJsonFormatter;\n\n\n//# sourceURL=webpack://databus-webapp/./js/utils/app-json-formatter.js?"); /***/ }), diff --git a/public/js/page-controller/profile-controller.js b/public/js/page-controller/profile-controller.js index 4007b7c1..bc924a74 100644 --- a/public/js/page-controller/profile-controller.js +++ b/public/js/page-controller/profile-controller.js @@ -24,8 +24,9 @@ function ProfileController($scope, $http) { $scope.putProfile = function (accountName) { - var accountJsonLd = AppJsonFormatter.createAccountData(DATABUS_RESOURCE_BASE_URL, - accountName, + var accountUri = `${DATABUS_RESOURCE_BASE_URL}/${accountName}`; + var accountJsonLd = AppJsonFormatter.createAccountData( + accountUri, accountName, null, null); @@ -183,8 +184,9 @@ function ProfileController($scope, $http) { return; } - var accountJsonLd = AppJsonFormatter.createAccountData(DATABUS_RESOURCE_BASE_URL, - $scope.auth.info.accountName, + var accountUri = `${DATABUS_RESOURCE_BASE_URL}/${$scope.auth.info.accountName}`; + var accountJsonLd = AppJsonFormatter.createAccountData( + accountUri, $scope.editData.label, $scope.editData.about, $scope.editData.imageUrl); diff --git a/public/js/utils/app-json-formatter.js b/public/js/utils/app-json-formatter.js index ab47ba13..e164662a 100644 --- a/public/js/utils/app-json-formatter.js +++ b/public/js/utils/app-json-formatter.js @@ -8,10 +8,9 @@ const JsonldUtils = require("./jsonld-utils"); */ class AppJsonFormatter { - static createAccountData(resourceBaseUrl, accountName, accountLabel, accountStatus, accountImage) { + static createAccountData(accountUri, accountLabel, accountStatus, accountImage) { - var accountUri = `${resourceBaseUrl}/${accountName}`; - var personUri = `${resourceBaseUrl}/${accountName}${DatabusConstants.WEBID_THIS}`; + var personUri = `${accountUri}${DatabusConstants.WEBID_THIS}`; var accountJsonLd = {}; @@ -34,12 +33,10 @@ class AppJsonFormatter { } - accountJsonLd[DatabusUris.JSONLD_GRAPH] = [ + return [ accountGraph, personGraph ]; - - return accountJsonLd; } static formatGroupData(graphs) { @@ -74,12 +71,13 @@ class AppJsonFormatter { static formatAccountData(graphs) { var result = {}; - var profileGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.FOAF_PERSONAL_PROFILE_DOCUMENT); + var accountGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.DATABUS_ACCOUNT); var personGraph = JsonldUtils.getTypedGraph(graphs, DatabusUris.FOAF_PERSON); - result.uri = profileGraph[DatabusUris.JSONLD_ID]; + result.uri = accountGraph[DatabusUris.JSONLD_ID]; result.accountName = DatabusUtils.uriToResourceName(result.uri); result.label = JsonldUtils.getProperty(personGraph, DatabusUris.FOAF_NAME); + result.about = JsonldUtils.getProperty(personGraph, DatabusUris.FOAF_STATUS); result.webIds = []; result.searchExtensions = []; diff --git a/public/js/utils/databus-utils.js b/public/js/utils/databus-utils.js index 9e93fd01..da0a134d 100644 --- a/public/js/utils/databus-utils.js +++ b/public/js/utils/databus-utils.js @@ -503,19 +503,6 @@ class DatabusUtils { return errorList; } - static validateNamespace(uri, accountName) { - - var baseURL = process.env.DATABUS_RESOURCE_BASE_URL; - - if (!uri.startsWith(process.env.DATABUS_RESOURCE_BASE_URL)) { - throw new ApiError(`Identifier <${uri}> does not start with the resource base url <${baseURL}> of this Databus.`, 400); - } - - var namespacePrefix = `${baseURL}/${accountName}/`; - if (!uri.startsWith(namespacePrefix)) { - throw new ApiError(`Identifier <${uri}> does not start with the expected namespace prefix <${namespacePrefix}>.`, 403); - } - } } module.exports = DatabusUtils; diff --git a/public/js/utils/jsonld-utils.js b/public/js/utils/jsonld-utils.js index abd341e2..b2d7435d 100644 --- a/public/js/utils/jsonld-utils.js +++ b/public/js/utils/jsonld-utils.js @@ -8,7 +8,7 @@ class JsonldUtils { result[DatabusUris.JSONLD_ID] = uri; return result; } - + static getTypedGraph(graphs, graphType) { for (var g in graphs) { @@ -139,14 +139,27 @@ class JsonldUtils { return obj[0]; } - static getFirstObjectUri(graph, key) { - var obj = graph[key]; + static getFirstObjectUri(graph, property) { + // Get the object + const obj = graph[property]; - if (obj == undefined || obj.length < 1) { + // Not found -> null + if (!obj) { return null; } + + // If it is an array... + if (Array.isArray(obj)) { + for (const item of obj) { + if (item && typeof item === 'object' && DatabusUris.JSONLD_ID in item) { + return item[DatabusUris.JSONLD_ID]; + } + } + } else if (typeof obj === 'object' && DatabusUris.JSONLD_ID in obj) { + return obj[DatabusUris.JSONLD_ID]; + } - return obj[0][DatabusUris.JSONLD_ID]; + return null; } } diff --git a/public/templates/404.ejs b/public/templates/404.ejs index 1a959725..807ba4b5 100644 --- a/public/templates/404.ejs +++ b/public/templates/404.ejs @@ -1,6 +1,6 @@ <%- include('header') -%>
-
+
diff --git a/public/templates/artifact.ejs b/public/templates/artifact.ejs index 0dae693c..d7575542 100644 --- a/public/templates/artifact.ejs +++ b/public/templates/artifact.ejs @@ -170,7 +170,8 @@ {{ version.version }} {{ utils.formatDate(version.date) }} - {{ version.license }} + {{ version.license + }} diff --git a/server/app/api/lib/account-writer.js b/server/app/api/lib/account-writer.js index 3e8d05cd..83bc63fb 100644 --- a/server/app/api/lib/account-writer.js +++ b/server/app/api/lib/account-writer.js @@ -19,13 +19,13 @@ class AccountWriter extends ResourceWriter { if(this.userData.accountName == null) { if(!this.resource.isAccount()) { - throw new ApiError(`Identifier <${uri}> is not a valid account URI.`, 400); + throw new ApiError(400, this.uri, `Identifier <${this.uri}> is not a valid account URI.`, null); } var accountName = this.resource.getAccount(); if(accountName.length < 4) { - throw new ApiError(`Specified account name ('${accountName}') must be at least 4 characters long.`, 400); + throw new ApiError(400, this.uri, `Specified account name ('${accountName}') must be at least 4 characters long.`, null); } this.userData = await this.createUserCallback(this.userData); @@ -73,6 +73,7 @@ class AccountWriter extends ResourceWriter { if(inputPersonGraph != null) { personGraph[DatabusUris.FOAF_NAME] = inputPersonGraph[DatabusUris.FOAF_NAME]; personGraph[DatabusUris.FOAF_IMG] = inputPersonGraph[DatabusUris.FOAF_IMG]; + personGraph[DatabusUris.FOAF_STATUS] = inputPersonGraph[DatabusUris.FOAF_STATUS]; } var profileUri = `${accountUri}${DatabusConstants.WEBID_DOCUMENT}`; @@ -102,280 +103,3 @@ class AccountWriter extends ResourceWriter { } module.exports = AccountWriter; - -/* -async function accountExists(accountName) { - let accountUri = UriUtils.createResourceUri([accountName]); - return await exec.executeAsk(`ASK { ?s <${DatabusUris.FOAF_ACCOUNT}> <${accountUri}> . }`); -} - - -async function publishAccount(inputGraphs, accountGraph, logger) { - - var accountUri = JsonldUtils.getFirstObjectUri(accountGraph, DatabusUris.JSONLD_ID); - - if (accountName.length < 4) { - throw new ApiError(`An account name should contain at least 4 characters.`, 400); - } - - // Expected uris - var accountUri = `${process.env.DATABUS_RESOURCE_BASE_URL}/${accountName}`; - - var personUri = `${accountUri}${DatabusConstants.WEBID_THIS}`; - var profileUri = `${accountUri}${DatabusConstants.WEBID_DOCUMENT}`; - - // Compare the specified id to the actual person uri - var personGraph = JsonldUtils.getTypedGraph(expandedGraphs, DatabusUris.FOAF_PERSON); - - if (personGraph == undefined) { - result.message = `No person graph found`; - result.statusCode = 400; - return result; - } - - // Mismatch gives error - if (personGraph[DatabusUris.JSONLD_ID] != personUri) { - result.message = `The specified uri of the foaf:Person does not match the expected value. (specified: ${personGraph['@id']}, expected: ${personUri})\n`; - result.statusCode = 400; - return result; - } - - // Compare the specified id to the actual person uri - var profileGraph = JsonldUtils.getTypedGraph(expandedGraphs, DatabusUris.FOAF_PERSONAL_PROFILE_DOCUMENT); - - if (profileGraph == undefined) { - result.message = `No profile graph found`; - result.statusCode = 400; - return result; - } - - - // URIs OK, look at content: -} - - -async function createUser(userDatabase, sub, accountName) { - - var accountExists = await userDatabase.hasUser(accountName); - - if(accountExists) { - throw new ApiError(`Account <${accountName}> already exists.`, 401); - } - - try { - await protector.addUser(sub, accountName, accountName); - } catch(err) { - throw new ApiError(`Failed to write to user database`, 500); - } -} - -module.exports = async function publishAccounts(inputGraphs, accountData, userDatabase, logger) { - // Find task related graphs - var accountGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_ACCOUNT); - logger.debug(null, `Found ${accountGraphs.length} account graphs.`, null); - - for (var accountGraph of accountGraphs) { - - var accountUri = accountGraph[DatabusUris.JSONLD_ID]; - logger.debug(null, `Found input entity <${accountUri}>.`, null); - - var accountName = accountData.name; - - if(accountName == null) { - // Try to create the user... - accountName = UriUtils.uriToName(accountUri); - createUser(userDatabase, accountData.sub, accountName); - // User is successfully created here - } - - DatabusUtils.validateNamespace(accountUri, accountName); - - - var accountUri = accountGraph[DatabusUris.JSONLD_ID]; - logger.debug(groupUri, `Processing account <${accountUri}>`, accountGraph); - - - - await publishAccount(inputGraphs, accountGraph, logger); - } - - var accountUri = graph[DatabusUris.JSONLD_ID]; - logger.debug(groupUri, `Processing account <${accountUri}>`, graph); - - DatabusUtils.validateNamespace(accountUri, accountName); - - if (accountName.length < 4) { - throw new ApiError(`An account name should contain at least 4 characters.`, 400); - } - - // URIs OK, look at content: - var triples = await constructor.executeConstruct(body, constructAccountQuery); - var expandedGraphs = await jsonld.flatten(await jsonld.fromRDF(triples)); - - if (expandedGraphs.length == 0) { - throw new ApiError(`The following construct query did not yield any triples:\n\n${constructAccountQuery}\n`, 400); - } - - // Fill / construct input data - - - - - - - - - - - - // Validate the group RDF with the shacl validation tool - var shaclResult = await shaclTester.validateWebIdRDF(body); - - if (!shaclResult.isSuccess) { - var response = 'SHACL validation error:\n'; - for (var m in shaclResult.messages) { - response += `>>> ${shaclResult.messages[m]}\n` - } - - throw new ApiError(response, 400); - } - -} - - -module.exports = async function publishAccount(accountName, body) { - - var result = {}; - result.isSuccess = false; - result.message = ""; - result.statusCode = 403; - - - try { - - // Get the accountName from the protected request - if (accountName.length < 4) { - result.message = `Account name is too short. An account name should contain at least 4 characters.\n`; - return result; - } - - - // Return failure - if (!shaclResult.isSuccess) { - var response = 'SHACL validation error:\n'; - for (var m in shaclResult.messages) { - response += `>>> ${shaclResult.messages[m]}\n` - } - - result.message = response; - result.statusCode = 400; - return result; - } - - var triples = await constructor.executeConstruct(body, constructAccountQuery); - var expandedGraphs = await jsonld.flatten(await jsonld.fromRDF(triples)); - - if (expandedGraphs.length == 0) { - result.message = `The following construct query did not yield any triples:\n\n${constructAccountQuery}\n`; - result.statusCode = 400; - return result; - } - - // Expected uris - var accountUri = `${process.env.DATABUS_RESOURCE_BASE_URL}/${accountName}`; - - var personUri = `${accountUri}${DatabusConstants.WEBID_THIS}`; - var profileUri = `${accountUri}${DatabusConstants.WEBID_DOCUMENT}`; - - // Compare the specified id to the actual person uri - var personGraph = JsonldUtils.getTypedGraph(expandedGraphs, DatabusUris.FOAF_PERSON); - - if (personGraph == undefined) { - result.message = `No person graph found`; - result.statusCode = 400; - return result; - } - - // Mismatch gives error - if (personGraph[DatabusUris.JSONLD_ID] != personUri) { - result.message = `The specified uri of the foaf:Person does not match the expected value. (specified: ${personGraph['@id']}, expected: ${personUri})\n`; - result.statusCode = 400; - return result; - } - - // Compare the specified id to the actual person uri - var profileGraph = JsonldUtils.getTypedGraph(expandedGraphs, DatabusUris.FOAF_PERSONAL_PROFILE_DOCUMENT); - - if (profileGraph == undefined) { - result.message = `No profile graph found`; - result.statusCode = 400; - return result; - } - - // Mismatch gives error - if (profileGraph[DatabusUris.JSONLD_ID] != profileUri) { - result.message = `The specified uri of the foaf:PersonalProfileDocument graph does not match the expected value. (specified: ${profileGraph['@id']}, expected: ${profileUri})\n`; - result.statusCode = 400; - return result; - } - - var pkeyPEM = fs.readFileSync(__dirname + '/../../../keypair/public-key.pem', 'utf-8'); - var publicKeyInfo = pem2jwk(pkeyPEM); - let buff = Buffer.from(publicKeyInfo.n, 'base64'); - var modulus = buff.toString('hex'); - - var rsaKeyGraph = {}; - rsaKeyGraph[DatabusUris.JSONLD_TYPE] = DatabusUris.CERT_RSA_PUBLIC_KEY; - rsaKeyGraph[DatabusUris.RDFS_LABEL] = DatabusConstants.WEBID_SHARED_PUBLIC_KEY_LABEL; - rsaKeyGraph[DatabusUris.CERT_MODULUS] = modulus; - rsaKeyGraph[DatabusUris.CERT_EXPONENT] = 65537; - - personGraph[DatabusUris.CERT_KEY] = [rsaKeyGraph]; - - - var insertGraphs = expandedGraphs; - var compactedGraph = await jsonld.compact(insertGraphs, defaultContext); - - if (process.env.DATABUS_CONTEXT_URL != null) { - compactedGraph[DatabusUris.JSONLD_CONTEXT] = process.env.DATABUS_CONTEXT_URL; - } - - var targetPath = Constants.DATABUS_FILE_WEBID; - - - var exists = await accountExists(accountName); - - - - // Save the data using the database manager - var saveResult = await GstoreHelper.save(accountName, targetPath, compactedGraph); - - if (!saveResult.isSuccess) { - // return with Forbidden - result.message = 'Internal database error.\n'; - result.statusCode = 500; - return result; - } - - if(process.send != undefined) { - process.send({ - id: DatabusMessage.REQUEST_SEARCH_INDEX_REBUILD, - resources : accountUri - }); - } - - result.isSuccess = true; - result.statusCode = exists ? 200 : 201; - result.message = 'Account saved successfully.\n'; - return result; - - } catch (err) { - // return 500 with error - console.log('User creation failed!'); - console.log(err); - result.message = err; - result.statusCode = 500; - return result; - } -} - */ \ No newline at end of file diff --git a/server/app/api/lib/artifact-writer.js b/server/app/api/lib/artifact-writer.js index 546854eb..f3cb5ecc 100644 --- a/server/app/api/lib/artifact-writer.js +++ b/server/app/api/lib/artifact-writer.js @@ -1,4 +1,5 @@ const DatabusUris = require('../../../../public/js/utils/databus-uris'); +const DatabusUtils = require('../../../../public/js/utils/databus-utils.js'); const JsonldUtils = require('../../../../public/js/utils/jsonld-utils.js'); const ResourceWriter = require('./resource-writer.js'); @@ -22,19 +23,23 @@ class ArtifactWriter extends ResourceWriter { artifactGraph[DatabusUris.DCT_TITLE] = inputArtifactGraph[DatabusUris.DCT_TITLE]; } - if(inputArtifactGraph[DatabusUris.DCT_ABSTRACT] != null) { - artifactGraph[DatabusUris.DCT_ABSTRACT] = inputArtifactGraph[DatabusUris.DCT_ABSTRACT]; - } if(inputArtifactGraph[DatabusUris.DCT_DESCRIPTION] != null) { artifactGraph[DatabusUris.DCT_DESCRIPTION] = inputArtifactGraph[DatabusUris.DCT_DESCRIPTION]; } + if(inputArtifactGraph[DatabusUris.DCT_ABSTRACT] != null) { + artifactGraph[DatabusUris.DCT_ABSTRACT] = inputArtifactGraph[DatabusUris.DCT_ABSTRACT]; + } else if (groupGraph[DatabusUris.DCT_DESCRIPTION] != null) { + artifactGraph[DatabusUris.DCT_DESCRIPTION] = DatabusUtils.createAbstractFromDescription(artifactGraph[DatabusUris.DCT_DESCRIPTION]); + } + var groupGraph = {}; groupGraph[DatabusUris.JSONLD_ID] = this.resource.getGroupURI(); groupGraph[DatabusUris.JSONLD_TYPE] = DatabusUris.DATABUS_GROUP; return [ - artifactGraph + artifactGraph, + groupGraph ]; } diff --git a/server/app/api/lib/databus-resource.js b/server/app/api/lib/databus-resource.js deleted file mode 100644 index ec5d9123..00000000 --- a/server/app/api/lib/databus-resource.js +++ /dev/null @@ -1,102 +0,0 @@ -class DatabusResource { - static DATABUS_COLLECTION_GROUP = "collections"; - - constructor(uriString) { - if (!uriString) { - throw new Error("A valid URI string is required"); - } - - this.parseUri(new URL(uriString)); - } - - parseUri(url) { - this.baseURI = `${url.protocol}//${url.host}`; - const segments = url.pathname.split("/").filter(Boolean); - - this.account = segments[0] || null; - this.group = segments[1] || null; - this.artifact = segments[2] || null; - this.version = segments[3] || null; - } - - getAccount() { - return this.account; - } - - getGroup() { - return this.group; - } - - getArtifact() { - return this.artifact; - } - - getVersion() { - return this.version; - } - - getAccountURI() { - return this.account ? `${this.baseURI}/${this.account}` : null; - } - - getGroupURI() { - return this.group ? `${this.baseURI}/${this.account}/${this.group}` : null; - } - - getArtifactURI() { - return this.artifact ? `${this.baseURI}/${this.account}/${this.group}/${this.artifact}` : null; - } - - getCollectionURI() { - return this.artifact ? `${this.baseURI}/${this.account}/${DatabusResource.DATABUS_COLLECTION_GROUP}/${this.artifact}` : null; - } - - getVersionURI() { - return this.version ? `${this.baseURI}/${this.account}/${this.group}/${this.artifact}/${this.version}` : null; - } - - getBaseURI() { - return this.baseURI; - } - - toString() { - return `DatabusResource { account: '${this.account}', group: '${this.group}', artifact: '${this.artifact}', version: '${this.version}' }`; - } - - equals(other) { - if (!(other instanceof DatabusResource)) return false; - return ( - this.account === other.account && - this.group === other.group && - this.artifact === other.artifact && - this.version === other.version && - this.baseURI === other.baseURI - ); - } - - hashCode() { - return JSON.stringify([this.account, this.group, this.artifact, this.version, this.baseURI]).hashCode(); - } - - isVersion() { - return this.version !== null; - } - - isArtifact() { - return this.artifact !== null && this.version === null && this.group !== DatabusResource.DATABUS_COLLECTION_GROUP; - } - - isCollection() { - return this.artifact !== null && this.version === null && this.group === DatabusResource.DATABUS_COLLECTION_GROUP; - } - - isGroup() { - return this.group !== null && this.artifact === null; - } - - isAccount() { - return this.account !== null && this.group === null; - } -} - -module.exports = DatabusResource; \ No newline at end of file diff --git a/server/app/api/lib/databus-tractate-suite.js b/server/app/api/lib/databus-tractate-suite.js index b5b7398e..05e86d90 100644 --- a/server/app/api/lib/databus-tractate-suite.js +++ b/server/app/api/lib/databus-tractate-suite.js @@ -8,6 +8,7 @@ const Constants = require('../../common/constants'); var fileAnalyzer = require('../../common/file-analyzer'); var GstoreHelper = require('../../common/utils/gstore-helper'); var requestRdf = require('../../common/request-rdf'); +const GstoreResource = require('./gstore-resource'); const pem2jwk = require('pem-jwk').pem2jwk; var tractateConfig = { @@ -140,8 +141,10 @@ signer.validate = async function (canonicalized, proof) { var repo = webIdURL.pathname.substring(1); // Read the WebId directly from the Gstore to avoid access problems in private mode - var webIdJsonLd = await GstoreHelper.read(repo, Constants.DATABUS_FILE_WEBID); - var flattenedGraphs = await jsonld.flatten(webIdJsonLd); + var gstoreResource = new GstoreResource(publisherUri); + await gstoreResource.read(); + + var flattenedGraphs = await jsonld.flatten(gstoreResource.content); quads = await requestRdf.parseRdf(Constants.HTTP_CONTENT_TYPE_JSONLD, JSON.stringify(flattenedGraphs)) diff --git a/server/app/api/lib/dataid-autocomplete.js b/server/app/api/lib/dataid-autocomplete.js index 7ce04d1a..0a73e335 100644 --- a/server/app/api/lib/dataid-autocomplete.js +++ b/server/app/api/lib/dataid-autocomplete.js @@ -220,58 +220,5 @@ autocompleter.autocomplete = function (expandedGraph, logger) { } -autocompleter.autocompleteArtifact = function (expandedGraphs) { - - var artifactGraph = JsonldUtils.getTypedGraph(expandedGraphs, DatabusUris.DATABUS_ARTIFACT); - var artifactUri = artifactGraph[DatabusUris.JSONLD_ID]; - var groupUri = UriUtils.navigateUp(artifactUri, 1); - var accountUri = UriUtils.navigateUp(artifactUri, 2); - var artifactName = UriUtils.uriToName(artifactUri); - - var groupGraph = {}; - groupGraph[DatabusUris.JSONLD_ID] = groupUri; - groupGraph[DatabusUris.JSONLD_TYPE] = DatabusUris.DATABUS_GROUP; - expandedGraphs.push(groupGraph); - - artifactGraph[DatabusUris.DATABUS_GROUP_PROPERTY] = [{}]; - artifactGraph[DatabusUris.DATABUS_GROUP_PROPERTY][0][DatabusUris.JSONLD_ID] = groupUri; - - artifactGraph[DatabusUris.DATABUS_ACCOUNT_PROPERTY] = [{}]; - artifactGraph[DatabusUris.DATABUS_ACCOUNT_PROPERTY][0][DatabusUris.JSONLD_ID] = accountUri; - - artifactGraph[DatabusUris.DATABUS_NAME] = [{}]; - artifactGraph[DatabusUris.DATABUS_NAME][0][DatabusUris.JSONLD_VALUE] = artifactName; - - if (artifactGraph[DatabusUris.DCT_ABSTRACT] == undefined - && artifactGraph[DatabusUris.DCT_DESCRIPTION] != undefined) { - var description = artifactGraph[DatabusUris.DCT_DESCRIPTION][0][DatabusUris.JSONLD_VALUE]; - artifactGraph[DatabusUris.DCT_ABSTRACT] = [{}]; - artifactGraph[DatabusUris.DCT_ABSTRACT][0][JSONLD_VALUE] = - DatabusUtils.createAbstractFromDescription(description); - } -} - -autocompleter.autocompleteGroup = function (expandedGraphs) { - - var groupGraph = JsonldUtils.getTypedGraph(expandedGraphs, DatabusUris.DATABUS_GROUP); - var groupUri = groupGraph[DatabusUris.JSONLD_ID]; - var accountUri = UriUtils.navigateUp(groupUri, 1); - var groupName = UriUtils.uriToName(groupUri); - - groupGraph[DatabusUris.DATABUS_ACCOUNT_PROPERTY] = [{}]; - groupGraph[DatabusUris.DATABUS_ACCOUNT_PROPERTY][0][DatabusUris.JSONLD_ID] = accountUri; - - groupGraph[DatabusUris.DATABUS_NAME] = [{}]; - groupGraph[DatabusUris.DATABUS_NAME][0][DatabusUris.JSONLD_VALUE] = groupName; - - if (groupGraph[DatabusUris.DCT_ABSTRACT] == undefined - && groupGraph[DatabusUris.DCT_DESCRIPTION] != undefined) { - - var description = groupGraph[DatabusUris.DCT_DESCRIPTION][0][DatabusUris.JSONLD_VALUE]; - groupGraph[DatabusUris.DCT_ABSTRACT] = [{}]; - groupGraph[DatabusUris.DCT_ABSTRACT][0][JSONLD_VALUE] = - DatabusUtils.createAbstractFromDescription(description); - } -} module.exports = autocompleter; \ No newline at end of file diff --git a/server/app/api/lib/group-writer.js b/server/app/api/lib/group-writer.js index c85327ef..e24ffd7b 100644 --- a/server/app/api/lib/group-writer.js +++ b/server/app/api/lib/group-writer.js @@ -1,4 +1,5 @@ const DatabusUris = require('../../../../public/js/utils/databus-uris'); +const DatabusUtils = require('../../../../public/js/utils/databus-utils.js'); const JsonldUtils = require('../../../../public/js/utils/jsonld-utils.js'); const ResourceWriter = require('./resource-writer.js'); @@ -9,7 +10,7 @@ class GroupWriter extends ResourceWriter { } async onCreateGraphs() { - + var inputGroupGraph = JsonldUtils.getGraphById(this.inputGraphs, this.uri); var groupGraph = {}; @@ -21,13 +22,16 @@ class GroupWriter extends ResourceWriter { groupGraph[DatabusUris.DCT_TITLE] = inputGroupGraph[DatabusUris.DCT_TITLE]; } - if(inputGroupGraph[DatabusUris.DCT_ABSTRACT] != null) { - groupGraph[DatabusUris.DCT_ABSTRACT] = inputGroupGraph[DatabusUris.DCT_ABSTRACT]; - } if(inputGroupGraph[DatabusUris.DCT_DESCRIPTION] != null) { groupGraph[DatabusUris.DCT_DESCRIPTION] = inputGroupGraph[DatabusUris.DCT_DESCRIPTION]; } + if(inputGroupGraph[DatabusUris.DCT_ABSTRACT] != null) { + groupGraph[DatabusUris.DCT_ABSTRACT] = inputGroupGraph[DatabusUris.DCT_ABSTRACT]; + } else if (groupGraph[DatabusUris.DCT_DESCRIPTION] != null) { + groupGraph[DatabusUris.DCT_DESCRIPTION] = DatabusUtils.createAbstractFromDescription(groupGraph[DatabusUris.DCT_DESCRIPTION]); + } + return [ groupGraph ]; diff --git a/server/app/api/lib/gstore-resource.js b/server/app/api/lib/gstore-resource.js index 2aef0753..39ef7193 100644 --- a/server/app/api/lib/gstore-resource.js +++ b/server/app/api/lib/gstore-resource.js @@ -59,7 +59,7 @@ class GstoreResource { try { var url = this.getRequestURL('Write'); - console.log(JSON.stringify(this.content, null, 3)); + // console.log(JSON.stringify(this.content, null, 3)); const response = await axios.post(url, this.content, { headers: { 'Content-Type': Constants.HTTP_CONTENT_TYPE_JSONLD } @@ -75,6 +75,7 @@ class GstoreResource { async read() { try { const response = await axios.get(this.getRequestURL('Read'), { headers: { 'Accept': 'application/ld+json' } }); + this.content = response.data; return response.data; } catch (error) { console.error('Error reading document:', error); diff --git a/server/app/api/lib/publish-artifact.js b/server/app/api/lib/publish-artifact.js deleted file mode 100644 index c0ea5eee..00000000 --- a/server/app/api/lib/publish-artifact.js +++ /dev/null @@ -1,111 +0,0 @@ -const UriUtils = require('../../common/utils/uri-utils'); -const DatabusUris = require('../../../../public/js/utils/databus-uris'); -const Constants = require('../../common/constants'); - -var shaclTester = require('../../common/shacl-tester'); -var GstoreHelper = require('../../common/utils/gstore-helper'); -var jsonld = require('jsonld'); -var constructor = require('../../common/execute-construct.js'); -var constructArtifactQuery = require('../../common/queries/constructs/construct-artifact.sparql'); -const DatabusUtils = require('../../../../public/js/utils/databus-utils'); -var autocompleter = require('./dataid-autocomplete'); -const DatabusMessage = require('../../common/databus-message'); - -module.exports = async function publishArtifact(accountName, graph, logger) { - - - try { - - var artifactUri = graph[DatabusUris.JSONLD_ID]; - logger.debug(artifactUri, `Processing artifact <${artifactUri}>`, graph); - - // Check for namespace violation - var expectedUriPrefix = `${process.env.DATABUS_RESOURCE_BASE_URL}/${accountName}/`; - - if (!artifactUri.startsWith(expectedUriPrefix)) { - logger.error(artifactUri, `Not allowed to access namespace of artifact identifier <${artifactUri}>.`); - return 403; - } - - var artifactSegment = UriUtils.cleanSegment(artifactUri.replace(expectedUriPrefix, "")); - - if (UriUtils.getPathLength(artifactSegment) != 2) { - logger.error(artifactUri, `Artifact uri <${artifactUri}> must have exactly 3 path segments relative to the Databus base url <${process.env.DATABUS_RESOURCE_BASE_URL}> (found ${UriUtils.getPathLength(artifactSegment) + 1})`, null); - return 400; - } - - var segments = artifactSegment.split("/"); - var groupName = segments[0]; - var artifactName = segments[1]; - - if (groupName == Constants.DATABUS_COLLECTIONS_GROUP_IDENTIFIER) { - logger.error(artifactUri, `Cannot create artifact with group name "${Constants.DATABUS_COLLECTIONS_GROUP_IDENTIFIER}" as it is reserved for Databus collections.`); - return 400; - } - - // Get the desired triples from the data via construct query - var triples = await constructor.executeConstruct(graph, constructArtifactQuery); - var tripleCount = DatabusUtils.lineCount(triples); - - if (tripleCount == 0) { - logger.info(artifactUri, `Construct query did not yield any triples. Nothing to publish.`, graph); - return 200; - } - - logger.debug(artifactUri, `${tripleCount} triples selected via construct query.`, triples); - var expandedGraphs = await jsonld.flatten(await jsonld.fromRDF(triples)); - - // Auto-complete - autocompleter.autocompleteArtifact(expandedGraphs); - logger.debug(artifactUri, `Input has been processed by the auto-completer`, expandedGraphs); - - // Validate the artifact RDF with the shacl validation tool - var shaclResult = await shaclTester.validateArtifactRDF(expandedGraphs); - - // Return failure with SHACL validation message - if (!shaclResult.isSuccess) { - logger.error(artifactUri, `SHACL validation error`, shaclResult); - return 400; - } - - logger.debug(artifactUri, `SHACL validation successful`, shaclResult); - - - // Compact graph, determine target path - var compactedGraph = await jsonld.compact(expandedGraphs, process.env.DATABUS_CONTEXT_URL); - logger.debug(artifactUri, `Compacted with context <${process.env.DATABUS_CONTEXT_URL}>`); - - //(if (process.env.DATABUS_CONTEXT_URL != null) { - // compactedGraph[DatabusUris.JSONLD_CONTEXT] = process.env.DATABUS_CONTEXT_URL; - // logger.debug(artifactUri, `Context has been resubstituted with <${process.env.DATABUS_CONTEXT_URL}>`); - //} l - - var targetPath = `${groupName}/${artifactName}/${Constants.DATABUS_FILE_ARTIFACT}`; - logger.debug(artifactUri, `Saving artifact <${artifactUri}> to ${accountName}:${targetPath}`, compactedGraph); - - // Save the RDF with the current path using the database manager - var publishResult = await GstoreHelper.save(accountName, targetPath, compactedGraph); - - // Return failure - if (!publishResult.isSuccess) { - logger.error(artifactUri, `Internal database error`, null); - return 500; - } - - if(process.send != undefined) { - process.send({ - id: DatabusMessage.REQUEST_SEARCH_INDEX_REBUILD, - resource: artifactUri - }); - } - - logger.info(artifactUri, `Successfully published artifact <${artifactUri}>.`, compactedGraph); - return 200; - - } catch (err) { - console.log(`Unexpected Databus error when processing artifact data`); - console.log(err); - logger.error(null, `Unexpected Databus error when processing artifact data`, null); - return 500; - } -} diff --git a/server/app/api/lib/publish-group.js b/server/app/api/lib/publish-group.js deleted file mode 100644 index 5864b9db..00000000 --- a/server/app/api/lib/publish-group.js +++ /dev/null @@ -1,111 +0,0 @@ -const UriUtils = require('../../common/utils/uri-utils'); -const DatabusUris = require('../../../../public/js/utils/databus-uris'); -const Constants = require('../../common/constants'); -const GstoreHelper = require('../../common/utils/gstore-helper'); -const DatabusUtils = require('../../../../public/js/utils/databus-utils'); -var shaclTester = require('../../common/shacl-tester'); -var jsonld = require('jsonld'); -var constructor = require('../../common/execute-construct.js'); -var constructGroupQuery = require('../../common/queries/constructs/construct-group.sparql'); -var autocompleter = require('./dataid-autocomplete'); -const DatabusMessage = require('../../common/databus-message'); - -module.exports = async function publishGroup(accountName, graph, logger) { - - try { - - var groupUri = graph[DatabusUris.JSONLD_ID]; - logger.debug(groupUri, `Processing group <${groupUri}>`, graph); - - // Check for namespace violation - if (!groupUri.startsWith(process.env.DATABUS_RESOURCE_BASE_URL)) { - logger.error(groupUri, `Group identifier does not start with the resource base url of this Databus (${process.env.DATABUS_RESOURCE_BASE_URL})`); - return 403; - } - - // Check for namespace violation - var expectedUriPrefix = `${process.env.DATABUS_RESOURCE_BASE_URL}/${accountName}/`; - if (!groupUri.startsWith(expectedUriPrefix)) { - logger.error(groupUri, `Not allowed to access namespace of group identifier <${groupUri}>.`); - return 403; - } - - var groupName = UriUtils.cleanSegment(groupUri.replace(expectedUriPrefix, "")); - - if (UriUtils.getPathLength(groupName) != 1) { - logger.error(groupUri, `Group uri <${groupUri}> must have exactly 2 path segments relative to the Databus base url <${process.env.DATABUS_RESOURCE_BASE_URL}> (found ${UriUtils.getPathLength(groupName) + 1})`, null); - return 400; - } - - if (groupName == Constants.DATABUS_COLLECTIONS_GROUP_IDENTIFIER) { - logger.error(groupUri, `Cannot create group with name "${Constants.DATABUS_COLLECTIONS_GROUP_IDENTIFIER}" as it is reserved for Databus collections.`); - return 400; - } - - // Get the desired triples from the data via construct query - var triples = await constructor.executeConstruct(graph, constructGroupQuery); - var tripleCount = DatabusUtils.lineCount(triples); - - if (tripleCount == 0) { - logger.info(groupUri, `Construct query did not yield any triples. Nothing to publish.`, graph); - return 200; - } - - logger.debug(groupUri, `${tripleCount} triples selected via construct query.`, triples); - var expandedGraphs = await jsonld.flatten(await jsonld.fromRDF(triples)); - - // Auto-complete - autocompleter.autocompleteGroup(expandedGraphs); - logger.debug(groupUri, `Input has been processed by the auto-completer`, expandedGraphs); - - - // Validate the group RDF with the shacl validation tool - var shaclResult = await shaclTester.validateGroupRDF(expandedGraphs); - - // Return failure with SHACL validation message - if (!shaclResult.isSuccess) { - logger.error(groupUri, `SHACL validation error`, shaclResult); - return 400; - } - - logger.debug(groupUri, `SHACL validation successful`, shaclResult); - - - // Compact graph, determine target path - var compactedGraph = await jsonld.compact(expandedGraphs, process.env.DATABUS_CONTEXT_URL); - logger.debug(groupUri, `Compacted with context <${process.env.DATABUS_CONTEXT_URL}>`); - //if(process.env.DATABUS_CONTEXT_URL != null) { - // compactedGraph[DatabusUris.JSONLD_CONTEXT] = process.env.DATABUS_CONTEXT_URL; - - // } - - var targetPath = `${groupName}/${Constants.DATABUS_FILE_GROUP}`; - logger.debug(groupUri, `Saving group <${groupUri}> to ${accountName}:${targetPath}`, compactedGraph); - - - // Save the RDF with the current path using the database manager - var publishResult = await GstoreHelper.save(accountName, targetPath, compactedGraph); - - // Return failure - if (!publishResult.isSuccess) { - logger.error(groupUri, `Internal database error`, null); - return 500; - } - - if(process.send != undefined) { - process.send({ - id: DatabusMessage.REQUEST_SEARCH_INDEX_REBUILD, - resource: groupUri - }); - } - - logger.info(groupUri, `Successfully published group <${groupUri}>.`, compactedGraph); - return 200; - - } catch (err) { - console.log(`Unexpected Databus error when processing group data`); - console.log(err); - logger.error(null, `Unexpected Databus error when processing group data`, null); - return 500; - } -} diff --git a/server/app/api/lib/resource-writer.js b/server/app/api/lib/resource-writer.js index 03d67459..eac8d830 100644 --- a/server/app/api/lib/resource-writer.js +++ b/server/app/api/lib/resource-writer.js @@ -1,83 +1,88 @@ - + const DatabusUtils = require('../../../../public/js/utils/databus-utils'); const DatabusMessage = require('../../common/databus-message'); const ApiError = require('../../common/utils/api-error'); -const DatabusResource = require('./databus-resource'); const GstoreResource = require('./gstore-resource'); const shaclTester = require('../../common/shacl-tester'); const jsonld = require('jsonld'); +const JsonldLoader = require('../../common/utils/jsonld-loader'); +const DatabusResource = require('../../common/databus-resource'); + +class ResourceWriter { + + constructor(logger) { + this.logger = logger; + } + + async writeResource(userData, inputGraphs, uri) { + this.userData = userData; + this.inputGraphs = inputGraphs; - class ResourceWriter { + this.resource = new DatabusResource(uri); + this.uri = uri; - constructor(logger) { - this.logger = logger; + var baseURL = process.env.DATABUS_RESOURCE_BASE_URL; + + this.logger.debug(`Processing resource <${uri}}>"...`); + + if (!uri.startsWith(baseURL)) { + let message = `Identifier <${uri}> does not start with the resource base url <${baseURL}> of this Databus.`; + throw new ApiError(400, uri, message, null); } - async writeResource(userData, inputGraphs, uri) { - this.userData = userData; - this.inputGraphs = inputGraphs; - - this.resource = new DatabusResource(uri); - this.uri = uri; - - var baseURL = process.env.DATABUS_RESOURCE_BASE_URL; - - this.logger.debug(`Processing resource <${uri}}>"...`); - - if (!uri.startsWith(baseURL)) { - throw new ApiError(`Identifier <${uri}> does not start with the resource base url <${baseURL}> of this Databus.`, 400); - } - - await this.onValidateUser(); - - - var graphs = await this.onCreateGraphs(); - - var shaclResult = await shaclTester.validateJsonld(graphs, this.getSHACLFilePath()); - - if (!shaclResult.isSuccess) { - var response = 'SHACL validation error:\n'; - for (var m in shaclResult.messages) { - response += `>>> ${shaclResult.messages[m]}\n` - } - - throw new ApiError(response, 400); - } - - var compactedGraph = await jsonld.compact(graphs, process.env.DATABUS_CONTEXT_URL); - this.logger.debug(this.uri, `Compacted with context <${process.env.DATABUS_CONTEXT_URL}>`); - - try { - this.logger.debug(this.uri, `Saving to gstore.`); - var gstoreResource = new GstoreResource(this.uri, compactedGraph); - await gstoreResource.save(); - } catch(err) { - throw new ApiError(err.message, 400); - } - - if(process.send != undefined) { - process.send({ - id: DatabusMessage.REQUEST_SEARCH_INDEX_REBUILD, - resource: this.uri - }); - } - + await this.onValidateUser(); + + var graphs = await this.onCreateGraphs(); + + var shaclResult = await shaclTester.validateJsonld(graphs, this.getSHACLFilePath()); + + if (!shaclResult.isSuccess) { + var message = 'SHACL validation error:\n'; + for (var m in shaclResult.messages) { + message += `>>> ${shaclResult.messages[m]}\n` + } + + throw new ApiError(400, this.uri, message, shaclResult.report); } - getSHACLFilePath() { - return ''; + var compactedGraph = await jsonld.compact(graphs, JsonldLoader.DEFAULT_CONTEXT_URL); + this.logger.debug(this.uri, `Compacted with context <${JsonldLoader.DEFAULT_CONTEXT_URL}>`); + + try { + this.logger.debug(this.uri, `Saving to gstore.`); + var gstoreResource = new GstoreResource(this.uri, compactedGraph); + await gstoreResource.save(); + + this.logger.info(this.uri, `Successfully published ${this.resource.getTypeName()} <${this.uri}>.`, compactedGraph); + } catch (err) { + let message = `Failed to save to gstore: ${err.message}`; + throw new ApiError(500, this.uri, message, compactedGraph); } - async onValidateUser() { - var namespacePrefix = `${process.env.DATABUS_RESOURCE_BASE_URL}/${this.userData.accountName}/`; - if (!`${this.uri}/`.startsWith(namespacePrefix)) { - throw new ApiError(`Identifier <${this.uri}> does not start with the expected namespace prefix <${namespacePrefix}>.`, 403); - } + if (process.send != undefined) { + process.send({ + id: DatabusMessage.REQUEST_SEARCH_INDEX_REBUILD, + resource: this.uri + }); } - async onCreateGraphs() { - return []; + } + + getSHACLFilePath() { + return ''; + } + + async onValidateUser() { + var namespacePrefix = `${process.env.DATABUS_RESOURCE_BASE_URL}/${this.userData.accountName}/`; + if (!`${this.uri}/`.startsWith(namespacePrefix)) { + let message = `Identifier <${this.uri}> does not start with the expected namespace prefix <${namespacePrefix}>.`; + throw new ApiError(403, this.uri, message, null); } - } + } + + async onCreateGraphs() { + return []; + } +} module.exports = ResourceWriter; \ No newline at end of file diff --git a/server/app/api/routes/artifact.js b/server/app/api/routes/artifact.js index c68aa82f..f6bccdcc 100644 --- a/server/app/api/routes/artifact.js +++ b/server/app/api/routes/artifact.js @@ -1,17 +1,13 @@ const ServerUtils = require("../../common/utils/server-utils"); -const DatabusUris = require("../../../../public/js/utils/databus-uris"); const Constants = require("../../common/constants"); const GstoreHelper = require('../../common/utils/gstore-helper'); const JsonldUtils = require("../../../../public/js/utils/jsonld-utils"); const DatabusLogger = require("../../common/databus-logger"); const UriUtils = require("../../common/utils/uri-utils"); - -const publishArtifact = require('../lib/publish-artifact'); -const defaultContext = require('../../common/res/context.jsonld'); const getLinkedData = require("../../common/get-linked-data"); +const ArtifactWriter = require("../lib/artifact-writer"); const jsonld = require('jsonld'); var cors = require('cors'); - const sparql = require("../../common/queries/sparql"); module.exports = function (router, protector) { @@ -30,20 +26,9 @@ module.exports = function (router, protector) { ]); - // Requesting a PUT on an uri outside of one's namespace is rejected - if (req.params.account != req.databus.accountName) { - res.status(403).send(MESSAGE_WRONG_NAMESPACE); - return; - } - var logger = new DatabusLogger(req.query['log-level']); var graph = req.body; - if (graph[DatabusUris.JSONLD_CONTEXT] == process.env.DATABUS_DEFAULT_CONTEXT_URL) { - graph[DatabusUris.JSONLD_CONTEXT] = defaultContext; - logger.debug(null, `Context "${graph[DatabusUris.JSONLD_CONTEXT]}" replaced with cached resolved context`, defaultContext); - } - // Expand JSONLD! var expandedGraph = await jsonld.flatten(graph); @@ -56,10 +41,15 @@ module.exports = function (router, protector) { return; } - logger.debug(null, `Found graph ${artifactUri} in the input.`, artifactGraph); - - var code = await publishArtifact(req.params.account, artifactGraph, logger); - res.status(code).json(logger.getReport()); + try { + var artifactWriter = new ArtifactWriter(logger); + await artifactWriter.writeResource(req.databus, expandedGraph, artifactUri); + } + catch (apiError) { + logger.error(apiError.resource, apiError.message, apiError.body); + res.status(apiError.statusCode).json(logger.getReport()); + return; + } } catch (err) { console.log(err); diff --git a/server/app/api/routes/general.js b/server/app/api/routes/general.js index a84331ef..9deace95 100644 --- a/server/app/api/routes/general.js +++ b/server/app/api/routes/general.js @@ -3,12 +3,12 @@ var request = require('request'); const jsonld = require('jsonld'); var cors = require('cors'); const publishVersion = require('../lib/publish-version'); -const publishArtifact = require('../lib/publish-artifact'); const JsonldUtils = require('../../../../public/js/utils/jsonld-utils'); const DatabusUris = require('../../../../public/js/utils/databus-uris'); const DatabusLogger = require('../../common/databus-logger'); const AccountWriter = require('../lib/account-writer'); const GroupWriter = require('../lib/group-writer'); +const ArtifactWriter = require('../lib/artifact-writer'); var SparqlParser = require('sparqljs').Parser; const ALLOWED_QUERY_TYPES = [ @@ -123,38 +123,43 @@ module.exports = function (router, protector, webdav) { var processedResources = 0; var expandedGraphs = await jsonld.flatten(req.body); - var accountGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_ACCOUNT); + try { + var accountGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_ACCOUNT); - for (var accountGraph of accountGraphs) { - processedResources++; - var accountWriter = new AccountWriter(createUser, logger); - await accountWriter.writeResource(userData, expandedGraphs, accountGraph[DatabusUris.JSONLD_ID]); - } + for (var accountGraph of accountGraphs) { + processedResources++; - // Publish groups - var groupGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_GROUP); - logger.debug(null, `Found ${groupGraphs.length} group graphs.`, null); + var accountWriter = new AccountWriter(createUser, logger); + await accountWriter.writeResource(userData, expandedGraphs, accountGraph[DatabusUris.JSONLD_ID]); + } - for (var groupGraph of groupGraphs) { - processedResources++; - - var groupWriter = new GroupWriter(logger); - await groupWriter.writeResource(userData, expandedGraphs, groupGraph[DatabusUris.JSONLD_ID]); - } + // Publish groups + var groupGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_GROUP); + logger.debug(null, `Found ${groupGraphs.length} group graphs.`, null); - // Publish artifacts - var artifactGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_ARTIFACT); - logger.debug(null, `Found ${artifactGraphs.length} artifact graphs.`, null); - processedResources += artifactGraphs.length; + for (var groupGraph of groupGraphs) { + processedResources++; + + var groupWriter = new GroupWriter(logger); + await groupWriter.writeResource(userData, expandedGraphs, groupGraph[DatabusUris.JSONLD_ID]); + } - for (var artifactGraph of artifactGraphs) { - var resultCode = await publishArtifact(accountName, artifactGraph, logger); + // Publish artifacts + var artifactGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_ARTIFACT); + logger.debug(null, `Found ${artifactGraphs.length} artifact graphs.`, null); - if (resultCode != 200) { - res.status(resultCode).json(logger.getReport()); - return; + for (var artifactGraph of artifactGraphs) { + processedResources++; + + var artifactWriter = new ArtifactWriter(logger); + await artifactWriter.writeResource(userData, expandedGraphs, artifactGraph[DatabusUris.JSONLD_ID]); } } + catch(apiError) { + logger.error(apiError.resource, apiError.message, apiError.body); + res.status(apiError.statusCode).json(logger.getReport()); + return; + } // Publish versions var datasetGraphs = JsonldUtils.getTypedGraphs(expandedGraphs, DatabusUris.DATABUS_VERSION); diff --git a/server/app/api/routes/group.js b/server/app/api/routes/group.js index 93f963f8..64674603 100644 --- a/server/app/api/routes/group.js +++ b/server/app/api/routes/group.js @@ -5,13 +5,12 @@ const GstoreHelper = require('../../common/utils/gstore-helper'); const JsonldUtils = require("../../../../public/js/utils/jsonld-utils"); const DatabusLogger = require("../../common/databus-logger"); const UriUtils = require("../../common/utils/uri-utils"); -const publishGroup = require('../lib/publish-group'); const jsonld = require('jsonld'); const getLinkedData = require("../../common/get-linked-data"); -const defaultContext = require('../../common/res/context.jsonld'); var cors = require('cors'); const sparql = require("../../common/queries/sparql"); +const GroupWriter = require("../lib/group-writer"); module.exports = function (router, protector) { @@ -31,26 +30,24 @@ module.exports = function (router, protector) { var logger = new DatabusLogger(req.query['log-level']); var graph = req.body; - if (graph[DatabusUris.JSONLD_CONTEXT] == process.env.DATABUS_DEFAULT_CONTEXT_URL) { - graph[DatabusUris.JSONLD_CONTEXT] = defaultContext; - logger.debug(null, `Context "${graph[DatabusUris.JSONLD_CONTEXT]}" replaced with cached resolved context`, defaultContext); - } - - var expandedGraph = await jsonld.flatten(graph); - - // Publish groups + let expandedGraph = await jsonld.expand(graph); var groupGraph = JsonldUtils.getGraphById(expandedGraph, groupUri); - + if (groupGraph == null) { logger.error(null, `No graph ${groupUri} found in the input.`, null); res.status(400).json(logger.getReport()); return; } - logger.debug(null, `Found graph ${groupUri} in the input.`, groupGraph); - - var code = await publishGroup(req.params.account, groupGraph, logger); - res.status(code).json(logger.getReport()); + try { + var groupWriter = new GroupWriter(logger); + await groupWriter.writeResource(req.databus, expandedGraph, groupUri); + } + catch (apiError) { + logger.error(apiError.resource, apiError.message, apiError.body); + res.status(apiError.statusCode).json(logger.getReport()); + return; + } } catch (err) { console.log(err); diff --git a/server/app/app.js b/server/app/app.js index 54072f67..95e4edde 100644 --- a/server/app/app.js +++ b/server/app/app.js @@ -20,6 +20,7 @@ const Constants = require("./common/constants"); const defaultContext = require("./common/res/context.jsonld"); const jsonld = require('jsonld'); const axios = require('axios'); +const JsonldLoader = require("./common/utils/jsonld-loader"); // Creation of the mighty server app var app = express(); @@ -124,56 +125,14 @@ initialize(app, memoryStore).then(function () { }); - -function initializeJsonLd() { - // how to override the default document loader with a custom one -- for - // example, one that uses pre-loaded contexts: - var defaultContextUrl = `${process.env.DATABUS_RESOURCE_BASE_URL}${Constants.DATABUS_DEFAULT_CONTEXT_PATH}` - - // define a mapping of context URL => context doc - const CONTEXTS = {} - CONTEXTS[defaultContextUrl] = defaultContext; - - // change the default document loader - const customLoader = async (url, options) => { - - if(url in CONTEXTS) { - return { - contextUrl: null, - document: CONTEXTS[url], - documentUrl: url - }; - } - - try { - // Use axios to fetch the document - const response = await axios.get(url, { - headers: { Accept: 'application/ld+json, application/json' }, - responseType: 'json', - timeout: 5000, - }); - - return { - contextUrl: null, - document: response.data, - documentUrl: url - }; - } catch (error) { - throw new Error(`Failed to load document from ${url}: ${error.message}`); - } - }; - - jsonld.documentLoader = customLoader; -} - /** * Express app initialization * @param {the express app} app */ async function initialize(app, memoryStore) { - initializeJsonLd(); - + JsonldLoader.initialize(); + try { app.set('trust proxy', 'loopback'); app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' })); diff --git a/server/app/common/get-jsonld.js b/server/app/common/get-jsonld.js index ffd749c5..b7e59f52 100644 --- a/server/app/common/get-jsonld.js +++ b/server/app/common/get-jsonld.js @@ -1,10 +1,10 @@ -const defaultContext = require('./res/context.jsonld'); const axios = require('axios'); const jsonld = require('jsonld'); const exec = require('./execute-query'); const ServerUtils = require('./utils/server-utils'); const DatabusUris = require('../../../public/js/utils/databus-uris'); const HttpStrings = require('./http-strings'); +const JsonldLoader = require('./utils/jsonld-loader'); module.exports = async function getJsonLd(resourceUri, template, formatting) { @@ -43,10 +43,7 @@ module.exports = async function getJsonLd(resourceUri, template, formatting) { // Format the result based on the requested formatting if (formatting === undefined || formatting === 'compacted' || formatting === 'compact') { // Compact the result with the Databus context - result = await jsonld.compact(result, defaultContext); - if (process.env.DATABUS_CONTEXT_URL !== undefined) { - result[DatabusUris.JSONLD_CONTEXT] = process.env.DATABUS_CONTEXT_URL; - } + result = await jsonld.compact(result, JsonldLoader.DEFAULT_CONTEXT_URL); } else if (formatting === 'flatten') { // Flatten the result result = await jsonld.flatten(result); diff --git a/server/app/common/request-rdf.js b/server/app/common/request-rdf.js index 81ce7cf6..d04c08a9 100644 --- a/server/app/common/request-rdf.js +++ b/server/app/common/request-rdf.js @@ -7,67 +7,67 @@ const Constants = require("./constants"); var requestRDF = {}; -requestRDF.parseRdf = async function(contentType, data) { - var buffer = streamify(data); - var quads = []; - return new Promise(function (resolve, reject) { - rdfParser.parse(buffer, { contentType: contentType }) - .on('data', (quad) => { quads.push(quad); }) - .on('error', (error) => reject(error)) - .on('end', () => resolve(quads)); - }); +requestRDF.parseRdf = async function (contentType, data) { + var buffer = streamify(data); + var quads = []; + return new Promise(function (resolve, reject) { + rdfParser.parse(buffer, { contentType: contentType }) + .on('data', (quad) => { quads.push(quad); }) + .on('error', (error) => reject(error)) + .on('end', () => resolve(quads)); + }); } -requestRDF.requestQuads = async function(uri) { - - // Do a POST request with the passed query - var options = { - method: 'GET', - uri: uri, - headers: { - "Accept": Constants.HTTP_ACCEPT_RDF - }, - transform: function (body, response, resolveWithFullResponse) { - return { 'headers': response.headers, 'data': body }; +requestRDF.requestQuads = async function (uri) { + + // Do a POST request with the passed query + var options = { + method: 'GET', + uri: uri, + headers: { + "Accept": Constants.HTTP_ACCEPT_RDF + }, + transform: function (body, response, resolveWithFullResponse) { + return { 'headers': response.headers, 'data': body }; + } + }; + + // Await the response + var response = await rp(options); + var contentType = response.headers['content-type'].split(' ')[0].split(';')[0]; + + if (contentType.startsWith(Constants.HTTP_CONTENT_TYPE_TEXT)) { + contentType = Constants.HTTP_CONTENT_TYPE_TURTLE; } - }; - // Await the response - var response = await rp(options); - var contentType = response.headers['content-type'].split(' ')[0].split(';')[0]; - - if (contentType.startsWith(Constants.HTTP_CONTENT_TYPE_TEXT)) { - contentType = Constants.HTTP_CONTENT_TYPE_TURTLE; - } - - if(contentType.startsWith(Constants.HTTP_CONTENT_TYPE_JSON)) { - contentType = Constants.HTTP_CONTENT_TYPE_JSONLD; - } + if (contentType.startsWith(Constants.HTTP_CONTENT_TYPE_JSON)) { + contentType = Constants.HTTP_CONTENT_TYPE_JSONLD; + } - console.log(`Content type ${contentType} detected. Parsing...`); - var quads = await requestRDF.parseRdf(contentType, response.data); + console.log(`Content type ${contentType} detected. Parsing...`); + var quads = await requestRDF.parseRdf(contentType, response.data); - return quads; + return quads; } -requestRDF.requestN3 = async function(uri) { - var quads = await requestRDF.requestQuads(uri); - var triples = []; +requestRDF.requestN3 = async function (uri) { + var quads = await requestRDF.requestQuads(uri); + var triples = []; - for(var quad of quads) { + for (var quad of quads) { - var subjectValue = `<${quad.subject.value}>`; - var predicateValue = `<${quad.predicate.value}>`; - var objectValue = `<${quad.object.value}>`; + var subjectValue = `<${quad.subject.value}>`; + var predicateValue = `<${quad.predicate.value}>`; + var objectValue = `<${quad.object.value}>`; - if (quad.object.termType == 'Literal') { - objectValue = `${quad.object.id}` - } + if (quad.object.termType == 'Literal') { + objectValue = `${quad.object.id}` + } - triples.push(`${subjectValue} ${predicateValue} ${objectValue} .`); - } + triples.push(`${subjectValue} ${predicateValue} ${objectValue} .`); + } - return triples; + return triples; } diff --git a/server/app/common/utils/api-error.js b/server/app/common/utils/api-error.js index b1bfddd2..68063e37 100644 --- a/server/app/common/utils/api-error.js +++ b/server/app/common/utils/api-error.js @@ -1,8 +1,10 @@ class ApiError extends Error { - constructor(message, statusCode) { + constructor(statusCode, resource, message, body) { super(message); this.name = "ApiError"; this.statusCode = statusCode; + this.resource = resource; + this.body = body; } } diff --git a/server/app/common/utils/jsonld-loader.js b/server/app/common/utils/jsonld-loader.js new file mode 100644 index 00000000..bc69b855 --- /dev/null +++ b/server/app/common/utils/jsonld-loader.js @@ -0,0 +1,52 @@ + +const Constants = require('../constants'); +const axios = require('axios'); +const jsonld = require('jsonld'); +const defaultContext = require('../../common/res/context.jsonld'); + +class JsonldLoader { + + static DEFAULT_CONTEXT_URL; + + static initialize() { + + JsonldLoader.DEFAULT_CONTEXT_URL = `${process.env.DATABUS_RESOURCE_BASE_URL}${Constants.DATABUS_DEFAULT_CONTEXT_PATH}` + + // define a mapping of context URL => context doc + const CONTEXTS = {} + CONTEXTS[JsonldLoader.DEFAULT_CONTEXT_URL] = defaultContext; + + // change the default document loader + const customLoader = async (url, options) => { + + if (url in CONTEXTS) { + return { + contextUrl: null, + document: CONTEXTS[url], + documentUrl: url + }; + } + + try { + // Use axios to fetch the document + const response = await axios.get(url, { + headers: { Accept: [ Constants.HTTP_CONTENT_TYPE_JSONLD, Constants.HTTP_CONTENT_TYPE_JSON ]}, + responseType: 'json', + timeout: 5000, + }); + + return { + contextUrl: null, + document: response.data, + documentUrl: url + }; + } catch (error) { + throw new Error(`Failed to load document from ${url}: ${error.message}`); + } + }; + + jsonld.documentLoader = customLoader; + } +} + +module.exports = JsonldLoader; \ No newline at end of file diff --git a/server/app/common/utils/server-utils.js b/server/app/common/utils/server-utils.js index c8f3d0df..32c2358a 100644 --- a/server/app/common/utils/server-utils.js +++ b/server/app/common/utils/server-utils.js @@ -2,7 +2,7 @@ var ASN1 = require('asn1js'); class ServerUtils { - + static getRSAModulusAndExponent(pubkey) { var unarmor = /-----BEGIN PUBLIC KEY-----([A-Za-z0-9+\/=\s]+)-----END PUBLIC KEY-----/; @@ -98,7 +98,7 @@ class ServerUtils { var result = {}; result.authenticated = false; - if(req.databus != undefined) { + if (req.databus != undefined) { result.authenticated = req.databus.authenticated; //.isAuthenticated(); } @@ -147,11 +147,11 @@ class ServerUtils { static NOT_HTML_ACCEPTED(req, res, next) { var acceptHeader = req.get('Accept'); - if(acceptHeader == undefined) { + if (acceptHeader == undefined) { return next(); } - if(acceptHeader.includes('html')) { + if (acceptHeader.includes('html')) { return next("route"); } @@ -161,7 +161,7 @@ class ServerUtils { static HTML_ACCEPTED(req, res, next) { var acceptHeader = req.get('Accept'); - if(acceptHeader == undefined) { + if (acceptHeader == undefined) { return next("route"); } @@ -188,5 +188,4 @@ class ServerUtils { } } - module.exports = ServerUtils diff --git a/server/config.json b/server/config.json index 2b0d76ec..6b295f6a 100644 --- a/server/config.json +++ b/server/config.json @@ -1,5 +1,5 @@ { - "version" : "2.1.0-rc.11", + "version" : "2.1.0-rc.12", "defaultColors": { "banner": "#81b8b2" } diff --git a/server/init.js b/server/init.js index 64c64e77..7ef45367 100644 --- a/server/init.js +++ b/server/init.js @@ -11,6 +11,10 @@ const { executeAsk } = require('./app/common/execute-query.js'); const AppJsonFormatter = require('../public/js/utils/app-json-formatter.js'); const MetricsManager = require('./app/api/statistics/metrics-manager.js'); var defaultContext = require('./app/common/res/context.jsonld'); +const AccountWriter = require('./app/api/lib/account-writer.js'); +const DatabusLogger = require('./app/common/databus-logger.js'); +const DatabusLogLevel = require('./app/common/databus-log-level.js'); +const JsonldLoader = require('./app/common/utils/jsonld-loader.js'); function writeManifest() { @@ -84,7 +88,7 @@ async function initializeShacl() { 'account', 'artifact', 'collection', 'version', 'group' ]; - for(var file of shaclFiles) { + for (var file of shaclFiles) { var shacl = require(`../model/generated/shacl/${file}.shacl`); var shaclFile = `${__dirname}/app/common/res/shacl/${file}.shacl`; @@ -96,7 +100,7 @@ async function initializeShacl() { async function initializeContext() { var defaultContextUrl = `${process.env.DATABUS_RESOURCE_BASE_URL}${Constants.DATABUS_DEFAULT_CONTEXT_PATH}` - + console.log(`Using self-hosted jsonld context at ${defaultContextUrl}...`); process.env.DATABUS_CONTEXT_URL = defaultContextUrl; @@ -157,48 +161,64 @@ async function initializeContext() { } -async function initializeUserDatabase() { +async function initializeUserDatabase(indexer) { + + console.log(`Connecting to User Databse...`); var userDatabase = new DatabusUserDatabase(); await userDatabase.connect(); console.log(`Verifying user account integrity`); - for(var user of await userDatabase.getUsers()) { + for (var user of await userDatabase.getUsers()) { var profileUri = `${UriUtils.createResourceUri([user.accountName])}${DatabusConstants.WEBID_DOCUMENT}`; var exists = await executeAsk(`ASK { <${profileUri}> ?p ?o }`); if (!exists) { // Redirect to the specific account page console.log(`No profile found for user ${user.accountName}. Creating profile...`); - + + var userData = { + accountName: user.accountName, + sub: user.sub + }; + + + var accountUri = `${process.env.DATABUS_RESOURCE_BASE_URL}/${user.accountName}`; + var accountJsonLd = AppJsonFormatter.createAccountData( - process.env.DATABUS_RESOURCE_BASE_URL, + accountUri, user.accountName, - user.accountName, - null, + null, null); + + var accountWriter = new AccountWriter(null, new DatabusLogger(DatabusLogLevel.ERROR)); + await accountWriter.writeResource(userData, accountJsonLd, accountUri); // await publishAccount(user.accountName, accountJsonLd); + indexer.updateResource(accountWriter.uri, accountWriter.resource.getTypeName()); console.log(`Created new default profile for user ${user.accountName}`); - } + } } } -module.exports = async function () { +module.exports = async function (indexer) { console.log(`Initializing...`); console.log(config); - if(process.env.METRICS_PORT != undefined) { + if (process.env.METRICS_PORT != undefined) { console.log(`Settings up Prometheus metrics...`); MetricsManager.initialize(); } - await initializeUserDatabase(); + + JsonldLoader.initialize(); + + await initializeUserDatabase(indexer); // await initializeShacl(); await initializeContext(); diff --git a/server/www b/server/www index aa87c5e7..6c6945b5 100755 --- a/server/www +++ b/server/www @@ -78,13 +78,23 @@ async function masterProcess() { console.log(`Environment Variables:`); console.log(`------------------------------------------------`); console.log(`DATABUS_RESOURCE_BASE_URL\t${process.env.DATABUS_RESOURCE_BASE_URL}`); + console.log(`DATABUS_DATABASE_URL\t\t${process.env.DATABUS_DATABASE_URL}`); console.log(`DATABUS_NAME\t\t\t${process.env.DATABUS_NAME}`); console.log(`DATABUS_ORG_ICON\t\t${process.env.DATABUS_ORG_ICON}`); console.log(`DATABUS_BANNER_COLOR\t\t${process.env.DATABUS_BANNER_COLOR}`); + console.log(`METRICS_PORT\t\t\t${process.env.METRICS_PORT}`); console.log(``); console.log(`================================================`); console.log(``); + if(process.env.DATABUS_RESOURCE_BASE_URL == null) { + console.log(`Environment variable DATABUS_RESOURCE_BASE_URL not set. Exiting.`); + } + + if(process.env.DATABUS_DATABASE_URL == null) { + console.log(`Environment variable DATABUS_DATABASE_URL not set. Exiting.`); + } + try { console.log(`Starting search service...`) @@ -101,7 +111,7 @@ async function masterProcess() { console.log(``); console.log(`================================================`); console.log(``); - await initialize(); + await initialize(searchIndexer); // TODO: Validate startup environment variables console.log(`Number of CPUs is ${numCPUs}`);