From 8d710c5ca9b86a42d0b275705664bcbe17c20105 Mon Sep 17 00:00:00 2001 From: aleksaelezovic Date: Mon, 27 Jan 2025 16:59:47 +0100 Subject: [PATCH 1/2] feat: support for auth with token --- README.md | 2 +- controllers/exampleSparqlController.js | 2 +- controllers/exampleVectorController.js | 2 +- middleware/auth.js | 10 +- services/authService.js | 4 +- services/userManagementService.js | 156 ++++++++++++++++--------- 6 files changed, 110 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 22eb3fd..7640516 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ After creating .env, please setup your real values for following variables: 1. LLM_API_KEY - Example dRAG uses LLM to formulate the answer. If you want to add your own variables for any other provider, model or any kind of data you need, you can do in Auth service -> UserConfig table, those variables will be available inside your DRAG: ```javascript - const userData = await authService.authenticateAndCache(req.sessionSid); + const userData = await authService.authenticateAndCache(req); ``` ```sh diff --git a/controllers/exampleSparqlController.js b/controllers/exampleSparqlController.js index b90d24f..8fe3b04 100644 --- a/controllers/exampleSparqlController.js +++ b/controllers/exampleSparqlController.js @@ -10,7 +10,7 @@ export default { try { const { question, chatHistory } = req.body; - const userData = await authService.authenticateAndCache(req.sessionSid); + const userData = await authService.authenticateAndCache(req); const llmService = new LLMService(userData); diff --git a/controllers/exampleVectorController.js b/controllers/exampleVectorController.js index 4ae18ac..9795731 100644 --- a/controllers/exampleVectorController.js +++ b/controllers/exampleVectorController.js @@ -11,7 +11,7 @@ export default { try { const { question, chatHistory } = req.body; - const userData = await authService.authenticateAndCache(req.sessionSid); + const userData = await authService.authenticateAndCache(req); const llmService = new LLMService(userData); diff --git a/middleware/auth.js b/middleware/auth.js index 1efee77..68afee9 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -1,16 +1,8 @@ import authService from "../services/authService.js"; export function authenticateToken(req, res, next) { - const token = req.headers.authorization; - - if (!token || !token.startsWith("Bearer ")) { - return res.status(401).json({ error: "Unauthorized" }); - } - - const authToken = token.split(" ")[1]; - authService - .authenticateAndCache(authToken) + .authenticateAndCache(req) .then((userData) => { if (userData) { next(); diff --git a/services/authService.js b/services/authService.js index 863f83c..fb38f17 100644 --- a/services/authService.js +++ b/services/authService.js @@ -2,9 +2,9 @@ import CacheService from "./cacheService.js"; import { authenticateToken } from "./userManagementService.js"; class AuthService { - async authenticateAndCache(cookie) { + async authenticateAndCache(req) { try { - const { userData, expiresIn } = await authenticateToken(cookie); + const { userData, expiresIn } = await authenticateToken(req); return userData; } catch (error) { diff --git a/services/userManagementService.js b/services/userManagementService.js index 7b133ae..41eebef 100644 --- a/services/userManagementService.js +++ b/services/userManagementService.js @@ -15,83 +15,135 @@ const baseUserData = { apiKey: process.env.LLM_API_KEY, }; -export async function authenticateToken(cookie) { +export async function authenticateToken(req) { + // try { + // const response = await axios.get(`${AUTH_ENDPOINT}/auth/check`, { + // headers: { Cookie: `${COOKIE_NAME}=${cookie}` }, + // withCredentials: "true", + // }); + // } catch (error) { + // logger.error("Error fetching user config: " + error); + // } + try { - const response = await axios.get(`${AUTH_ENDPOINT}/auth/check`, { - headers: { Cookie: `${COOKIE_NAME}=${cookie}` }, - withCredentials: "true", - }); + const authHeader = req.headers["authorization"]; + + if (authHeader && authHeader.startsWith("Bearer ")) { + // Bearer token is present + const token = authHeader.split(" ")[1]; + + if (!token) { + throw Error("Invalid Bearer token format"); + } + + const response = await axios.get(`${AUTH_ENDPOINT}/auth/check`, { + headers: { Authorization: `Bearer ${token}` }, + withCredentials: true, + }); + return prepareResponse(response, baseUserData); + } else { + // Bearer token not present, check for session cookie + const sessionCookie = req.headers.cookie; + + if (!sessionCookie) { + throw Error("No Bearer token or session cookie found"); + } + + const response = await axios.get(`${AUTH_ENDPOINT}/auth/check`, { + headers: { Cookie: sessionCookie }, + withCredentials: true, + }); + return prepareResponse(response, baseUserData); + } + } catch (error) { + console.error("Error during authentication:", error); + logger.error("Error fetching user config: " + error); + throw new Error("Internal server error"); + } +} - const userConfig = response.data.user.config.find( +function prepareResponse(response, baseUserData) { + const userConfig = + response.data.user.config.find( (cfg) => cfg.option === DRAG_USER_CONFIG_OPTION ) || null; - const edgeNodePublishMode = response.data.user.config.find( + const edgeNodePublishMode = + response.data.user.config.find( (cfg) => cfg.option === "edge_node_publish_mode" )?.value || null; - const edgeNodeParanetUAL = response.data.user.config.find( - (cfg) => cfg.option === "edge_node_paranet_ual" + const edgeNodeParanetUAL = + response.data.user.config.find( + (cfg) => cfg.option === "edge_node_paranet_ual" )?.value || null; - const environment = response.data.user.config.find( + const environment = + response.data.user.config.find( (cfg) => cfg.option === "edge_node_environment" )?.value || null; - const runTimeNodeEndpoint = response.data.user.config.find( + const runTimeNodeEndpoint = + response.data.user.config.find( (cfg) => cfg.option === "run_time_node_endpoint" )?.value || null; - const blockchain = response.data.user.config.find( - (cfg) => cfg.option === "blockchain" - )?.value || null; + const blockchain = + response.data.user.config.find((cfg) => cfg.option === "blockchain") + ?.value || null; - const vectorDBUri = response.data.user.config.find( - (cfg) => cfg.option === "milvus_address" - )?.value || null; + const vectorDBUri = + response.data.user.config.find((cfg) => cfg.option === "milvus_address") + ?.value || null; - const vectorDBCredentials = response.data.user.config + const vectorDBCredentials = + response.data.user.config .find((cfg) => cfg.option === "milvus_token") ?.value?.split(":") || null; - const vectorDBUsername = (vectorDBCredentials !== null && vectorDBCredentials.length > 0) ? vectorDBCredentials[0] : null; - const vectorDBPassword = (vectorDBCredentials !== null && vectorDBCredentials.length > 0) ? vectorDBCredentials[1] : null; - - const vectorCollection = response.data.user.config + const vectorDBUsername = + vectorDBCredentials !== null && vectorDBCredentials.length > 0 + ? vectorDBCredentials[0] + : null; + const vectorDBPassword = + vectorDBCredentials !== null && vectorDBCredentials.length > 0 + ? vectorDBCredentials[1] + : null; + + const vectorCollection = + response.data.user.config .find((cfg) => cfg.option === "vector_collection") ?.value?.split(",") || null; - const embeddingModelAPIKey = response.data.user.config.find( + const embeddingModelAPIKey = + response.data.user.config.find( (cfg) => cfg.option === "embedding_model_api_key" )?.value || null; - const embeddingModel = response.data.user.config.find( - (cfg) => cfg.option === "embedding_model" - )?.value || null; - - const cohereKey = response.data.user.config.find( - (cfg) => cfg.option === "cohere_key" - )?.value || null; - - return { - userData: { - ...baseUserData, - id: userConfig.id, - edgeNodePublishMode: edgeNodePublishMode, - paranetUAL: edgeNodeParanetUAL, - environment: environment, - endpoint: runTimeNodeEndpoint, - blockchain: blockchain, - vectorCollection: vectorCollection, - vectorDBUri: vectorDBUri, - vectorDBUsername: vectorDBUsername, - vectorDBPassword: vectorDBPassword, - embeddingModelAPIKey: embeddingModelAPIKey, - embeddingModel: embeddingModel, - cohereKey: cohereKey, - }, - }; - } catch (error) { - logger.error("Error fetching user config: " + error); - } + const embeddingModel = + response.data.user.config.find((cfg) => cfg.option === "embedding_model") + ?.value || null; + + const cohereKey = + response.data.user.config.find((cfg) => cfg.option === "cohere_key") + ?.value || null; + + return { + userData: { + ...baseUserData, + id: userConfig.id, + edgeNodePublishMode: edgeNodePublishMode, + paranetUAL: edgeNodeParanetUAL, + environment: environment, + endpoint: runTimeNodeEndpoint, + blockchain: blockchain, + vectorCollection: vectorCollection, + vectorDBUri: vectorDBUri, + vectorDBUsername: vectorDBUsername, + vectorDBPassword: vectorDBPassword, + embeddingModelAPIKey: embeddingModelAPIKey, + embeddingModel: embeddingModel, + cohereKey: cohereKey, + }, + }; } From c9047fc154252c964e25a1516a5630ea6e24b039 Mon Sep 17 00:00:00 2001 From: aleksaelezovic Date: Mon, 27 Jan 2025 17:00:10 +0100 Subject: [PATCH 2/2] format --- controllers/exampleSparqlController.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/controllers/exampleSparqlController.js b/controllers/exampleSparqlController.js index 8fe3b04..411301e 100644 --- a/controllers/exampleSparqlController.js +++ b/controllers/exampleSparqlController.js @@ -22,14 +22,13 @@ export default { chatHistory ); - const headline = await llmService.getDigitalDocumentTitle(standaloneQuestion); + const headline = await llmService.getDigitalDocumentTitle( + standaloneQuestion + ); const sparqlQuery = getSparqlQuery(headline); - const queryResults = await dkgService.query( - sparqlQuery, - userData - ); + const queryResults = await dkgService.query(sparqlQuery, userData); let result = queryResults[0]; if (result.length === 0) {