From 8f36ed5f8f633eb31c70cf6a327b3feecc94b189 Mon Sep 17 00:00:00 2001 From: aecsocket <43144841+aecsocket@users.noreply.github.com> Date: Wed, 19 Aug 2026 23:51:13 +0900 Subject: [PATCH] ignore TOTP in debug --- ...cb7d62a7e7160c6aa95cea71ff11ea43c973.json} | 4 +- .../labrinth/src/queue/payout_run/estimate.rs | 20 +++---- .../src/routes/internal/payout_runs/admin.rs | 54 ++++++++++++------- 3 files changed, 48 insertions(+), 30 deletions(-) rename apps/labrinth/.sqlx/{query-63e02c2f770542021a83afbf919d20d7cc5458d00d9067ae8af932434d1c1ad6.json => query-c4ebaf1d3b32250101b0f31bc6decb7d62a7e7160c6aa95cea71ff11ea43c973.json} (56%) diff --git a/apps/labrinth/.sqlx/query-63e02c2f770542021a83afbf919d20d7cc5458d00d9067ae8af932434d1c1ad6.json b/apps/labrinth/.sqlx/query-c4ebaf1d3b32250101b0f31bc6decb7d62a7e7160c6aa95cea71ff11ea43c973.json similarity index 56% rename from apps/labrinth/.sqlx/query-63e02c2f770542021a83afbf919d20d7cc5458d00d9067ae8af932434d1c1ad6.json rename to apps/labrinth/.sqlx/query-c4ebaf1d3b32250101b0f31bc6decb7d62a7e7160c6aa95cea71ff11ea43c973.json index d90d45707c..f927699567 100644 --- a/apps/labrinth/.sqlx/query-63e02c2f770542021a83afbf919d20d7cc5458d00d9067ae8af932434d1c1ad6.json +++ b/apps/labrinth/.sqlx/query-c4ebaf1d3b32250101b0f31bc6decb7d62a7e7160c6aa95cea71ff11ea43c973.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n EXISTS (\n SELECT 1\n FROM payout_runs\n WHERE period = $1\n AND status IN ('scheduled', 'running')\n ) AS \"has_active_run!\",\n EXISTS (\n SELECT 1\n FROM payout_runs\n WHERE period = $1\n AND status = 'succeeded'\n ) AS \"has_succeeded_run!\"\n ", + "query": "\n SELECT\n EXISTS (\n SELECT 1\n FROM payout_runs\n WHERE status IN ('scheduled', 'running')\n ) AS \"has_active_run!\",\n EXISTS (\n SELECT 1\n FROM payout_runs\n WHERE period = $1\n AND status = 'succeeded'\n ) AS \"has_succeeded_run!\"\n ", "describe": { "columns": [ { @@ -24,5 +24,5 @@ null ] }, - "hash": "63e02c2f770542021a83afbf919d20d7cc5458d00d9067ae8af932434d1c1ad6" + "hash": "c4ebaf1d3b32250101b0f31bc6decb7d62a7e7160c6aa95cea71ff11ea43c973" } diff --git a/apps/labrinth/src/queue/payout_run/estimate.rs b/apps/labrinth/src/queue/payout_run/estimate.rs index 3665cfad8b..6c6911e18a 100644 --- a/apps/labrinth/src/queue/payout_run/estimate.rs +++ b/apps/labrinth/src/queue/payout_run/estimate.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; -use chrono::{Datelike, Months, NaiveDate}; +use chrono::{Months, NaiveDate}; use dashmap::DashMap; -use eyre::{Result, eyre}; +use eyre::Result; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use xredis::RedisPool; @@ -85,6 +85,13 @@ async fn fetch_estimates( let mut map = HashMap::::new(); for response in metrics.responses { for row in response.rows { + let Some(raw_estimated_revenue_usd) = row.revenue else { + continue; + }; + let Some(impressions) = row.impressions else { + continue; + }; + let date = row.time.date_naive(); let period = YearMonth::from_day1(date); @@ -94,15 +101,10 @@ async fn fetch_estimates( }); let days = &mut period_estimate.days; - let day = date.day(); days.push(DayEstimate { date, - raw_estimated_revenue_usd: row - .revenue - .wrap_err_with(|| eyre!("no revenue data for day {day}"))?, - impressions: row.impressions.wrap_err_with(|| { - eyre!("no impressions data for day {day}") - })?, + raw_estimated_revenue_usd, + impressions, }); } } diff --git a/apps/labrinth/src/routes/internal/payout_runs/admin.rs b/apps/labrinth/src/routes/internal/payout_runs/admin.rs index f3ae45e9b5..f8d246ecc6 100644 --- a/apps/labrinth/src/routes/internal/payout_runs/admin.rs +++ b/apps/labrinth/src/routes/internal/payout_runs/admin.rs @@ -28,7 +28,13 @@ use crate::{ #[derive(Debug, Deserialize)] pub struct StartPayoutRun { pub period: YearMonth, - pub two_factor_code: String, + pub two_factor_code: Option, + /// Skip TOTP verification when testing this route locally. + /// + /// This field does not exist in release builds. + #[cfg(debug_assertions)] + #[serde(default)] + pub ignore_totp: bool, #[serde(with = "rust_decimal::serde::float")] pub raw_actual_revenue_usd: Decimal, pub adjustments: Vec, @@ -66,26 +72,37 @@ pub async fn start_run( } let user_id = DBUserId::from(user.id); - let secret = sqlx::query_scalar!( - r#" + #[cfg(debug_assertions)] + let ignore_totp = body.ignore_totp; + #[cfg(not(debug_assertions))] + let ignore_totp = false; + + if !ignore_totp { + let two_factor_code = body + .two_factor_code + .as_deref() + .wrap_auth_err_with(|| AuthenticationError::InvalidCredentials)?; + let secret = sqlx::query_scalar!( + r#" SELECT totp_secret FROM users WHERE id = $1 "#, - user_id.0, - ) - .fetch_one(&**pool) - .await - .wrap_internal_err("fetching user two-factor secret")? - .wrap_auth_err_with(|| AuthenticationError::InvalidCredentials)?; - let valid_totp = - verify_2fa_code(&body.two_factor_code, &secret, user_id, &redis) - .await - .wrap_auth_err("verifying two-factor code")?; - if !valid_totp { - return Err(ApiError::Auth(eyre::eyre!( - AuthenticationError::InvalidCredentials, - ))); + user_id.0, + ) + .fetch_one(&**pool) + .await + .wrap_internal_err("fetching user two-factor secret")? + .wrap_auth_err_with(|| AuthenticationError::InvalidCredentials)?; + let valid_totp = + verify_2fa_code(two_factor_code, &secret, user_id, &redis) + .await + .wrap_auth_err("verifying two-factor code")?; + if !valid_totp { + return Err(ApiError::Auth(eyre::eyre!( + AuthenticationError::InvalidCredentials, + ))); + } } if body.raw_actual_revenue_usd.is_sign_negative() { @@ -144,8 +161,7 @@ pub async fn start_run( EXISTS ( SELECT 1 FROM payout_runs - WHERE period = $1 - AND status IN ('scheduled', 'running') + WHERE status IN ('scheduled', 'running') ) AS "has_active_run!", EXISTS ( SELECT 1