diff --git a/.env.local b/.env.local index 34c8c52..b44ada4 100644 --- a/.env.local +++ b/.env.local @@ -1 +1,2 @@ VITE_FIREBASE_CONFIG={"apiKey":"AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc","authDomain":"imex-dev.firebaseapp.com","databaseURL":"https://imex-dev.firebaseio.com","projectId":"imex-dev","storageBucket":"imex-dev.appspot.com","messagingSenderId":"759548147434","appId":"1:759548147434:web:e8239868a48ceb36700993","measurementId":"G-K5XRBVVB4S"} +VITE_GRAPHQL_ENDPOINT=https://db.dev.imex.online/v1/graphql \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index df144bf..132fc57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "electron-log": "^5.3.2", "electron-store": "^8.2.0", "electron-updater": "^6.3.9", - "graphql-request": "^7.1.2", + "graphql": "^16.10.0", "i18next": "^24.2.2", "lodash": "^4.17.21", "playwright": "^1.51.0", @@ -47,6 +47,7 @@ "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.19", "firebase": "^11.4.0", + "graphql-request": "^7.1.2", "prettier": "^3.5.3", "react": "^19.0.0", "react-dom": "^19.0.0", @@ -2224,6 +2225,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "dev": true, "license": "MIT", "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" @@ -7364,7 +7366,6 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", "license": "MIT", - "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -7373,6 +7374,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-7.1.2.tgz", "integrity": "sha512-+XE3iuC55C2di5ZUrB4pjgwe+nIQBuXVIK9J98wrVwojzDW3GMdSBZfxUk8l4j9TieIpjpggclxhNEU9ebGF8w==", + "dev": true, "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.2.0" diff --git a/package.json b/package.json index d8bc063..57b807a 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "electron-log": "^5.3.2", "electron-store": "^8.2.0", "electron-updater": "^6.3.9", - "graphql-request": "^7.1.2", + "graphql": "^16.10.0", "i18next": "^24.2.2", "lodash": "^4.17.21", "playwright": "^1.51.0", @@ -59,6 +59,7 @@ "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.19", "firebase": "^11.4.0", + "graphql-request": "^7.1.2", "prettier": "^3.5.3", "react": "^19.0.0", "react-dom": "^19.0.0", diff --git a/src/main/graphql/graphql-client.ts b/src/main/graphql/graphql-client.ts new file mode 100644 index 0000000..efd2f1c --- /dev/null +++ b/src/main/graphql/graphql-client.ts @@ -0,0 +1,42 @@ +import { BrowserWindow, ipcMain } from "electron"; +import log from "electron-log/main"; +import { GraphQLClient, RequestMiddleware } from "graphql-request"; +import errorTypeCheck from "../../util/errorTypeCheck.js"; +import ipcTypes from "../../util/ipcTypes.json"; + +const requestMiddleware: RequestMiddleware = async (request) => { + const token = await getTokenFromRenderer(); + return { + ...request, + headers: { ...request.headers, Authorization: `Bearer ${token}` }, + }; +}; + +const client: GraphQLClient = new GraphQLClient( + import.meta.env.VITE_GRAPHQL_ENDPOINT, + { + requestMiddleware, + } +); + +export async function getTokenFromRenderer(): Promise { + return new Promise((resolve) => { + try { + const mainWindow = BrowserWindow.getAllWindows()[0]; //TODO: Filter to only main window once a proper key has been set. + //TODO: Verify that this will work if the app is minimized/closed. + mainWindow.webContents.send(ipcTypes.toRenderer.user.getToken); + } catch (error) { + log.error( + "Unable to send request to renderer process for token", + errorTypeCheck(error) + ); + } + + // Set up one-time listener for the response + ipcMain.once(ipcTypes.toMain.user.getTokenResponse, (_, token: string) => { + resolve(token); + }); + }); +} + +export default client; diff --git a/src/main/index.ts b/src/main/index.ts index 0284bcc..6369bad 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -4,6 +4,7 @@ import log from "electron-log/main"; import path, { join } from "path"; import icon from "../../resources/icon.png?asset"; import ErrorTypeCheck from "../util/errorTypeCheck"; +import client from "./graphql/graphql-client"; import store from "./store/store"; log.initialize(); @@ -32,7 +33,7 @@ function createWindow(): void { }, }); - const template = [ + const template: Electron.MenuItemConstructorOptions[] = [ // { role: 'appMenu' } ...(isMac ? [ @@ -117,13 +118,14 @@ function createWindow(): void { submenu: [ { label: "Learn More", - click: async () => { + click: async (): Promise => { const { shell } = require("electron"); await shell.openExternal("https://electronjs.org"); }, }, ], }, + ...(import.meta.env.DEV ? [ { @@ -148,6 +150,26 @@ function createWindow(): void { shell.openPath(path.dirname(store.path)); }, }, + { + type: "separator", + }, + { + label: "Temp Test Action - Get Token from Renderer", + click: (): void => { + client + .request( + ` + query jobs{ + jobs + { + id}} + ` + ) + .then((data) => { + log.info("Data from graffle", data); + }); + }, + }, ], }, ] diff --git a/src/renderer/src/main.tsx b/src/renderer/src/main.tsx index 7c4d133..1732922 100644 --- a/src/renderer/src/main.tsx +++ b/src/renderer/src/main.tsx @@ -2,6 +2,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./util/i18n"; +import "./util/ipcRendererHandler"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/src/renderer/src/util/ipcRendererHandler.ts b/src/renderer/src/util/ipcRendererHandler.ts index 49c6d63..718a87f 100644 --- a/src/renderer/src/util/ipcRendererHandler.ts +++ b/src/renderer/src/util/ipcRendererHandler.ts @@ -1,5 +1,6 @@ //Set up all of the IPC handlers. import ipcTypes from "../../../util/ipcTypes.json"; +import { auth } from "./firebase"; const ipcRenderer = window.electron.ipcRenderer; @@ -10,3 +11,11 @@ ipcRenderer.on( console.log(arg); } ); + +ipcRenderer.on( + ipcTypes.toRenderer.user.getToken, + async (event: Electron.IpcRendererEvent, arg) => { + const token = await auth.currentUser?.getIdToken(); + ipcRenderer.send(ipcTypes.toMain.user.getTokenResponse, token); + } +); diff --git a/src/util/ipcTypes.json b/src/util/ipcTypes.json index 3466e7f..586803e 100644 --- a/src/util/ipcTypes.json +++ b/src/util/ipcTypes.json @@ -15,9 +15,15 @@ "add": "toMain_settings_filepaths_add", "remove": "toMain_settings_filepaths_remove" } + }, + "user": { + "getTokenResponse": "toMain_user_getTokenResponse" } }, "toRenderer": { - "test": "toRenderer_test" + "test": "toRenderer_test", + "user": { + "getToken": "toRenderer_user_getToken" + } } }