pusk/bin/twitter.ml

102 lines
3.1 KiB
OCaml
Raw Normal View History

2023-05-13 19:58:48 +02:00
open Pusk.Net
open Pusk.Utils
2023-05-14 20:39:24 +02:00
type credentials =
{ username : string
; password : string
}
let inject_username session_id way creds =
2023-05-13 22:13:26 +02:00
(* Find username input *)
2023-05-14 20:39:24 +02:00
let xpath =
match way with
| 0 ->
XPath
"/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[5]/label/div/div[2]/div/input"
| 1 ->
XPath
"/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[2]/label/div/div[2]/div/input"
| _ -> raise (Any "Unknown page to use for injecting username")
in
2023-05-14 01:44:11 +02:00
let input_username =
2023-05-14 20:39:24 +02:00
match find session_id xpath with
| [] -> raise (Any (fmt "Username input not found (page %d)" way))
2023-05-13 22:13:26 +02:00
| _ as l ->
if List.length l > 1
then raise (Any "Too many element found as the username input")
else List.nth l 0
in
(* Insert the username *)
2023-05-14 20:39:24 +02:00
send_keys session_id input_username creds.username;
2023-05-14 01:44:11 +02:00
Unix.sleep 1;
2023-05-14 20:39:24 +02:00
send_keys session_id input_username Keys.return;
Unix.sleep 3
;;
let rec _inject_password session_id creds try_count =
if try_count == 0 then raise (Any "Password input not found");
2023-05-14 01:44:11 +02:00
let input_password =
match
find
2023-05-14 20:39:24 +02:00
session_id
2023-05-14 01:44:11 +02:00
(XPath
"/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div/div[3]/div/label/div/div[2]/div[1]/input")
with
2023-05-14 20:39:24 +02:00
| [] ->
(* Retry to inject username with the second page *)
inject_username session_id 1 creds;
_inject_password session_id creds (try_count - 1);
None
2023-05-14 01:44:11 +02:00
| _ as l ->
if List.length l > 1
then raise (Any "Too many element found as the password input")
2023-05-14 20:39:24 +02:00
else Some (List.nth l 0)
2023-05-14 01:44:11 +02:00
in
2023-05-14 20:39:24 +02:00
match input_password with
| Some input ->
(* Insert password *)
send_keys session_id input creds.password;
Unix.sleep 1;
send_keys session_id input Keys.return;
2023-05-14 22:37:00 +02:00
Unix.sleep 3
2023-05-14 20:39:24 +02:00
| None -> ()
;;
let inject_password session_id creds = _inject_password session_id creds 1
2023-05-14 22:37:00 +02:00
let inject_2fa session_id secret input =
let code =
2023-05-14 22:16:20 +02:00
match secret with
| Some seed -> Twostep.TOTP.code ~secret:seed ()
| None -> raise (Any "No TOTP code given, but TOTP required")
in
2023-05-14 22:37:00 +02:00
(* Insert 2FA code *)
send_keys session_id input code;
Unix.sleep 1;
send_keys session_id input Keys.return;
Unix.sleep 5
2023-05-14 22:16:20 +02:00
;;
let login_twitter ctx username password secret =
2023-05-14 20:39:24 +02:00
(* Navigate to login page and wait for page loaded*)
ignore (navigate ctx.session_id "https://twitter.com/i/flow/login");
2023-05-14 01:57:29 +02:00
Unix.sleep 5;
2023-05-14 20:39:24 +02:00
let creds = { username; password } in
(* Insert the username *)
inject_username ctx.session_id 0 creds;
(* Find password input *)
inject_password ctx.session_id creds;
2023-05-14 01:57:29 +02:00
(* Detection of 2FA *)
2023-05-14 22:37:00 +02:00
match
find
ctx.session_id
(XPath
"/html/body/div[1]/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[2]/label/div/div[2]/div/input")
with
| [] -> print_endline "Don't use 2FA input as input not found"
2023-05-14 22:16:20 +02:00
| _ as l ->
if List.length l > 1
2023-05-14 22:37:00 +02:00
then raise (Any "Too many element found as 2FA input")
2023-05-14 22:16:20 +02:00
else inject_2fa ctx.session_id secret (List.nth l 0)
2023-05-13 19:58:48 +02:00
;;