Last active 1747616828

aly's Avatar aly revised this gist 1747616828. Go to revision

2 files changed, 92 insertions

main.py(file created)

@@ -0,0 +1,11 @@
1 + #!/usr/bin/env python3
2 + from pyotp import TOTP
3 + import requests
4 + from traceback import print_exc
5 + while True:
6 + try:
7 + code = TOTP("aVeryLongSecretCode").now()
8 + requests.get("http://localhost:4646/ffxivlauncher/" + code, timeout=10)
9 + break
10 + except requests.exceptions.ConnectionError:
11 + print_exc()

main.rs(file created)

@@ -0,0 +1,81 @@
1 + use std::time::Duration;
2 + use log::{error, info, warn, debug};
3 +
4 + use reqwest::Client;
5 + use totp_rs::{Algorithm, TOTP, Secret};
6 + use clap::Parser;
7 +
8 + const TOTP_DIGITS: usize = 6;
9 + const TOTP_STEP: u64 = 30;
10 + const TOTP_ALGORITHM: Algorithm = Algorithm::SHA1;
11 +
12 + #[derive(Parser, Debug)]
13 + #[command(version, about, long_about = None)]
14 + struct Args {
15 + secret: String,
16 + }
17 +
18 + #[tokio::main]
19 + async fn main() -> Result<(), Box<dyn std::error::Error>> {
20 + // Initialize logging
21 + env_logger::builder()
22 + .filter_level(log::LevelFilter::Info)
23 + .format_target(false)
24 + .format_timestamp(None)
25 + .init();
26 + let args: Args = Args::parse();
27 +
28 + // Create the TOTP instance
29 + let totp: TOTP = TOTP::new(
30 + TOTP_ALGORITHM,
31 + TOTP_DIGITS,
32 + 1,
33 + TOTP_STEP,
34 + Secret::Encoded(args.secret).to_bytes()?,
35 + )?;
36 +
37 + // Generate the current TOTP code
38 + let mut token: String = totp.generate_current()?;
39 + info!("Generated TOTP token: {}", token);
40 +
41 + // Send the TOTP code to the local service
42 + let client: Client = Client::new();
43 + loop {
44 + match totp.check_current(&token) {
45 + Ok(true) => {
46 + debug!("TOTP token is valid.");
47 + }
48 + Ok(false) => {
49 + info!("TOTP token is invalid. Regenerating...");
50 + token = totp.generate_current()?;
51 + }
52 + Err(e) => {
53 + error!("Error checking TOTP token: {}", e);
54 + }
55 + }
56 + match client
57 + .get(&format!("http://localhost:4646/ffxivlauncher/{}", token))
58 + .timeout(Duration::from_secs(5))
59 + .send()
60 + .await
61 + {
62 + Ok(response ) => {
63 + if response.status().is_success() {
64 + info!("TOTP token sent successfully.");
65 + break;
66 + } else {
67 + warn!("Failed to send TOTP token. Status: {}", response.status());
68 + }
69 + }
70 + Err(e) => {
71 + if e.is_connect() {
72 + info!("Connection refused. Retrying...");
73 + } else {
74 + error!("Unexpected error: {}", e);
75 + }
76 + }
77 + }
78 + }
79 +
80 + Ok(())
81 + }
Newer Older