From 136b2115c7ec3fb9ce6230e7c087f49eb8d99e63 Mon Sep 17 00:00:00 2001 From: Mythicaeda Date: Fri, 8 Dec 2023 14:48:50 -0800 Subject: [PATCH] Improve altair experience (#50) * Automatically set Auth headers and add preRQ script - Automatically install the GQL explorer plugin - Update Altair version * Update login script to only login when the JWT expires - Move Login script to external file - Exclude `static/` directory from esLint --- .eslintrc.cjs | 1 + package-lock.json | 30 +++++++++---------- package.json | 2 +- src/packages/api-playground/api-playground.ts | 27 ++++++++++++++++- static/api-playground/pre-request-script.js | 24 +++++++++++++++ 5 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 static/api-playground/pre-request-script.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 5a37996..b70d668 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,4 +1,5 @@ module.exports = { + ignorePatterns: ["static/*"], extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', diff --git a/package-lock.json b/package-lock.json index e0f4c73..fc057d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.1.0", "license": "MIT", "dependencies": { - "altair-express-middleware": "^5.0.28", + "altair-express-middleware": "^5.2.11", "cors": "^2.8.5", "express": "^4.18.2", "express-rate-limit": "^6.7.0", @@ -637,11 +637,11 @@ } }, "node_modules/altair-express-middleware": { - "version": "5.0.28", - "resolved": "https://registry.npmjs.org/altair-express-middleware/-/altair-express-middleware-5.0.28.tgz", - "integrity": "sha512-qoqlGxWrrAXZ6Iuz7msbWofkeO9fSS0PXwncLrUKlYUGjpX6Uv6FqTeTbkSXs+TGhjMjp0qsnrgFa3d0b807dA==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/altair-express-middleware/-/altair-express-middleware-5.2.11.tgz", + "integrity": "sha512-ezZtpmTf+P36U7NhS1Gj2ziChTyXAN5EO4QKbQI+V21QNfKnNGMua/0Hw1B/TGsIgCRr7taBqa5akLApYFy1qA==", "dependencies": { - "altair-static": "^5.0.28", + "altair-static": "^5.2.11", "express": "^4.16.2" }, "engines": { @@ -653,9 +653,9 @@ } }, "node_modules/altair-static": { - "version": "5.0.28", - "resolved": "https://registry.npmjs.org/altair-static/-/altair-static-5.0.28.tgz", - "integrity": "sha512-RMThoxUODIEM1f9UqWO+hTemhbR8D6feMSW2fcnxHIciw901yckdxmfpseh2Z6H0S4COitZO4YXkFPrnzFxHVA==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/altair-static/-/altair-static-5.2.11.tgz", + "integrity": "sha512-WByckcissWf6Drx87+L0dqe269PAMZngjMUHcR1oUVoM5NRFenO8RPH0+TSV8fuZXAXeiKgrYa5B67rjzd+kOA==", "engines": { "node": ">= 6.9.1" }, @@ -3816,18 +3816,18 @@ } }, "altair-express-middleware": { - "version": "5.0.28", - "resolved": "https://registry.npmjs.org/altair-express-middleware/-/altair-express-middleware-5.0.28.tgz", - "integrity": "sha512-qoqlGxWrrAXZ6Iuz7msbWofkeO9fSS0PXwncLrUKlYUGjpX6Uv6FqTeTbkSXs+TGhjMjp0qsnrgFa3d0b807dA==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/altair-express-middleware/-/altair-express-middleware-5.2.11.tgz", + "integrity": "sha512-ezZtpmTf+P36U7NhS1Gj2ziChTyXAN5EO4QKbQI+V21QNfKnNGMua/0Hw1B/TGsIgCRr7taBqa5akLApYFy1qA==", "requires": { - "altair-static": "^5.0.28", + "altair-static": "^5.2.11", "express": "^4.16.2" } }, "altair-static": { - "version": "5.0.28", - "resolved": "https://registry.npmjs.org/altair-static/-/altair-static-5.0.28.tgz", - "integrity": "sha512-RMThoxUODIEM1f9UqWO+hTemhbR8D6feMSW2fcnxHIciw901yckdxmfpseh2Z6H0S4COitZO4YXkFPrnzFxHVA==" + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/altair-static/-/altair-static-5.2.11.tgz", + "integrity": "sha512-WByckcissWf6Drx87+L0dqe269PAMZngjMUHcR1oUVoM5NRFenO8RPH0+TSV8fuZXAXeiKgrYa5B67rjzd+kOA==" }, "ansi-regex": { "version": "5.0.1", diff --git a/package.json b/package.json index a5d18a3..7223a76 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "start": "node dist/main.js" }, "dependencies": { - "altair-express-middleware": "^5.0.28", + "altair-express-middleware": "^5.2.11", "cors": "^2.8.5", "express": "^4.18.2", "express-rate-limit": "^6.7.0", diff --git a/src/packages/api-playground/api-playground.ts b/src/packages/api-playground/api-playground.ts index 6c1202c..243cf3f 100644 --- a/src/packages/api-playground/api-playground.ts +++ b/src/packages/api-playground/api-playground.ts @@ -1,9 +1,34 @@ import { altairExpress } from 'altair-express-middleware'; import type { Express } from 'express'; import { getEnv } from '../../env.js'; +import { readFileSync } from 'fs'; export default (app: Express) => { const { GQL_API_URL: endpointURL, GQL_API_WS_URL: subscriptionsEndpoint } = getEnv(); const initialQuery = '{ plan { id name } }'; - app.use('/api-playground', altairExpress({ endpointURL, initialQuery, subscriptionsEndpoint })); + const initialHeaders = { Authorization: 'Bearer {{user}}', 'x-hasura-role': 'viewer' }; + const initialPreRequestScript = readFileSync('static/api-playground/pre-request-script.js').toString(); + const initialSettings = { + addQueryDepthLimit: 5, + enableExperimental: true, + 'plugin.list': ['altair-graphql-plugin-graphql-explorer'], + 'request.withCredentials': true, + 'schema.reloadOnStart': true, + 'script.allowedCookies': ['user'], + tabSize: 2, + theme: 'dracula', + }; + + app.use( + '/api-playground', + altairExpress({ + disableAccount: true, + endpointURL, + initialHeaders, + initialPreRequestScript, + initialQuery, + initialSettings, + subscriptionsEndpoint, + }), + ); }; diff --git a/static/api-playground/pre-request-script.js b/static/api-playground/pre-request-script.js new file mode 100644 index 0000000..f0b0617 --- /dev/null +++ b/static/api-playground/pre-request-script.js @@ -0,0 +1,24 @@ +const nowInSeconds = () => Date.now() / 1000; +const tokenExpiry = await altair.storage.get('token_exp') || 0; + +if (nowInSeconds() >= Number(tokenExpiry)) { + // Fetch a new token from the Gateway + const res = await altair.helpers.request( + 'POST', + '/auth/login', // AUTH ENDPOINT OF THE DEPLOYMENT + { + body: { username: '', password: '' }, // CREDENTIALS TO LOG IN AS + headers: { 'Content-Type': 'application/json' } + }); + if(res.success) { + const token = res.token; + await altair.storage.set('token', token); + // Set JWT expiry + const atob = await altair.importModule('atob'); + const body = JSON.parse(atob(token.split('.')[1])); + await altair.storage.set('token_exp', body.exp); + } else { altair.log(res); } +} +// Set the token in the environment +const token = await altair.storage.get('token'); +altair.helpers.setEnvironment('user', token);