From af29569ed5cfc7df6337a9dab51c743116c07343 Mon Sep 17 00:00:00 2001 From: Lizzy Hunt Date: Fri, 24 Mar 2023 15:44:30 -0600 Subject: [PATCH] Add position id in req body, auto fake remember me --- src/aggietime.js | 18 ++++++++++-------- src/constants.js | 6 ++++-- src/main.js | 20 ++++++++++++++------ src/session.js | 14 +++++++++++++- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/aggietime.js b/src/aggietime.js index b887e36..413188a 100644 --- a/src/aggietime.js +++ b/src/aggietime.js @@ -21,16 +21,16 @@ const aggietime = client.create({ const replace_path_args = (path, map) => path.replaceAll(/:([a-zA-Z0-9_]+)/g, (_, key) => map[key]); -const get_user_position_or_specified = async (position) => { +const get_user_position_or_specified = async (position_id) => { const { positions } = await get_user_info(); - if (!position && positions.length != 1) { + if (position_id === undefined && positions.length != 1) { throw "Must specify a position when there's not only one to choose from"; - } else if (!position) { - position = positions[0]; + } else if (position_id === undefined) { + return positions[0]; } - return position; + return position_id; }; export const get_user_info = async () => { @@ -53,12 +53,12 @@ export const get_user_info = async () => { return expireCache.get("user"); }; -const do_clock_mutation = async (path, { position } = {}) => { - position = await get_user_position_or_specified(position); +const do_clock_mutation = async (path, { position_id } = {}) => { + position_id = await get_user_position_or_specified(position_id); return await aggietime .post( - replace_path_args(path, { position }), + replace_path_args(path, { position_id }), { comment: "", }, @@ -74,6 +74,8 @@ const do_clock_mutation = async (path, { position } = {}) => { }); }; +// Actions + export const clock_in = async (rest) => do_clock_mutation(CLOCKIN_PATH, rest); export const clock_out = async (rest) => do_clock_mutation(CLOCKOUT_PATH, rest); diff --git a/src/constants.js b/src/constants.js index 9b6c037..7ae26c0 100644 --- a/src/constants.js +++ b/src/constants.js @@ -8,8 +8,8 @@ export const AGGIETIME_URL_CONTAINS_SIGNIFIES_AUTH_COMPLETE = "employee"; export const REFRESH_JWT_MS = 5 * 1000 * 60; export const LOGIN_PATH = "api/v1/auth/login"; -export const CLOCKIN_PATH = "api/v1/positions/:position/clock_in"; -export const CLOCKOUT_PATH = "api/v1/positions/:position/clock_out"; +export const CLOCKIN_PATH = "api/v1/positions/:position_id/clock_in"; +export const CLOCKOUT_PATH = "api/v1/positions/:position_id/clock_out"; export const USER_PATH = "api/v1/auth/get_user_info"; export const OPEN_SHIFT_PATH = "api/v1/users/:anumber/open_shift"; export const OPEN_SHIFT_EXP_SEC = 60; @@ -21,6 +21,8 @@ export const SAML_SUBMIT_SELECTOR = "input[type=submit]"; export const SAML_EMAIL_SELECTOR = "input[type=email]"; export const SAML_PASSWORD_SELECTOR = "input[type=password]"; +export const DUO_TRUST_SELECTOR = "#trust-browser-button"; + export const MAX_DEFAULT_RETRY_AMOUNT = 3; export const WAIT_MS = 2000; export const RETRY_EXPONENT = 1.2; diff --git a/src/main.js b/src/main.js index 690b55f..b08dd80 100644 --- a/src/main.js +++ b/src/main.js @@ -20,7 +20,7 @@ export default async () => { if (args.daemon) { try { - start_server(args.socket_path, args.pass_cmd, session.logout); + start_server(args, session.logout); } catch (e) { console.error(e); if (fs.existsSync(args.socket_path)) { @@ -29,15 +29,17 @@ export default async () => { } } else if (args.action) { if (fs.existsSync(args.socket_path)) { - run_action(args.socket_path, args.action); + run_action(args); } else { console.error(`ERR: No such socket '${args.socket_path}'`); } } }; -const run_action = (socket_path, action) => { +const run_action = (args) => { + const { socket_path, action, position_id } = args; const connection = net.connect(socket_path); + connection.on("data", (data) => { if (Buffer.isBuffer(data)) { console.log(data.toString().trim()); @@ -46,7 +48,8 @@ const run_action = (socket_path, action) => { } connection.end(); }); - connection.write(JSON.stringify({ action })); + + connection.write(JSON.stringify({ action, rest: { position_id } })); }; const build_args = () => { @@ -58,6 +61,11 @@ const build_args = () => { default: false, }); + parser.add_argument("-pos", "--position-id", { + help: "Position ID (for usage with --action clock_in or clock_out)", + default: undefined, + }); + parser.add_argument("-s", "--socket_path", { default: DEFAULT_SOCKET_PATH, help: `Set server socket path, defaults to ${DEFAULT_SOCKET_PATH}`, @@ -84,7 +92,7 @@ const kill_server = (server, socket_path) => { } }; -const start_server = async (socket_path, login_cmd, on_exit = () => {}) => { +const start_server = async ({ socket_path, pass_cmd }, on_exit = () => {}) => { if (fs.existsSync(socket_path)) { console.error( `ERR: Socket '${socket_path}' already exists. @@ -95,7 +103,7 @@ specify another socket path with --socket_path` process.exit(1); } - const { anumber, password } = await retrieve_creds(login_cmd); + const { anumber, password } = await retrieve_creds(pass_cmd); await session.login(anumber, password); session.refresh_jwt(); diff --git a/src/session.js b/src/session.js index aee49c2..40eb5f9 100644 --- a/src/session.js +++ b/src/session.js @@ -6,6 +6,7 @@ import { AGGIETIME_DOMAIN, AGGIETIME_URI, AGGIETIME_URL_CONTAINS_SIGNIFIES_AUTH_COMPLETE, + DUO_TRUST_SELECTOR, LOGIN_PATH, SAML_SIGN_IN_TITLE, SAML_SUBMIT_SELECTOR, @@ -60,9 +61,20 @@ export const login = async (a_number, password) => { await new Promise((res) => setTimeout(res, 500)); console.log("Submit!"); - await driver.findElement(By.css(SAML_SUBMIT_SELECTOR)).click(); + await driver + .wait(until.elementLocated(By.css(SAML_SUBMIT_SELECTOR))) + .then(() => driver.findElement(By.css(SAML_SUBMIT_SELECTOR)).click()); } + console.log('Press (fake and cringe) "remember me" buttons...'); + await driver + .wait(until.elementLocated(By.css(DUO_TRUST_SELECTOR))) + .then(() => driver.findElement(By.css(DUO_TRUST_SELECTOR)).click()) + .then(() => + driver.wait(until.elementLocated(By.css(SAML_SUBMIT_SELECTOR))) + ) + .then(() => driver.findElement(By.css(SAML_SUBMIT_SELECTOR)).click()); + console.log( "Waiting for aggietime response (potential DUO required here)..." );