/home/josie/development/irc-now/crates/web-api/templates/dashboard.html-80-
/home/josie/development/irc-now/crates/web-api/templates/dashboard.html-81-
/home/josie/development/irc-now/crates/web-api/templates/billing.html-9-
billing
/home/josie/development/irc-now/crates/web-api/templates/billing.html-10-
/home/josie/development/irc-now/crates/web-api/templates/billing.html:11:
current plan
/home/josie/development/irc-now/crates/web-api/templates/billing.html:12:
{{ plan }}
/home/josie/development/irc-now/crates/web-api/templates/billing.html-13- {% if is_pro %}
/home/josie/development/irc-now/crates/web-api/templates/billing.html-14-
manage subscription
/home/josie/development/irc-now/crates/web-api/templates/billing.html-15- {% else %}
--
/home/josie/development/irc-now/crates/web-api/src/auth_guard.rs-34- };
/home/josie/development/irc-now/crates/web-api/src/auth_guard.rs-35-
/home/josie/development/irc-now/crates/web-api/src/auth_guard.rs-36- let suspended: Option
= sqlx::query_scalar(
/home/josie/development/irc-now/crates/web-api/src/auth_guard.rs:37: "SELECT suspended_at IS NOT NULL FROM users WHERE keycloak_sub = $1",
/home/josie/development/irc-now/crates/web-api/src/auth_guard.rs-38- )
/home/josie/development/irc-now/crates/web-api/src/auth_guard.rs-39- .bind(&claims.sub)
/home/josie/development/irc-now/crates/web-api/src/auth_guard.rs-40- .fetch_optional(&state.db)
--
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-55- }
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-56-
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-57- let upgrades_30d: i64 = sqlx::query_scalar(
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs:58: "SELECT COUNT(*) FROM events WHERE event_type = 'plan_upgrade' AND created_at > NOW() - INTERVAL '30 days'",
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-59- )
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-60- .fetch_one(&db)
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-61- .await
--
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-76- gauge!("irc_now_conversion_rate_30d").set(conversion_rate);
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-77-
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-78- let downgrades_30d: i64 = sqlx::query_scalar(
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs:79: "SELECT COUNT(*) FROM events WHERE event_type = 'plan_downgrade' AND created_at > NOW() - INTERVAL '30 days'",
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-80- )
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-81- .fetch_one(&db)
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-82- .await
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-83- .unwrap_or(0);
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-84-
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-85- let pro_users: i64 = sqlx::query_scalar(
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs:86: "SELECT COUNT(*) FROM users WHERE plan = 'pro'",
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-87- )
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-88- .fetch_one(&db)
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-89- .await
--
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-106- }
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-107-
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-108- if let Ok(rows) = sqlx::query_as::<_, (String, i64)>(
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs:109: "SELECT plan, COUNT(*) FROM users GROUP BY plan",
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-110- )
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-111- .fetch_all(&db)
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-112- .await
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-113- {
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs:114: for (plan, count) in rows {
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs:115: gauge!("irc_now_users_by_plan", "plan" => plan).set(count as f64);
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-116- }
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-117- }
/home/josie/development/irc-now/crates/web-api/src/business_metrics.rs-118- }
--
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-16-#[template(path = "billing.html")]
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-17-pub struct BillingTemplate {
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-18- pub page: PageContext,
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:19: pub plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-20- pub is_pro: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-21-}
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-22-
--
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-25- headers: HeaderMap,
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-26- AuthUser(user): AuthUser,
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-27-) -> impl IntoResponse {
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:28: let plan = user.plan.unwrap_or_else(|| "free".to_string());
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:29: let is_pro = plan == "pro";
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-30-
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-31- let page = PageContext::from_request(&headers, &state.announcement);
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-32- let clear = page.flash.is_some();
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-33-
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:34: let template = BillingTemplate { page, plan, is_pro };
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-35-
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-36- if clear {
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-37- (axum::response::AppendHeaders([flash::clear_flash()]), template).into_response()
--
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-63- }
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-64-
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-65- let mut metadata = std::collections::HashMap::new();
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:66: metadata.insert("keycloak_sub".to_string(), user.sub.clone());
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-67- params.metadata = Some(metadata);
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-68-
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-69- let session = match stripe::CheckoutSession::create(&state.stripe_client, params).await {
--
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-148- let customer = event.data.object.get("customer")
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-149- .and_then(|v| v.as_str());
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-150- let sub = event.data.object.get("metadata")
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:151: .and_then(|m| m.get("keycloak_sub"))
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-152- .and_then(|v| v.as_str());
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-153-
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-154- if let (Some(customer), Some(sub)) = (customer, sub) {
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-155- let result = sqlx::query(
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:156: "UPDATE users SET plan = 'pro', stripe_customer_id = $1 WHERE keycloak_sub = $2 AND plan != 'pro'",
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-157- )
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-158- .bind(customer)
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-159- .bind(sub)
--
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-169- tracing::warn!("keycloak attribute sync after upgrade failed: {e}");
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-170- }
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-171- crate::events::record(
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:172: &state.db, sub, "plan_upgrade",
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-173- Some(serde_json::json!({"from": "free", "to": "pro"})),
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-174- ).await;
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-175- }
--
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-183-
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-184- if let Some(customer) = customer {
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-185- let sub: Option = sqlx::query_scalar(
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:186: "UPDATE users SET plan = 'free' WHERE stripe_customer_id = $1 RETURNING keycloak_sub",
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-187- )
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-188- .bind(customer)
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-189- .fetch_optional(&state.db)
--
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-195- tracing::warn!("keycloak attribute sync after downgrade failed: {e}");
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-196- }
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-197- crate::events::record(
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs:198: &state.db, &sub, "plan_downgrade",
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-199- Some(serde_json::json!({"from": "pro", "to": "free"})),
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-200- ).await;
/home/josie/development/irc-now/crates/web-api/src/routes/billing.rs-201- }
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-332-
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-333-#[derive(FromRow)]
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-334-struct UserSearchRow {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:335: keycloak_sub: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-336- email: Option,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:337: plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-338- is_admin: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-339- suspended_at: Option>,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-340- created_at: Option>,
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-344-pub struct UserSearchEntry {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-345- pub sub: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-346- pub email: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:347: pub plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-348- pub is_admin: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-349- pub suspended: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-350- pub created_at: String,
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-374-
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-375- let rows = if query.is_empty() {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-376- sqlx::query_as::<_, UserSearchRow>(
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:377: "SELECT keycloak_sub, email, plan, is_admin, suspended_at, created_at
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-378- FROM users ORDER BY created_at DESC LIMIT 50",
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-379- )
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-380- .fetch_all(&state.db)
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-381- .await
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-382- } else {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-383- sqlx::query_as::<_, UserSearchRow>(
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:384: "SELECT keycloak_sub, email, plan, is_admin, suspended_at, created_at
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:385: FROM users WHERE email ILIKE $1 OR keycloak_sub = $2
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-386- ORDER BY created_at DESC LIMIT 50",
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-387- )
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-388- .bind(format!("%{query}%"))
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-399- let users = rows
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-400- .into_iter()
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-401- .map(|r| UserSearchEntry {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:402: sub: r.keycloak_sub,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-403- email: r.email.unwrap_or_default(),
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:404: plan: r.plan,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-405- is_admin: r.is_admin,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-406- suspended: r.suspended_at.is_some(),
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-407- created_at: r
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-416-
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-417-#[derive(FromRow)]
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-418-struct UserDetailRow {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:419: keycloak_sub: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-420- email: Option,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:421: plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-422- display_name: Option,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-423- is_admin: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-424- suspended_at: Option>,
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-438- pub sub: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-439- pub email: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-440- pub display_name: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:441: pub plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-442- pub is_admin: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-443- pub suspended: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-444- pub suspended_reason: String,
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-455- let clear = page.flash.is_some();
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-456-
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-457- let row = sqlx::query_as::<_, UserDetailRow>(
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:458: "SELECT keycloak_sub, email, plan, display_name, is_admin, suspended_at, suspended_reason, created_at
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:459: FROM users WHERE keycloak_sub = $1",
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-460- )
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-461- .bind(&sub)
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-462- .fetch_optional(&state.db)
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-478- let template = AdminUserDetailTemplate {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-479- page,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-480- user: UserDetailView {
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:481: sub: row.keycloak_sub,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-482- email: row.email.unwrap_or_default(),
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-483- display_name: row.display_name.unwrap_or_default(),
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:484: plan: row.plan,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-485- is_admin: row.is_admin,
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-486- suspended: row.suspended_at.is_some(),
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-487- suspended_reason: row.suspended_reason.unwrap_or_default(),
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-519- }
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-520-
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-521- let _ = sqlx::query(
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:522: "UPDATE users SET suspended_at = NOW(), suspended_reason = $1 WHERE keycloak_sub = $2",
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-523- )
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-524- .bind(&reason)
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-525- .bind(&sub)
--
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-553- }
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-554-
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-555- let _ = sqlx::query(
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs:556: "UPDATE users SET suspended_at = NULL, suspended_reason = NULL WHERE keycloak_sub = $1",
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-557- )
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-558- .bind(&sub)
/home/josie/development/irc-now/crates/web-api/src/routes/admin.rs-559- .execute(&state.db)
--
/home/josie/development/irc-now/crates/web-api/src/routes/bot.rs-214-
/home/josie/development/irc-now/crates/web-api/src/routes/bot.rs-215- let body = serde_json::json!({
/home/josie/development/irc-now/crates/web-api/src/routes/bot.rs-216- "user_id": user.sub,
/home/josie/development/irc-now/crates/web-api/src/routes/bot.rs:217: "plan": user.plan.as_deref().unwrap_or("free"),
/home/josie/development/irc-now/crates/web-api/src/routes/bot.rs-218- "name": form.name.trim(),
/home/josie/development/irc-now/crates/web-api/src/routes/bot.rs-219- "nick": nick,
/home/josie/development/irc-now/crates/web-api/src/routes/bot.rs-220- "network_addr": network_addr,
--
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-40-
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-41-#[derive(FromRow)]
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-42-struct UserRow {
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs:43: plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-44- stripe_customer_id: Option,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-45- display_name: Option,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-46- content_expires: bool,
--
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-150- let email = payload.userinfo.email.as_deref();
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-151-
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-152- let row = sqlx::query_as::<_, UserRow>(
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs:153: "INSERT INTO users (keycloak_sub, email)
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-154- VALUES ($1, $2)
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs:155: ON CONFLICT (keycloak_sub) DO UPDATE SET email = EXCLUDED.email, last_login_at = NOW()
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs:156: RETURNING plan, stripe_customer_id, display_name, content_expires, is_admin, created_at, (xmax = 0) AS is_new",
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-157- )
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-158- .bind(sub)
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-159- .bind(email)
--
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-174- let claims = UserClaims {
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-175- sub: sub.clone(),
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-176- email: email.map(String::from),
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs:177: plan: Some(row.plan.clone()),
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-178- stripe_customer_id: row.stripe_customer_id,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-179- display_name: row.display_name,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-180- content_expires: Some(row.content_expires),
--
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-184- if let Err(e) = update_keycloak_user_attributes(
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-185- &state,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-186- sub,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs:187: &row.plan,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-188- row.content_expires,
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-189- )
/home/josie/development/irc-now/crates/web-api/src/routes/auth.rs-190- .await
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-19-struct ProfileRow {
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-20- email: Option,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-21- display_name: Option,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:22: plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-23- created_at: String,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-24- content_expires: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-25-}
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-30- pub page: PageContext,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-31- pub display_name: String,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-32- pub email: String,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:33: pub plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-34- pub sub: String,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-35- pub created_at: String,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-36- pub password_url: String,
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-43- AuthUser(user): AuthUser,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-44-) -> Result {
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-45- let row = sqlx::query_as::<_, ProfileRow>(
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:46: "SELECT email, display_name, plan, to_char(created_at, 'YYYY-MM-DD') AS created_at, content_expires FROM users WHERE keycloak_sub = $1",
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-47- )
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-48- .bind(&user.sub)
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-49- .fetch_one(&state.db)
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-65- page,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-66- display_name: row.display_name.unwrap_or_default(),
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-67- email: row.email.unwrap_or_default(),
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:68: plan: row.plan,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-69- sub: user.sub,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-70- created_at: row.created_at,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-71- password_url,
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-121- };
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-122-
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-123- let result = sqlx::query(
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:124: "UPDATE users SET display_name = $1, email = $2, content_expires = $3 WHERE keycloak_sub = $4",
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-125- )
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-126- .bind(display_name_val)
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-127- .bind(&new_email)
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-135- return flash_response(&headers, "profile_save_failed", "/profile");
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-136- }
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-137-
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:138: let plan_str = user.plan.as_deref().unwrap_or("free");
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-139- if let Err(e) = update_keycloak_user_attributes(
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-140- &state,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-141- &user.sub,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:142: plan_str,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-143- content_expires,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-144- )
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-145- .await
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-154- } else {
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-155- Some(new_email)
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-156- },
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:157: plan: user.plan,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-158- stripe_customer_id: user.stripe_customer_id,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-159- display_name: if display_name.is_empty() {
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-160- None
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-187-pub(crate) async fn update_keycloak_user_attributes(
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-188- state: &AppState,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-189- sub: &str,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:190: plan: &str,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-191- content_expires: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-192-) -> Result<(), String> {
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-193- let token = crate::keycloak::get_admin_token(state).await?;
--
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-208- .bearer_auth(&token)
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-209- .json(&serde_json::json!({
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-210- "attributes": {
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs:211: "plan": [plan],
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-212- "content_expires": [content_expires.to_string()]
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-213- }
/home/josie/development/irc-now/crates/web-api/src/routes/profile.rs-214- }))
--
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-20- pub has_bouncer: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-21- pub bouncer_ready: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-22- pub is_pro: bool,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs:23: pub plan: String,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-24- pub networks: i64,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-25- pub channels: i64,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-26- pub messages_relayed: i64,
--
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-92- .map(|c| c.status == "True")
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-93- .unwrap_or(false);
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-94-
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs:95: let plan = user.plan.unwrap_or_else(|| "free".to_string());
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs:96: let is_pro = plan == "pro";
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-97-
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-98- let (mut networks, mut channels, mut messages_relayed) = (0i64, 0i64, 0i64);
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-99- let mut bouncer_uptime = "--".to_string();
--
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-153- has_bouncer,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-154- bouncer_ready,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-155- is_pro,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs:156: plan,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-157- networks,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-158- channels,
/home/josie/development/irc-now/crates/web-api/src/routes/dashboard.rs-159- messages_relayed,