diff --git a/config/inesdata.js b/config/inesdata.js index db35212..60f5d39 100644 --- a/config/inesdata.js +++ b/config/inesdata.js @@ -5,5 +5,6 @@ module.exports = ({ env }) => ({ tokenUsername: env('TOKEN_USERNAME', 'user-c1'), tokenPassword: env('TOKEN_PASSWORD', 'user-c1'), keycloakBaseUrl: env('KEYCLOAK_BASE_URL', 'http://keycloak:8080'), - catalogBaseUrl: env('CATALOG_BASE_URL', 'http://connector-c1:19193') + catalogBaseUrl: env('CATALOG_BASE_URL', 'http://connector-c1:19193'), + vocabulariesBaseUrl: env('VOCABULARIES_BASE_URL', 'http://connector-c1:19196') }) diff --git a/src/api/get-federated-catalog/controllers/get-federated-catalog.js b/src/api/get-federated-catalog/controllers/get-federated-catalog.js index afe7974..baad042 100644 --- a/src/api/get-federated-catalog/controllers/get-federated-catalog.js +++ b/src/api/get-federated-catalog/controllers/get-federated-catalog.js @@ -1,95 +1,13 @@ 'use strict'; const axios = require('axios'); +const tokenService = require('../../services/token-service'); -const tokenData = { - accessToken: null, - refreshToken: null, - expiresIn: null, - refreshExpiresIn: null, - obtainedAt: null, - refreshObtainedAt: null -}; - -const getTokenFromAuthServer = async () => { - try { - const params = new URLSearchParams(); - params.append('grant_type', 'password'); - params.append('client_id', process.env.TOKEN_CLIENT_ID); - params.append('username', process.env.TOKEN_USERNAME); - params.append('password', process.env.TOKEN_PASSWORD); - - const tokenUrl = `${process.env.KEYCLOAK_BASE_URL}/realms/dataspace/protocol/openid-connect/token`; - - const response = await axios.post(tokenUrl, params); - const data = response.data; - - tokenData.accessToken = data.access_token; - tokenData.refreshToken = data.refresh_token; - tokenData.expiresIn = data.expires_in; // expires_in is in seconds - tokenData.refreshExpiresIn = data.refresh_expires_in; // refresh_expires_in is in seconds - tokenData.obtainedAt = Date.now(); // store the time the token was obtained - tokenData.refreshObtainedAt = Date.now(); // store the time the refresh token was obtained - - return data; - } catch (error) { - console.error('Error obtaining token from auth server:', error); - throw new Error('Failed to obtain token from auth server'); - } -}; - -const refreshToken = async () => { - try { - const params = new URLSearchParams(); - params.append('grant_type', 'refresh_token'); - params.append('client_id', process.env.TOKEN_CLIENT_ID); - params.append('refresh_token', tokenData.refreshToken); - - const tokenUrl = `${process.env.KEYCLOAK_BASE_URL}/realms/dataspace/protocol/openid-connect/token`; - - const response = await axios.post(tokenUrl, params); - const data = response.data; - - tokenData.accessToken = data.access_token; - tokenData.refreshToken = data.refresh_token; - tokenData.expiresIn = data.expires_in; - tokenData.refreshExpiresIn = data.refresh_expires_in; - tokenData.obtainedAt = Date.now(); - - return data; - } catch (error) { - console.error('Error refreshing token:', error); - throw new Error('Failed to refresh token'); - } -}; - -const getAccessToken = async () => { - try { - if (!tokenData.accessToken || !tokenData.refreshToken) { - await getTokenFromAuthServer(); - } else { - const currentTime = Date.now(); - const accessTokenExpired = (currentTime - tokenData.obtainedAt) / 1000 > tokenData.expiresIn; - const refreshTokenExpired = (currentTime - tokenData.refreshObtainedAt) / 1000 > tokenData.refreshExpiresIn; - - if (refreshTokenExpired) { - await getTokenFromAuthServer(); - } else if (accessTokenExpired) { - await refreshToken(); - } - } - - return tokenData.accessToken; - } catch (error) { - console.error('Error getting access token:', error); - throw new Error('Failed to get access token'); - } -}; module.exports = { getFederatedCatalog: async (ctx, next) => { try { - const accessToken = await getAccessToken(); + const accessToken = await tokenService.getAccessToken(); if (!accessToken) { ctx.body = { message: 'Access token not available. Please authenticate first.' }; ctx.status = 401; @@ -99,7 +17,13 @@ module.exports = { // URL for fetching the federated catalog const countCatalogUrl = `${process.env.CATALOG_BASE_URL}/management/pagination/count?type=federatedCatalog`; - const countResponse = await axios.get(countCatalogUrl, { + const body = ctx.request.body + delete body.offset + delete body.limit + delete body.sortOrder + delete body.sortField + + const countResponse = await axios.post(countCatalogUrl, body,{ headers: { Authorization: `Bearer ${accessToken}` } diff --git a/src/api/get-vocabularies/controllers/get-vocabularies.js b/src/api/get-vocabularies/controllers/get-vocabularies.js new file mode 100644 index 0000000..92d9477 --- /dev/null +++ b/src/api/get-vocabularies/controllers/get-vocabularies.js @@ -0,0 +1,36 @@ +'use strict'; + +const axios = require('axios'); +const tokenService = require('../../services/token-service'); + + +module.exports = { + getVocabularies: async (ctx, next) => { + try { + const accessToken = await tokenService.getAccessToken(); + if (!accessToken) { + ctx.body = { message: 'Access token not available. Please authenticate first.' }; + ctx.status = 401; + return; + } + + + // URL for fetching the vocabularies + const vocabulariesBaseUrl = `${process.env.VOCABULARIES_BASE_URL}/shared/connector-vocabularies/request`; + + // Fetch the vocabularies using the access token + const vocabulariesResponse = await axios.post(vocabulariesBaseUrl, {}, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }); + + // Respond with the fetched data + ctx.body = vocabulariesResponse.data; + } catch (err) { + console.error('Error:', err); + ctx.body = { message: 'Error fetching vocabularies!', details: err.message }; + ctx.status = 500; + } + } +}; diff --git a/src/api/get-vocabularies/routes/get-vocabularies.js b/src/api/get-vocabularies/routes/get-vocabularies.js new file mode 100644 index 0000000..916ae8d --- /dev/null +++ b/src/api/get-vocabularies/routes/get-vocabularies.js @@ -0,0 +1,9 @@ +module.exports = { + "routes": [ + { + "method": "POST", + "path": "/get-vocabularies", + "handler": "get-vocabularies.getVocabularies" + } + ] +}; diff --git a/src/api/services/token-service.js b/src/api/services/token-service.js new file mode 100644 index 0000000..983354d --- /dev/null +++ b/src/api/services/token-service.js @@ -0,0 +1,91 @@ +const axios = require('axios'); + +const tokenData = { + accessToken: null, + refreshToken: null, + expiresIn: null, + refreshExpiresIn: null, + obtainedAt: null, + refreshObtainedAt: null +}; + +const getTokenFromAuthServer = async () => { + try { + const params = new URLSearchParams(); + params.append('grant_type', 'password'); + params.append('client_id', process.env.TOKEN_CLIENT_ID); + params.append('username', process.env.TOKEN_USERNAME); + params.append('password', process.env.TOKEN_PASSWORD); + + const tokenUrl = `${process.env.KEYCLOAK_BASE_URL}/realms/dataspace/protocol/openid-connect/token`; + + const response = await axios.post(tokenUrl, params); + const data = response.data; + + tokenData.accessToken = data.access_token; + tokenData.refreshToken = data.refresh_token; + tokenData.expiresIn = data.expires_in; // expires_in is in seconds + tokenData.refreshExpiresIn = data.refresh_expires_in; // refresh_expires_in is in seconds + tokenData.obtainedAt = Date.now(); // store the time the token was obtained + tokenData.refreshObtainedAt = Date.now(); // store the time the refresh token was obtained + + return data; + } catch (error) { + console.error('Error obtaining token from auth server:', error); + throw new Error('Failed to obtain token from auth server'); + } +}; + +const refreshToken = async () => { + try { + const params = new URLSearchParams(); + params.append('grant_type', 'refresh_token'); + params.append('client_id', process.env.TOKEN_CLIENT_ID); + params.append('refresh_token', tokenData.refreshToken); + + const tokenUrl = `${process.env.KEYCLOAK_BASE_URL}/realms/dataspace/protocol/openid-connect/token`; + + const response = await axios.post(tokenUrl, params); + const data = response.data; + + tokenData.accessToken = data.access_token; + tokenData.refreshToken = data.refresh_token; + tokenData.expiresIn = data.expires_in; + tokenData.refreshExpiresIn = data.refresh_expires_in; + tokenData.obtainedAt = Date.now(); + + return data; + } catch (error) { + console.error('Error refreshing token:', error); + throw new Error('Failed to refresh token'); + } +}; + +const getAccessToken = async () => { + try { + if (!tokenData.accessToken || !tokenData.refreshToken) { + await getTokenFromAuthServer(); + } else { + const currentTime = Date.now(); + const accessTokenExpired = (currentTime - tokenData.obtainedAt) / 1000 > tokenData.expiresIn; + const refreshTokenExpired = (currentTime - tokenData.refreshObtainedAt) / 1000 > tokenData.refreshExpiresIn; + + if (refreshTokenExpired) { + await getTokenFromAuthServer(); + } else if (accessTokenExpired) { + await refreshToken(); + } + } + + return tokenData.accessToken; + } catch (error) { + console.error('Error getting access token:', error); + throw new Error('Failed to get access token'); + } +}; + +module.exports = { + getTokenFromAuthServer, + refreshToken, + getAccessToken +};