main.py
· 326 B · Python
Raw
#!/usr/bin/env python3
from pyotp import TOTP
import requests
from traceback import print_exc
while True:
try:
code = TOTP("aVeryLongSecretCode").now()
requests.get("http://localhost:4646/ffxivlauncher/" + code, timeout=10)
break
except requests.exceptions.ConnectionError:
print_exc()
| 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() |
| 12 |
main.rs
· 2.2 KiB · Rust
Raw
use std::time::Duration;
use log::{error, info, warn, debug};
use reqwest::Client;
use totp_rs::{Algorithm, TOTP, Secret};
use clap::Parser;
const TOTP_DIGITS: usize = 6;
const TOTP_STEP: u64 = 30;
const TOTP_ALGORITHM: Algorithm = Algorithm::SHA1;
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
secret: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize logging
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.init();
let args: Args = Args::parse();
// Create the TOTP instance
let totp: TOTP = TOTP::new(
TOTP_ALGORITHM,
TOTP_DIGITS,
1,
TOTP_STEP,
Secret::Encoded(args.secret).to_bytes()?,
)?;
// Generate the current TOTP code
let mut token: String = totp.generate_current()?;
info!("Generated TOTP token: {}", token);
// Send the TOTP code to the local service
let client: Client = Client::new();
loop {
match totp.check_current(&token) {
Ok(true) => {
debug!("TOTP token is valid.");
}
Ok(false) => {
info!("TOTP token is invalid. Regenerating...");
token = totp.generate_current()?;
}
Err(e) => {
error!("Error checking TOTP token: {}", e);
}
}
match client
.get(&format!("http://localhost:4646/ffxivlauncher/{}", token))
.timeout(Duration::from_secs(5))
.send()
.await
{
Ok(response ) => {
if response.status().is_success() {
info!("TOTP token sent successfully.");
break;
} else {
warn!("Failed to send TOTP token. Status: {}", response.status());
}
}
Err(e) => {
if e.is_connect() {
info!("Connection refused. Retrying...");
} else {
error!("Unexpected error: {}", e);
}
}
}
}
Ok(())
}
| 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 | } |