loosened the CORS settings, added set-url to lemma-term.js for cross-site api usage

This commit is contained in:
defparam 2024-07-16 21:14:05 -04:00
parent 437aa33127
commit d3d70a6bab
2 changed files with 97 additions and 9 deletions

View File

@ -1,5 +1,6 @@
from fastapi import FastAPI, Query, Request from fastapi import FastAPI, Query, Request
from fastapi.responses import StreamingResponse, FileResponse, Response from fastapi.responses import StreamingResponse, FileResponse, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
import asyncio import asyncio
import os import os
@ -13,6 +14,16 @@ import shlex
app = FastAPI() app = FastAPI()
# Allow all origins, all methods, and all headers
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # You can specify a list of allowed origins here
allow_credentials=True,
allow_methods=["*"], # Allow all HTTP methods
allow_headers=["*"], # Allow all headers
expose_headers=["x-lemma-timeout"], # Expose the custom header
)
# get a list of every file (not directory) with +x set in the tools directory # get a list of every file (not directory) with +x set in the tools directory
tools = [f for f in os.listdir("tools") if os.path.isfile(os.path.join("tools", f)) and os.access(os.path.join("tools", f), os.X_OK)] tools = [f for f in os.listdir("tools") if os.path.isfile(os.path.join("tools", f)) and os.access(os.path.join("tools", f), os.X_OK)]
@ -25,6 +36,11 @@ def access_allowed(request):
ckey = request.cookies.get("LEMMA_API_KEY") ckey = request.cookies.get("LEMMA_API_KEY")
if ckey and ckey == key: if ckey and ckey == key:
return None return None
# check if key is in the header field "x-lemma-api-key"
header_key = request.headers.get("x-lemma-api-key")
if header_key and header_key == key:
return None
if key and request.query_params.get("key") == key: if key and request.query_params.get("key") == key:
# return redirect to '/' with a cookie set # return redirect to '/' with a cookie set
r = Response(status_code=302, headers={"Location": "/"}) r = Response(status_code=302, headers={"Location": "/"})

View File

