2023-02-14 17:37:40 -07:00
|
|
|
import {
|
|
|
|
AGGIETIME_URI,
|
|
|
|
LOGIN_PATH,
|
2023-02-15 11:04:32 -07:00
|
|
|
USER_PATH,
|
2023-02-14 17:37:40 -07:00
|
|
|
DUO_IFRAME_SELECTOR,
|
|
|
|
DUO_FACTOR,
|
|
|
|
DUO_INPUT_FIELD_SELECTORS,
|
|
|
|
EXECUTION_SELECTOR,
|
|
|
|
} from "./constants.js";
|
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
import { client } from "./axios_client.js";
|
|
|
|
|
2023-02-14 17:37:40 -07:00
|
|
|
import { parse } from "node-html-parser";
|
2023-02-15 11:04:32 -07:00
|
|
|
//import axios from "axios";
|
2023-02-14 17:37:40 -07:00
|
|
|
|
|
|
|
const make_auth_params = (username, password, execution) =>
|
|
|
|
new URLSearchParams({
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
execution,
|
|
|
|
_eventId: "submit",
|
|
|
|
geolocation: "",
|
|
|
|
});
|
|
|
|
|
|
|
|
const push_duo_get_cookie = async (
|
|
|
|
duo_iframe_obj,
|
|
|
|
response_url,
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
execution
|
|
|
|
) => {
|
|
|
|
const [duo_host, duo_sig, duo_src] = [
|
|
|
|
"data-host",
|
|
|
|
"data-sig-request",
|
|
|
|
"src",
|
|
|
|
].map((attr) => duo_iframe_obj.getAttribute(attr));
|
2023-02-15 11:04:32 -07:00
|
|
|
const transaction_id = duo_sig.split(":").at(0);
|
|
|
|
const app = duo_sig.split(":APP").at(-1);
|
2023-02-14 17:37:40 -07:00
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
const duo = client.create({
|
2023-02-14 17:37:40 -07:00
|
|
|
baseURL: `https://${duo_host}`,
|
|
|
|
});
|
|
|
|
|
|
|
|
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 {
|
|
|
|
response: { txid },
|
|
|
|
} = await duo.post("/frame/prompt", push_params).then(({ data }) => data);
|
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
const { cookie, parent } = await wait_approve_duo_cookie_resp(duo, sid, txid);
|
|
|
|
return { duo_signed_resp: cookie + ":APP" + app, parent };
|
2023-02-14 17:37:40 -07:00
|
|
|
};
|
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
const wait_approve_duo_cookie_resp = async (duo, sid, txid) => {
|
2023-02-14 17:37:40 -07:00
|
|
|
const status_params = new URLSearchParams({
|
|
|
|
sid,
|
|
|
|
txid,
|
|
|
|
});
|
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
// First status to confirm device was pushed to
|
|
|
|
// Second to long-poll for approval :3
|
2023-02-14 17:37:40 -07:00
|
|
|
const {
|
|
|
|
response: { result_url },
|
2023-02-15 11:04:32 -07:00
|
|
|
} = await duo.post("/frame/status", status_params).then(async ({ data }) => {
|
|
|
|
if (data.stat === "OK" && data.response.status_code === "pushed")
|
|
|
|
return await duo
|
|
|
|
.post("/frame/status", status_params)
|
|
|
|
.then(({ data }) => data);
|
|
|
|
return data;
|
|
|
|
});
|
2023-02-14 17:37:40 -07:00
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
const {
|
|
|
|
response: { cookie, parent },
|
|
|
|
} = await duo
|
|
|
|
.post(result_url, new URLSearchParams({ sid }))
|
|
|
|
.then(({ data }) => data);
|
2023-02-14 17:37:40 -07:00
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
return { cookie, parent };
|
2023-02-14 17:37:40 -07:00
|
|
|
};
|
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
const get_execution = (cas_root) => {};
|
|
|
|
|
2023-02-14 17:37:40 -07:00
|
|
|
export const login = async (username, password) => {
|
2023-02-15 11:04:32 -07:00
|
|
|
const login_page_promise = client.get(`${AGGIETIME_URI}/${LOGIN_PATH}`);
|
2023-02-14 17:37:40 -07:00
|
|
|
|
|
|
|
const {
|
|
|
|
request: {
|
|
|
|
res: { responseUrl: response_url },
|
|
|
|
},
|
|
|
|
} = await login_page_promise;
|
2023-02-15 11:04:32 -07:00
|
|
|
let cas_root = await login_page_promise.then(({ data }) => parse(data));
|
|
|
|
const login_execution = cas_root
|
2023-02-14 17:37:40 -07:00
|
|
|
.querySelector(EXECUTION_SELECTOR)
|
|
|
|
.getAttribute("value");
|
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
cas_root = await client
|
|
|
|
.post(response_url, make_auth_params(username, password, login_execution))
|
|
|
|
.then(({ data }) => parse(data));
|
|
|
|
const authed_execution = cas_root
|
|
|
|
.querySelector(EXECUTION_SELECTOR)
|
|
|
|
.getAttribute("value");
|
2023-02-14 17:37:40 -07:00
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
const duo_iframe_obj = cas_root.querySelector(DUO_IFRAME_SELECTOR);
|
|
|
|
|
|
|
|
const { duo_signed_resp, parent: signed_response_url } =
|
|
|
|
await push_duo_get_cookie(
|
|
|
|
duo_iframe_obj,
|
|
|
|
response_url,
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
login_execution
|
|
|
|
);
|
2023-02-14 17:37:40 -07:00
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
const jwt_cookie_set = await client.post(
|
|
|
|
signed_response_url,
|
|
|
|
new URLSearchParams({
|
|
|
|
execution: authed_execution,
|
|
|
|
signedDuoResponse: duo_signed_resp,
|
|
|
|
_eventId: "submit",
|
|
|
|
})
|
|
|
|
);
|
2023-02-14 17:37:40 -07:00
|
|
|
|
2023-02-15 11:04:32 -07:00
|
|
|
return jwt_cookie_set;
|
2023-02-14 17:37:40 -07:00
|
|
|
};
|