/** * Call this function only after we have successfully logged in. * Updates user status etc. */ function handle_post_login() { global $messages; if (!isset($messages)) { // we might be in auto-login, create a temporary message field anyway $messages = array(); } $user = get_user(user_id()); // display warning if account was disabled if ($user['is_disabled']) { $messages[] = t("Your account was disabled :ago due to inactivity; your account is now re-enabled, and account data will be updated again soon.", array(':ago' => recent_format($user['disabled_at']))); $q = db()->prepare("UPDATE user_properties SET is_disabled=0,logins_after_disabled=logins_after_disabled+1 WHERE id=?"); $q->execute(array($user['id'])); } // keep track of users that logged in after receiving a warning if ($user['is_disable_warned']) { $q = db()->prepare("UPDATE user_properties SET is_disable_warned=0,logins_after_disable_warned=logins_after_disable_warned+1 WHERE id=?"); $q->execute(array($user['id'])); } // update locale if ($user['locale']) { I18n::setLocale($user['locale']); } // update login time $query = db()->prepare("UPDATE user_properties SET last_login=NOW(),is_disabled=0 WHERE id=?"); $query->execute(array($user["id"])); // if we don't have an IP set, update it now if (!$user["user_ip"]) { $q = db()->prepare("UPDATE user_properties SET user_ip=? WHERE id=?"); $q->execute(array(user_ip(), $user['id'])); } }
/** * Implements failing tables; if an account type fails multiple times, * then send the user an email and disable the account. * @see OpenclerkJobQueuer#getStandardJobs() */ function failed(\Exception $runtime_exception, Connection $db, Logger $logger) { // is this a standard job? $standard = $this->findStandardJob(); if ($standard) { $logger->info("Using standard job " . print_r($standard, true)); if (!$standard['failure']) { $logger->info("Not a failure standard job"); return; } } else { return; } $failing_table = $standard['table']; $job = $this->job; // find the relevant account_data for this standard job $account_data = false; foreach (account_data_grouped() as $label => $group) { foreach ($group as $exchange => $data) { if (isset($data['job_type']) && $job['job_type'] == $data['job_type']) { $account_data = $data; $account_data['exchange'] = $exchange; break; } } } if (!$account_data) { $logger->warn("Could not find any account data for job type '" . $job['job_type'] . "'"); } $logger->info("Using account data " . print_r($account_data, true)); // don't count CloudFlare as a failure if ($runtime_exception instanceof CloudFlareException || $runtime_exception instanceof \Openclerk\Apis\CloudFlareException) { $logger->info("Not increasing failure count: was a CloudFlareException"); } else { if ($runtime_exception instanceof IncapsulaException || $runtime_exception instanceof \Openclerk\Apis\IncapsulaException) { $logger->info("Not increasing failure count: was a IncapsulaException"); } else { if ($runtime_exception instanceof BlockchainException || $runtime_exception instanceof \Core\BlockchainException) { $logger->info("Not increasing failure count: was a BlockchainException"); } else { $q = $db->prepare("UPDATE {$failing_table} SET failures=failures+1,first_failure=IF(ISNULL(first_failure), NOW(), first_failure) WHERE id=?"); $q->execute(array($job['arg_id'])); $logger->info("Increasing account failure count"); } } } $user = get_user($job['user_id']); if (!$user) { $logger->info("Warning: No user " . $job['user_id'] . " found"); } else { // failed too many times? $q = $db->prepare("SELECT * FROM {$failing_table} WHERE id=? LIMIT 1"); $q->execute(array($job['arg_id'])); $account = $q->fetch(); $logger->info("Current account failure count: " . number_format($account['failures'])); if ($account['failures'] >= get_premium_value($user, 'max_failures')) { // disable it and send an email $q = $db->prepare("UPDATE {$failing_table} SET is_disabled=1 WHERE id=?"); $q->execute(array($job['arg_id'])); crypto_log(print_r($account_data, true)); if ($user['email'] && !$account['is_disabled']) { $email_type = $job['job_type'] == "notification" ? "failure_notification" : "failure"; send_user_email($user, $email_type, array("name" => $user['name'] ? $user['name'] : $user['email'], "exchange" => get_exchange_name($account_data['exchange']), "label" => $account_data['label'], "labels" => $account_data['labels'], "failures" => number_format($account['failures']), "message" => $runtime_exception->getMessage(), "length" => recent_format(strtotime($account['first_failure']), "", ""), "title" => isset($account['title']) && $account['title'] ? "\"" . $account['title'] . "\"" : "untitled", "url" => absolute_url(url_for("wizard_accounts")))); $logger->info("Sent failure e-mail to " . htmlspecialchars($user['email']) . "."); } } } }
function recent_format_html($date, $suffix = false, $future_suffix = false) { return '<span title="' . ($date ? htmlspecialchars(iso_date($date)) : ht("Never")) . '">' . recent_format($date, $suffix, $future_suffix) . '</span>'; }
<?php /** * An existing free user has not logged in within X days and we * now need to disable their account. */ // get the relevant user info $user = get_user($job['arg_id']); if (!$user) { throw new JobException("Cannot find user ID " . $job['arg_id']); } // check that they're not a premium user etc - this should never happen if ($user['is_premium']) { throw new JobException("Premium user was requested to be disabled - this should not happen"); } // update user (before sending email) $q = db()->prepare("UPDATE user_properties SET is_disabled=1,disabled_at=NOW() WHERE id=? LIMIT 1"); $q->execute(array($user['id'])); // construct email if ($user['email']) { $disables_at = strtotime(($user['last_login'] ? $user['last_login'] : $user['created_at']) . " +" . get_site_config('user_expiry_days') . " day"); send_user_email($user, "disable", array("name" => $user['name'] ? $user['name'] : $user['email'], "days" => number_format(get_site_config('user_expiry_days')), "disables" => iso_date($disables_at), "disables_text" => recent_format($disables_at, false, ""), "url" => absolute_url(url_for("user#user_premium")), "login" => absolute_url(url_for("login")), "profile" => absolute_url(url_for("profile")))); crypto_log("Sent disabled account e-mail to " . htmlspecialchars($user['email']) . "."); } else { crypto_log("User had no valid e-mail address."); }
$external[$e['job_type']] = $e; if ($first_first == 0 || strtotime($e['job_first']) < strtotime($first_first)) { $first_first = $e['job_first']; } $sample_size = $e['sample_size']; $last_updated = $e['created_at']; } ?> <h1><?php echo ht("External API Status"); ?> </h1> <p> <?php echo t(":site_name relies on the output of many external APIs.\n This page lists the current status of each of these APIs, as collected over the last :time (:samples samples).", array(':time' => recent_format($first_first, "", ""), ':samples' => number_format($sample_size))); ?> </p> <ul class="external_list"> <?php $external_apis = get_external_apis(); function get_error_class($n) { if ($n <= 0.1) { // 0% return "perfect"; } else { if ($n <= 5) { return "good"; } else {
<?php /** * An existing premium user's account needs to expire. * May send out an e-mail. */ // get the relevant user info $user = get_user($job['arg_id']); if (!$user) { throw new JobException("Cannot find user ID " . $job['arg_id']); } $was_premium = $user['is_premium']; // update user (before sending email) $q = db()->prepare("UPDATE user_properties SET updated_at=NOW(),is_premium=0 WHERE id=? LIMIT 1"); $q->execute(array($user['id'])); crypto_log("Disabled premium status on user " . $user['id'] . "."); // construct email, but only if we haven't already sent an email out if ($user['email'] && $was_premium) { send_user_email($user, "expire", array("name" => $user['name'] ? $user['name'] : $user['email'], "expires" => iso_date($user['premium_expires']), "expires_text" => recent_format($user['premium_expires'], false, ""), "prices" => get_text_premium_prices(), "prices_html" => get_html_premium_prices(), "url" => absolute_url(url_for("user#user_premium")))); crypto_log("Sent premium expired e-mail to " . htmlspecialchars($user['email']) . "."); } else { crypto_log("User had no valid e-mail address."); }
<?php /** * Outstanding premium payments job. */ // get the relevant premium and address info $q = db()->prepare("SELECT p.*,\n a.address, a.currency\n FROM outstanding_premiums AS p\n JOIN addresses AS a ON p.address_id=a.id\n WHERE p.id=?"); $q->execute(array($job['arg_id'])); $address = $q->fetch(); if (!$address) { throw new JobException("Cannot find outstanding ID " . $job['arg_id'] . " with a relevant address"); } $reminder = recent_format(strtotime("+" . get_site_config('outstanding_reminder_hours') . " hour"), false, ""); $cancelled = recent_format(strtotime("+" . get_site_config('outstanding_abandon_days') . " day"), false, ""); crypto_log("Reminders are sent every '{$reminder}'; cancelled after '{$cancelled}'."); // get current user $q = db()->prepare("SELECT * FROM user_properties WHERE id=?"); $q->execute(array($address['user_id'])); $user = $q->fetch(); if (!$user) { throw new JobException("Could not find user " . $address['user_id']); } // find the most recent balance $q = db()->prepare("SELECT * FROM address_balances WHERE address_id=? AND is_recent=1"); $q->execute(array($address['address_id'])); $balance = $q->fetch(); if (!$balance) { // no balance yet crypto_log("No balance retrieved yet."); } else { if ($address['balance'] == 0) {