From 7331da69aa3442d7edaed4160b5a6bd3239ed265 Mon Sep 17 00:00:00 2001 From: Lizzy Hunt Date: Wed, 11 Oct 2023 11:06:35 -0600 Subject: [PATCH] allow cookie on stdin --- cli.js | 2 +- src/aggietime.js | 12 ++++++------ src/exponential_retry.js | 6 +++--- src/main.js | 25 ++++++++++++++++++++----- src/session.js | 11 +++++++---- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/cli.js b/cli.js index 289ecfa..d67ff6d 100755 --- a/cli.js +++ b/cli.js @@ -1,4 +1,4 @@ #!/usr/bin/env node -import main from './src/main.js'; +import main from "./src/main.js"; main(); diff --git a/src/aggietime.js b/src/aggietime.js index f037fd4..8fa1880 100644 --- a/src/aggietime.js +++ b/src/aggietime.js @@ -43,11 +43,11 @@ export const get_user_info = async () => { .toJSON() .cookies.find( ({ domain, key }) => - domain === AGGIETIME_DOMAIN && key === "XSRF-TOKEN" + domain === AGGIETIME_DOMAIN && key === "XSRF-TOKEN", ).value; expireCache.set("aggietime-csrf", csrf_token); return data; - }) + }), ); expireCache.set("user", user, USER_CACHE_EXP_SEC); @@ -68,7 +68,7 @@ const do_clock_mutation = async (path, { position_id } = {}) => { headers: { "X-XSRF-TOKEN": expireCache.get("aggietime-csrf"), }, - } + }, ) .then(({ data }) => { expireCache.remove("status_line"); @@ -109,14 +109,14 @@ export const get_status_line = async () => { const start = new Date(shift?.start); status_line = ((new Date().getTime() - start.getTime()) / (1000 * 60 * 60)).toFixed( - 2 + 2, ) + " hours"; } expireCache.set( "status_line", `${anumber} - ${status_line}`, - OPEN_SHIFT_EXP_SEC + OPEN_SHIFT_EXP_SEC, ); } return { status: expireCache.get("status_line") }; @@ -143,7 +143,7 @@ export const last_week = async ({ position_id }) => { expireCache.set( "past_week", `${anumber} - ${hours} hours`, - PAST_WEEK_EXP_SEC + PAST_WEEK_EXP_SEC, ); } return { status: expireCache.get("past_week") }; diff --git a/src/exponential_retry.js b/src/exponential_retry.js index 96ca979..66c78d3 100644 --- a/src/exponential_retry.js +++ b/src/exponential_retry.js @@ -11,12 +11,12 @@ export const with_exponential_retry = async ( promise_fn, validation_fn = (x) => Promise.resolve(!!x), max_retries = MAX_DEFAULT_RETRY_AMOUNT, - retries = 0 + retries = 0, ) => { try { if (retries) await wait_for( - WAIT_MS * Math.pow(RETRY_EXPONENT, RETRY_EXPONENTIAL_FACTOR * retries) + WAIT_MS * Math.pow(RETRY_EXPONENT, RETRY_EXPONENTIAL_FACTOR * retries), ); const res = await promise_fn(); @@ -29,7 +29,7 @@ export const with_exponential_retry = async ( promise_fn, validation_fn, max_retries, - retries + 1 + retries + 1, ); } }; diff --git a/src/main.js b/src/main.js index e1cb666..2e1c975 100644 --- a/src/main.js +++ b/src/main.js @@ -55,6 +55,12 @@ const run_action = (args) => { const build_args = () => { const parser = new argparse.ArgumentParser({ description: "AggieTime CLI" }); + parser.add_argument("-cos", "--cookie-on-stdin", { + help: "Set a cookie from whatever is on stdin", + action: argparse.BooleanOptionalAction, + default: false, + }); + parser.add_argument("-d", "--daemon", { help: "Start server as a process blocking daemon", action: argparse.BooleanOptionalAction, @@ -92,19 +98,28 @@ const kill_server = (server, socket_path) => { } }; -const start_server = async ({ socket_path, pass_cmd }, on_exit = () => {}) => { +const start_server = async ( + { cookie_on_stdin, socket_path, pass_cmd }, + on_exit = () => {}, +) => { if (fs.existsSync(socket_path)) { console.error( `ERR: Socket '${socket_path}' already exists. If no server process is running, remove it (this should've been done automatically, except in the event of a catastrophic failure) OR -specify another socket path with --socket_path` +specify another socket path with --socket_path`, ); process.exit(1); } - const { anumber, password } = await retrieve_creds(pass_cmd); - await session.login(anumber, password); + if (!cookie_on_stdin) { + const { anumber, password } = await retrieve_creds(pass_cmd); + await session.login(anumber, password); + } else { + let cookie = ""; + for await (const chunk of process.stdin) cookie += chunk; + await session.setCookie(cookie); + } session.refresh_jwt(); setInterval(session.refresh_jwt, REFRESH_JWT_MS); @@ -140,6 +155,6 @@ specify another socket path with --socket_path` // Attempt to clean up socket before process gets killed KILL_SIGNALS.forEach((signal) => - process.on(signal, () => kill_server(unix_server, socket_path)) + process.on(signal, () => kill_server(unix_server, socket_path)), ); }; diff --git a/src/session.js b/src/session.js index 42a8617..d55b772 100644 --- a/src/session.js +++ b/src/session.js @@ -21,6 +21,9 @@ export const refresh_jwt = () => { return aggietime.get_user_info(); }; +export const setCookie = (jwt) => + jar.setCookie(`${AGGIETIME_AUTH_COOKIE_NAME}=${jwt}`, AGGIETIME_URI); + export const logout = () => client.get(`${AGGIETIME_URI}/${LOGOUT_PATH}`); export const login = async (a_number, password) => { @@ -47,8 +50,8 @@ export const login = async (a_number, password) => { console.log("Waiting until password field is located..."); await Promise.all( [SAML_PASSWORD_SELECTOR, SAML_SUBMIT_SELECTOR].map((selector) => - driver.wait(until.elementLocated(By.css(selector))) - ) + driver.wait(until.elementLocated(By.css(selector))), + ), ); console.log("Filling password..."); @@ -66,7 +69,7 @@ export const login = async (a_number, password) => { } await driver.wait( - until.urlContains(AGGIETIME_URL_CONTAINS_SIGNIFIES_AUTH_COMPLETE) + until.urlContains(AGGIETIME_URL_CONTAINS_SIGNIFIES_AUTH_COMPLETE), ); console.log("Retrieving cookie..."); @@ -77,7 +80,7 @@ export const login = async (a_number, password) => { ...cookie, key: cookie.name, }), - AGGIETIME_URI + AGGIETIME_URI, ); console.log("Got it!"); } finally {