diff options
Diffstat (limited to 'src/session.js')
-rw-r--r-- | src/session.js | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/src/session.js b/src/session.js index 0206731..a127ac2 100644 --- a/src/session.js +++ b/src/session.js @@ -1,17 +1,17 @@ import { AGGIETIME_URI, LOGIN_PATH, + LOGOUT_PATH, USER_PATH, DUO_IFRAME_SELECTOR, DUO_FACTOR, DUO_INPUT_FIELD_SELECTORS, EXECUTION_SELECTOR, } from "./constants.js"; - +import * as aggietime from "./aggietime.js"; import { client } from "./axios_client.js"; import { parse } from "node-html-parser"; -//import axios from "axios"; const make_auth_params = (username, password, execution) => new URLSearchParams({ @@ -22,6 +22,22 @@ const make_auth_params = (username, password, execution) => geolocation: "", }); +const make_duo_push_params = ( + sid, + out_of_date, + days_out_of_date, + days_to_block, + device +) => + new URLSearchParams({ + sid, + out_of_date, + days_out_of_date, + days_to_block, + device, + factor: DUO_FACTOR, + }); + const push_duo_get_cookie = async ( duo_iframe_obj, response_url, @@ -34,49 +50,43 @@ const push_duo_get_cookie = async ( "data-sig-request", "src", ].map((attr) => duo_iframe_obj.getAttribute(attr)); - const transaction_id = duo_sig.split(":").at(0); - const app = duo_sig.split(":APP").at(-1); const duo = client.create({ baseURL: `https://${duo_host}`, }); + const transaction_id = duo_sig.split(":").at(0); + const app = duo_sig.split(":APP").at(-1); + console.log("Retrieving DUO frame DOM for this transaction..."); const duo_frame = await duo .post( `/frame/web/v1/auth?tx=${transaction_id}&parent=${response_url}&v=2.6` ) .then(({ data }) => parse(data)); - const [sid, out_of_date, days_out_of_date, days_to_block, device] = - DUO_INPUT_FIELD_SELECTORS.map((selector) => - duo_frame.querySelector(selector).getAttribute("value") - ); - - const push_params = new URLSearchParams({ - sid, - out_of_date, - days_out_of_date, - days_to_block, - device, - factor: DUO_FACTOR, - }); + const push_param_list = DUO_INPUT_FIELD_SELECTORS.map((selector) => + duo_frame.querySelector(selector).getAttribute("value") + ); + let [sid, _] = push_param_list; const { response: { txid }, - } = await duo.post("/frame/prompt", push_params).then(({ data }) => data); + } = await duo + .post("/frame/prompt", make_duo_push_params.apply(null, push_param_list)) + .then(({ data }) => data); + console.log("Waiting for approval..."); const { cookie, parent } = await wait_approve_duo_cookie_resp(duo, sid, txid); return { duo_signed_resp: cookie + ":APP" + app, parent }; }; const wait_approve_duo_cookie_resp = async (duo, sid, txid) => { + // First status to confirm device was pushed to, + // Second to create a long-poll connection-alive socket for approval status :3 const status_params = new URLSearchParams({ sid, txid, }); - - // First status to confirm device was pushed to - // Second to long-poll for approval :3 const { response: { result_url }, } = await duo.post("/frame/status", status_params).then(async ({ data }) => { @@ -93,33 +103,48 @@ const wait_approve_duo_cookie_resp = async (duo, sid, txid) => { .post(result_url, new URLSearchParams({ sid })) .then(({ data }) => data); + if (!cookie) throw "Unable to retrieve signed cookie from DUO"; + return { cookie, parent }; }; -const get_execution = (cas_root) => {}; +export const refresh_jwt = () => { + console.log("Refreshing JWT..."); + + return aggietime.get_user_info(); +}; + +export const logout = () => client.get(`${AGGIETIME_URI}/${LOGOUT_PATH}`); export const login = async (username, password) => { const login_page_promise = client.get(`${AGGIETIME_URI}/${LOGIN_PATH}`); + console.log("Retreiving login page..."); const { request: { res: { responseUrl: response_url }, }, } = await login_page_promise; + let cas_root = await login_page_promise.then(({ data }) => parse(data)); + + console.log("Parsing DOM for spring execution token..."); const login_execution = cas_root .querySelector(EXECUTION_SELECTOR) .getAttribute("value"); + console.log("Sending CAS credentials..."); cas_root = await client .post(response_url, make_auth_params(username, password, login_execution)) .then(({ data }) => parse(data)); + + console.log("Parsing DOM for authenticated spring execution token..."); const authed_execution = cas_root .querySelector(EXECUTION_SELECTOR) .getAttribute("value"); const duo_iframe_obj = cas_root.querySelector(DUO_IFRAME_SELECTOR); - + console.log("Starting DUO authentication..."); const { duo_signed_resp, parent: signed_response_url } = await push_duo_get_cookie( duo_iframe_obj, @@ -129,7 +154,8 @@ export const login = async (username, password) => { login_execution ); - const jwt_cookie_set = await client.post( + console.log("Sending DUO signed response back to CAS..."); + return await client.post( signed_response_url, new URLSearchParams({ execution: authed_execution, @@ -137,6 +163,4 @@ export const login = async (username, password) => { _eventId: "submit", }) ); - - return jwt_cookie_set; }; |