2024-02-05 11:07:34 +01:00
const axios = require ( 'axios' ) ;
2016-09-09 09:59:26 +02:00
var express = require ( "express" ) ;
var bodyParser = require ( "body-parser" ) ;
2019-06-06 11:31:03 +02:00
var cookieParser = require ( 'cookie-parser' ) ;
2016-09-09 09:59:26 +02:00
var multer = require ( "multer" ) ;
2019-06-06 11:31:03 +02:00
var PropertiesReader = require ( 'properties-reader' ) ;
var properties = PropertiesReader ( './properties.file' ) ;
2016-09-09 09:59:26 +02:00
var app = express ( ) ;
2019-06-06 11:31:03 +02:00
var http = null ;
2021-11-25 17:53:59 +01:00
// Properties
2020-09-28 23:32:09 +02:00
if ( properties . get ( 'ssl' ) ) {
2019-06-28 11:28:25 +02:00
http = require ( "https" ) ;
2019-06-06 11:31:03 +02:00
} else {
http = require ( "http" ) ;
}
2024-02-05 11:07:34 +01:00
var searchServiceAPIUrl = properties . get ( 'searchServiceAPIUrl' ) ;
2019-06-06 11:31:03 +02:00
var auth = properties . get ( 'userInfoUrl' ) ;
2021-11-25 17:53:59 +01:00
/** @deprecated*/
var authDeprecated = auth . includes ( "accessToken" ) ;
2019-06-21 13:11:50 +02:00
var localPath = properties . get ( 'localPath' ) ;
2021-11-25 17:53:59 +01:00
var maxSize = properties . get ( 'max.size' ) * 1024 ;
var bigMaxSize = properties . get ( 'big-max.size' ) * 1024 ;
2019-06-06 11:31:03 +02:00
var storage = multer . diskStorage ( {
destination : function ( req , file , cb ) {
cb ( null , 'uploads' )
} ,
filename : function ( req , file , cb ) {
2020-09-28 23:32:09 +02:00
if ( req . params . id ) {
2021-11-26 10:50:01 +01:00
cb ( null , req . params . id + ( req . params . label ? ( '-' + req . params . label ) : '' ) +
2021-11-25 17:53:59 +01:00
'-' + new Date ( ) . getTime ( ) + '.' + file . originalname . split ( '.' ) . pop ( ) ) ;
2019-06-06 11:31:03 +02:00
} else {
cb ( null , file . originalname ) ;
}
}
} ) ;
2020-09-28 23:32:09 +02:00
var upload = multer ( { storage : storage } )
2016-09-09 09:59:26 +02:00
app . use ( bodyParser . json ( ) ) ;
2019-06-06 11:31:03 +02:00
app . use ( bodyParser . urlencoded ( { extended : true } ) ) ;
app . use ( cookieParser ( ) ) ;
app . use ( function ( req , res , next ) {
2021-11-25 17:53:59 +01:00
res . header ( 'Access-Control-Allow-Origin' , req . headers . origin ) ;
res . header ( 'Access-Control-Allow-Headers' , 'Origin, X-Requested-With, Content-Type, Accept, x-xsrf-token' ) ;
2021-11-26 10:50:01 +01:00
res . header ( 'Access-Control-Allow-Credentials' , "true" ) ;
2021-11-25 17:53:59 +01:00
res . header ( 'Access-Control-Allow-Methods' , 'GET, OPTIONS, POST, DELETE' ) ;
2021-11-26 10:50:01 +01:00
res . header ( 'Access-Control-Max-Age' , "1800" ) ;
2021-11-25 17:53:59 +01:00
next ( ) ;
} ) ;
app . get ( '/download/:filename' , function ( req , res ) {
res . download ( './uploads/' + req . params . filename ) ;
2019-06-06 11:31:03 +02:00
} ) ;
app . post ( "/upload" , upload . array ( "uploads[]" , 12 ) , function ( req , res ) {
2020-09-28 23:32:09 +02:00
var filepath = ( localPath ? "." : _ _dirname ) + "/" + req . files [ 0 ] . path ;
2019-12-13 10:35:51 +01:00
let type = req . query . type ;
2021-11-25 17:53:59 +01:00
if ( type === 'json' && req . files [ 0 ] . mimetype !== 'application/json' ) {
console . error ( "No proper file type" ) ;
2019-12-13 10:35:51 +01:00
res . status ( 500 ) . send ( getResponse ( 500 , "No proper file type" ) ) ;
2021-11-25 17:53:59 +01:00
} else if ( ( ! type || type === 'csv' ) && req . files [ 0 ] . mimetype !== 'text/csv' && req . files [ 0 ] . mimetype !== 'application/vnd.ms-excel' ) {
2019-06-06 11:31:03 +02:00
console . error ( "No proper file type" ) ;
res . status ( 500 ) . send ( getResponse ( 500 , "No proper file type" ) ) ;
} else {
res . download ( filepath ) ;
2020-09-28 23:32:09 +02:00
setTimeout ( function ( ) {
deleteFile ( filepath ) ;
} , 3000 ) ;
2019-07-24 14:49:32 +02:00
// deleteFile(filepath);
2019-06-06 11:31:03 +02:00
}
} ) ;
2021-11-26 10:50:01 +01:00
app . post ( [ '/upload/:id' , '/upload/stakeholder/:id' , '/upload/:type/:id' , '/upload/:type/:id/:label' ] , upload . single ( 'photo' ) , ( req , res ) => {
2021-11-25 17:53:59 +01:00
let fileMaxSize = ( req . query . big ) ? bigMaxSize : maxSize
sendFile ( req , res , fileMaxSize , ( result ) => {
let type = req . params [ 'type' ] ;
let id = req . params [ 'id' ] ;
let roles = result . roles ;
if ( type ) {
return isPortalAdmin ( roles ) || isCurator ( type , roles ) || isManager ( type , id , roles ) ;
2019-06-27 15:44:54 +02:00
} else {
2021-11-25 17:53:59 +01:00
return result . sub . indexOf ( id ) !== - 1 || isPortalAdmin ( roles ) || isAnyCurator ( roles ) ;
2019-06-27 15:44:54 +02:00
}
2019-06-06 12:06:50 +02:00
} ) ;
} ) ;
2021-11-25 17:53:59 +01:00
app . delete ( [ '/delete/:filename' , '/delete/stakeholder/:filename' , '/delete/:type/:id/:filename' ] , function ( req , res ) {
2020-09-28 23:41:23 +02:00
deleteFileSend ( req , res , ( result ) => {
2021-11-25 17:53:59 +01:00
let roles = result . roles ;
let type = req . params [ 'type' ] ;
let id = req . params [ 'id' ] ;
if ( type && id ) {
return isPortalAdmin ( roles ) || isCurator ( type , roles ) || isManager ( type , id , roles ) ;
} else {
return result . sub . indexOf ( req . params . filename . split ( '-' ) [ 0 ] ) !== - 1 || isPortalAdmin ( roles ) || isAnyCurator ( roles ) ;
}
} ) ;
2020-09-28 23:41:23 +02:00
} ) ;
2024-02-05 11:07:34 +01:00
app . get ( '/explore/home' , async function ( req , res ) {
try {
// Make requests to multiple APIs
const publicationsRES = await axios . get ( searchServiceAPIUrl + 'publications/count?format=json' ) ;
const datasetsRES = await axios . get ( searchServiceAPIUrl + 'datasets/count?format=json' ) ;
const softwareRES = await axios . get ( searchServiceAPIUrl + 'software/count?format=json' ) ;
const otherRES = await axios . get ( searchServiceAPIUrl + 'other/count?format=json' ) ;
const resultRES = await axios . get ( searchServiceAPIUrl + 'results/?fields=relfunder&sf=relfunder&format=json&size=0' ) ;
const datasourcesRES = await axios . get ( searchServiceAPIUrl + 'datasources/count?format=json' ) ;
const organizationsRES = await axios . get ( searchServiceAPIUrl + 'resources2/?format=json&size=0&type=organizations&fq=(reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or reldatasourcecompatibilityid exact openaire2.0 or reldatasourcecompatibilityid exact openaire3.0 or reldatasourcecompatibilityid exact openaire4.0 or reldatasourcecompatibilityid exact openaire-cris_1.1 or reldatasourcecompatibilityid exact openaire2.0_data or reldatasourcecompatibilityid exact hostedBy or relproject=*)' ) ;
const projectsRES = await axios . get ( searchServiceAPIUrl + 'projects/?fields=funder&sf=funder&format=json&size=0' ) ;
const datasetsInterlinkedRES = await axios . get ( searchServiceAPIUrl + 'resources?query=(%20(oaftype%20exact%20result)%20and%20(resulttypeid%20exact%20dataset)%20and%20(relresulttype%3Dpublication)%20%20)&page=0&size=0&format=json' ) ;
const softwareInterlinkedRES = await axios . get ( searchServiceAPIUrl + 'resources?query=(%20(oaftype%20exact%20result)%20and%20(resulttypeid%20exact%20software)%20and%20(relresulttype%3Dpublication)%20%20)&page=0&size=0&format=json' ) ;
// Combine the data
const aggregatedData = {
publications : publicationsRES . data . total ,
datasets : datasetsRES . data . total ,
software : softwareRES . data . total ,
other : otherRES . data . total ,
results : resultRES . data . meta . total ,
/*resultFunders:resultRES.data.refineResults.relfunder.length,*/
datasources : datasourcesRES . data . total ,
organizations : organizationsRES . data . meta . total ? organizationsRES . data . meta . total : '--' ,
projects : projectsRES . data . meta . total ,
/*projectFunders:projectsRES.data.refineResults.funder.length,*/
funders : parseNoOfFunders ( resultRES , projectsRES ) ,
datasetsInterlinked : datasetsInterlinkedRES . data . meta . total ,
softwareInterlinked : softwareInterlinkedRES . data . meta . total ,
} ;
// Send the aggregated data as the response
res . json ( aggregatedData ) ;
} catch ( error ) {
console . error ( 'Error fetching data:' , error . message ) ;
res . status ( 500 ) . send ( 'Internal Server Error' ) ;
}
} ) ;
app . get ( '/explore/search' , async function ( req , res ) {
try {
// Make requests to multiple APIs
const resultRES = await axios . get ( searchServiceAPIUrl + 'resources2/?format=json&size=0&type=results&fq=resultbestaccessright%20exact%20%22Open%20Access%22' ) ;
const datasourcesRES = await axios . get ( searchServiceAPIUrl + 'datasources/count?format=json' ) ;
const organizationsRES = await axios . get ( searchServiceAPIUrl + 'resources2/?format=json&size=0&type=organizations&fq=(reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or reldatasourcecompatibilityid exact openaire2.0 or reldatasourcecompatibilityid exact openaire3.0 or reldatasourcecompatibilityid exact openaire4.0 or reldatasourcecompatibilityid exact openaire-cris_1.1 or reldatasourcecompatibilityid exact openaire2.0_data or reldatasourcecompatibilityid exact hostedBy or relproject=*)' ) ;
const projectsRES = await axios . get ( searchServiceAPIUrl + 'projects/count?format=json' ) ;
// Combine the data
const aggregatedData = {
results : resultRES . data . meta . total ,
datasources : datasourcesRES . data . total ,
organizations : organizationsRES . data . meta . total ? organizationsRES . data . meta . total : '--' ,
projects : projectsRES . data . total
} ;
// Send the aggregated data as the response
res . json ( aggregatedData ) ;
} catch ( error ) {
console . error ( 'Error fetching data:' , error . message ) ;
res . status ( 500 ) . send ( 'Internal Server Error' ) ;
}
} ) ;
app . get ( '/grouped-requests' , async function ( req , res ) {
res . json ( [
"/explore/search" ,
"/explore/home"
] ) ;
} ) ;
function parseNoOfFunders ( resultRES , projectsRES ) {
// combines the refines qeries on funders field, the funders with results and the funders that have at least one project
let mergedFundersSet = new Set ( ) ;
let queriedFunders = resultRES . data . refineResults . relfunder ;
queriedFunders . forEach ( queriedFunder => {
if ( ! mergedFundersSet . has ( queriedFunder . id ) ) {
mergedFundersSet . add ( queriedFunder . id ) ;
}
} ) ;
queriedFunders = projectsRES . data . refineResults . funder ;
queriedFunders . forEach ( queriedFunder => {
if ( + queriedFunder . count > 1 ) {
if ( ! mergedFundersSet . has ( queriedFunder . id ) ) {
mergedFundersSet . add ( queriedFunder . id ) ;
}
}
} ) ;
return mergedFundersSet . size ;
}
2022-10-03 11:22:13 +02:00
const server = app . listen ( properties . get ( 'port' ) , function ( ) {
2020-09-28 23:41:23 +02:00
console . log ( "Listening on port %s..." , server . address ( ) . port ) ;
} ) ;
2021-11-25 17:53:59 +01:00
function sendFile ( req , res , size , authorized ) {
const cookie = ( authDeprecated ) ? req . cookies [ 'AccessToken' ] : req . cookies [ 'openAIRESession' ] ;
2020-09-28 23:41:23 +02:00
const file = req . file ;
var filepath = ( localPath ? "." : _ _dirname ) + "/" + file . path ;
2021-11-25 17:53:59 +01:00
if ( ! cookie ) {
2019-06-06 11:31:03 +02:00
res . status ( 401 ) . send ( getResponse ( 401 , "Unauthorized" ) ) ;
2020-09-28 23:41:23 +02:00
deleteFile ( filepath ) ;
} else if ( ! file || ( file . mimetype !== 'image/jpeg' && file . mimetype !== 'image/png' ) ) {
res . status ( 500 ) . send ( getResponse ( 500 , "No image file type" ) ) ;
deleteFile ( filepath ) ;
2021-11-25 17:53:59 +01:00
} else if ( file . size > size ) {
2020-09-28 23:41:23 +02:00
res . status ( 500 ) . send ( getResponse ( 500 , "Exceeds file size limit" ) ) ;
deleteFile ( filepath ) ;
2019-06-06 11:31:03 +02:00
} else {
2021-11-26 10:50:01 +01:00
getUserInfo ( authorized , req , res , ( ) => {
res . send ( file ) ;
2019-06-06 11:31:03 +02:00
} ) ;
}
2020-09-28 23:41:23 +02:00
}
2018-07-13 13:56:03 +02:00
2020-09-28 23:41:23 +02:00
function deleteFileSend ( req , res , authorized ) {
2021-11-25 17:53:59 +01:00
const cookie = ( authDeprecated ) ? req . cookies [ 'AccessToken' ] : req . cookies [ 'openAIRESession' ] ;
if ( ! cookie ) {
2020-09-28 23:32:09 +02:00
res . status ( 401 ) . send ( getResponse ( 401 , "Unauthorized" ) ) ;
} else {
2021-11-26 10:50:01 +01:00
getUserInfo ( authorized , req , res , ( ) => {
deleteFile ( './uploads/' + req . params . filename , res ) ;
} ) ;
}
}
function getUserInfo ( authorized , req , res , success ) {
let url = ( authDeprecated ) ? ( auth + cookie ) : auth ;
http . get ( url , { headers : { Cookie : req . header ( 'Cookie' ) } } , function ( resp ) {
var responseString = "" ;
resp . on ( "data" , function ( data ) {
responseString += data ;
} ) ;
resp . on ( "end" , function ( ) {
var result = JSON . parse ( responseString ) ;
if ( result . error ) {
res . status ( 401 ) . send ( getResponse ( 401 , "Unauthorized" ) ) ;
} else {
if ( authorized ( result ) ) {
success ( ) ;
2020-09-28 23:32:09 +02:00
} else {
2021-11-26 10:50:01 +01:00
res . status ( 401 ) . send ( getResponse ( 401 , "Unauthorized" ) ) ;
2020-09-28 23:32:09 +02:00
}
2021-11-26 10:50:01 +01:00
}
2020-09-28 23:32:09 +02:00
} ) ;
2021-11-26 10:50:01 +01:00
} ) ;
2020-09-28 23:32:09 +02:00
}
2019-06-06 11:31:03 +02:00
function getResponse ( code , message ) {
var response = { } ;
response [ "code" ] = code ;
response [ "message" ] = message ;
return response ;
}
2021-11-25 17:53:59 +01:00
function deleteFile ( filepath , res = null ) {
2019-06-06 11:31:03 +02:00
const fs = require ( 'fs' ) ;
fs . stat ( filepath , function ( err , stats ) {
if ( err ) {
return console . error ( err ) ;
}
2021-11-25 17:53:59 +01:00
try {
fs . unlinkSync ( filepath ) ;
2019-06-06 11:31:03 +02:00
console . log ( 'file deleted successfully' ) ;
2021-11-25 17:53:59 +01:00
if ( res ) {
res . send ( "File Deleted Successfully" ) ;
}
} catch ( err ) {
console . error ( err ) ;
}
2019-06-06 11:31:03 +02:00
} ) ;
}
2021-11-25 17:53:59 +01:00
function mapType ( type , communityMap = true ) {
if ( type === 'organization' ) {
return 'institution' ;
} else if ( type === 'ri' && communityMap ) {
return 'community' ;
} else {
return type ;
2020-09-28 23:41:23 +02:00
}
}
2021-11-25 17:53:59 +01:00
function isPortalAdmin ( roles ) {
return roles . includes ( "PORTAL_ADMINISTRATOR" ) ;
2018-07-13 13:56:03 +02:00
}
2019-06-06 11:31:03 +02:00
2021-11-25 17:53:59 +01:00
function isAnyCurator ( roles ) {
return roles . filter ( role => role . includes ( "CURATOR_" ) ) . length > 0 ;
2019-06-06 11:31:03 +02:00
}
2021-11-25 17:53:59 +01:00
function isCurator ( type , roles ) {
return roles . includes ( "CURATOR_" + mapType ( type ) . toUpperCase ( ) ) ;
}
2019-06-06 11:31:03 +02:00
2021-11-25 17:53:59 +01:00
function isManager ( type , id , roles ) {
return roles . includes ( mapType ( type ) . toUpperCase ( ) + "_" + id . toUpperCase ( ) + "_MANAGER" ) ;
2019-06-06 11:31:03 +02:00
}