@ -7,6 +7,8 @@ let lineBuffer = [];
let history = []; let history = [];
let historyIndex = -1; let historyIndex = -1;
let offset = 0; let offset = 0;
let lambdaurl = "";
let lemmaauth = "";
function stripAnsiCodes(str) { function stripAnsiCodes(str) {
// Regular expression to match ANSI escape codes // Regular expression to match ANSI escape codes
@ -17,7 +19,11 @@ function stripAnsiCodes(str) {
async function load_tools() async function load_tools()
{ {
try { try {
const response = await fetch('/tools.json'); const response = await fetch(lambdaurl + '/tools.json', {
headers: {
"x-lemma-api-key": lemmaauth
}
});
if (!response.ok) { if (!response.ok) {
throw new Error('Network response was not ok'); throw new Error('Network response was not ok');
} }
@ -94,13 +100,16 @@ async function execute_remote_tool(terminal, args) {
const abortController = new AbortController(); const abortController = new AbortController();
try { try {
const url = new URL('/runtool', window.location.origin); const url = new URL('/runtool', lambdaurl);
url.searchParams.set('cmd', encodeURIComponent(args)); url.searchParams.set('cmd', encodeURIComponent(args));
url.searchParams.set('verbose', "true"); url.searchParams.set('verbose', "true");
const response = await fetch(url.toString(), { const response = await fetch(url.toString(), {
method: 'POST', method: 'POST',
signal: abortController.signal, signal: abortController.signal,
headers: {
"x-lemma-api-key": lemmaauth
}
}); });
if (!response.body) { if (!response.body) {
@ -108,7 +117,7 @@ async function execute_remote_tool(terminal, args) {
} }
// Get the timeout from the header and set the timeout // Get the timeout from the header and set the timeout
const timeoutHeader = response.headers.get('X-Lemma-Timeout'); const timeoutHeader = response.headers.get('x-lemma-timeout');
const timeout = parseInt(timeoutHeader, 10) * 1000; // Convert to milliseconds const timeout = parseInt(timeoutHeader, 10) * 1000; // Convert to milliseconds
// Set a timeout to abort the request // Set a timeout to abort the request
@ -189,6 +198,27 @@ document.addEventListener('DOMContentLoaded', () => {
// Adjust terminal size when window is resized // Adjust terminal size when window is resized
window.addEventListener('resize', fitTerminal); window.addEventListener('resize', fitTerminal);
// first lets get the LAMBDA_URL cookie using document.cookie
const cookies = document.cookie.split(';');
cookies.forEach(cookie => {
if (cookie.includes('LEMMA_URL')) {
lambdaurl = cookie.split('=')[1];
}
});
cookies.forEach(cookie => {
if (cookie.includes('LEMMA_OVERRIDE_API_KEY')) {
lemmaauth = cookie.split('=')[1];
}
});
if (lambdaurl === "") {
// get the host name of the page
lambdaurl = window.location.origin
}
// check if the command query has been set // check if the command query has been set
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const command = urlParams.get('cmd'); const command = urlParams.get('cmd');
@ -307,6 +337,7 @@ document.addEventListener('DOMContentLoaded', () => {
terminal.write(' \x1b[32msize -\x1b[0m Show or Set terminal size (i.e size, size 45x100)\r\n'); terminal.write(' \x1b[32msize -\x1b[0m Show or Set terminal size (i.e size, size 45x100)\r\n');
terminal.write(' \x1b[32mrun <args> -\x1b[0m Run a remote tool in the current terminal\r\n'); terminal.write(' \x1b[32mrun <args> -\x1b[0m Run a remote tool in the current terminal\r\n');
terminal.write(' \x1b[32mfork <args> -\x1b[0m Run a remote tool in a new terminal\r\n'); terminal.write(' \x1b[32mfork <args> -\x1b[0m Run a remote tool in a new terminal\r\n');
terminal.write(' \x1b[32mset-url <lamdaurl> -\x1b[0m Set the lambda URL\r\n');
terminal.write(prompt); terminal.write(prompt);
} else if (command0 === 'clear') { } else if (command0 === 'clear') {
terminal.clear(); terminal.clear();
@ -320,6 +351,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (terminalContainer.clientWidth <= 1024) { if (terminalContainer.clientWidth <= 1024) {
truecols = 100; truecols = 100;
} }
toollist = [];
terminal.clear(); terminal.clear();
terminal.resize(truerows, truecols); terminal.resize(truerows, truecols);
fitTerminal() fitTerminal()
@ -354,6 +386,46 @@ document.addEventListener('DOMContentLoaded', () => {
window.open(finalurl, '_blank'); window.open(finalurl, '_blank');
terminal.write(prompt); terminal.write(prompt);
} else if (command0 === 'set-url') {
// lets take the LAMBDA_URL and set it as a cookie called LAMBDA_URL
const url = command.split(' ').slice(1).join(' ').trim();
if ((url === "") || (url === undefined)) {
document.cookie = "LEMMA_URL=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
document.cookie = "LEMMA_OVERRIDE_API_KEY=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
lambdaurl = window.location.origin;
lemmaauth = "";
terminal.write(`\x1b[32mLambda URL reset\x1b[0m\r\n`);
terminal.write(prompt);
return
}
let parsedUrl;
try {
parsedUrl = new URL(url);
} catch (_) {
terminal.write(`\x1b[31mInvalid Lambda URL:\x1b[0m ${url}\r\n`);
terminal.write(prompt);
return
}
const hostname = parsedUrl.hostname;
const keyValue = parsedUrl.searchParams.get('key');
if (keyValue !== null) {
document.cookie = "LEMMA_URL=https://" + hostname + "; path=/"
document.cookie = "LEMMA_OVERRIDE_API_KEY=" + keyValue + "; path=/"
lambdaurl = "https://" + hostname;
lemmaauth = keyValue;
terminal.write(`\x1b[32mLambda URL set to:\x1b[0m ${url}\r\n`);
terminal.write(prompt);
}
else {
terminal.write(`\x1b[31mInvalid Lambda URL:\x1b[0m ${url}\r\n`);
terminal.write(prompt);
}
} else if (command0 === 'run') { } else if (command0 === 'run') {
const args = command.split(' ').slice(1).join(' '); const args = command.split(' ').slice(1).join(' ');
disableInput = true; disableInput = true;