public function isUserAuthenticated($auth_required = true) { // Cached Result... (if checked before, return the result) if ($this->authentication != self::AUTH_UNKNOWN) { return $this->authentication == self::AUTH_PASSED; } // Check Token Validity -- Avoid DB Overhead if (self::isSessionIDValid($this->id)) { $db = Database::getConnection(); $query = $db->query("SELECT user_id, update_timestamp, persistent FROM " . self::TABLE_NAME . " WHERE (id=:id) AND (expiry_timestamp > :now)", array(":id" => $this->id, ":now" => Carbon::now())); } else { if (!$auth_required) { return false; } } // Check Query Result (and that it was executed) if (isset($query) && $query && $query->rowCount()) { $db_row = $query->fetch(PDO::FETCH_ASSOC); $this->user_id = $db_row['user_id']; // only set here, force people to call this function first before being allowed to look at the ID // We need to renew sessions on a regular basis in order for us to determine when sessions become inactive... if (Carbon::parse($db_row['update_timestamp'])->diffInSeconds(Carbon::now()) > self::SESSION_RENEWAL_PERIOD_SECONDS) { $this->create($db_row['user_id'], isTrue($db_row['persistent'])); } // renew $this->authentication = self::AUTH_PASSED; return true; } else { if ($auth_required) { // Determine the Current Target/Action $request = RequestModel::currentRequest(); $router = RouteController::getController(); $route = $router->findRouteForURL($request->url()); // Add Query Params? $url = $router->urlForAction($route->action(), $route->extractArgs($request->url())); if (count($request->queryArgArray())) { $url = addQueryParams($url, $request->queryArgArray()); } // Request a Login AppController::requestUserLogin($url); // we need to extract and re-inject any args or we lose context... } else { $this->authentication = self::AUTH_FAILED; return false; } } }
public static function redirect($url, $query_parameters = array()) { $request = RequestModel::currentRequest(); $redirect_host = parse_url($url, PHP_URL_HOST); // Check that we're redirecting to our own domain, avoids potential security issues... if (!isValidURL($url)) { $url = '/'; // fallback } else { if ($redirect_host !== HOSTNAME) { // Remote Domain! (new Log(SECURITY_LOG))->logMessage("Attempted redirect to external URL: {$url}"); $url = '/'; // fallback } else { // URL is OK, modify the existing URL if parameters were specified... if (!empty($query_parameters)) { $url = addQueryParams($url, $query_parameters); } } } // OK to Redirect User? if (headers_sent($file, $line)) { // Log Error (new Log(ERROR_LOG))->logMessage("Unable to redirect, headers already sent in {$file} on line {$line}"); // Ask user for manual redirection... echo "Unable to redirect automatically, please click this link: <a href=\"{$url}\">{$url}</a>"; } else { // We're OK to Redirect header("Location: {$url}"); } exit; // terminate }
public function resetPassword() { $this->view = new HTMLView(); if ($this->request->isPOST()) { $post = $this->request->postData(); $user = new UserModel(); if ($this->request->isQueryArgSet('token')) { if ($user->getUserForPasswordResetToken($this->request->queryArgValue('token'))) { $user->password = @$post['password']; if ($user->save()) { $user->deletePasswordResetTokens(); $alert = new Alert(Alert::SUCCESS); $alert->addMessage('Password Set, Please Login'); } else { $alert = new Alert(Alert::ERROR); $alert->addMessageArray($user->getErrors()); } $this->view->includeTemplate('auth.reset-password.password', ['app_name' => AppConfig::getValue('app_name'), 'alert' => $alert]); } else { AppController::redirect(RouteController::fqURL('resetPassword'), ['status' => 'token-expired']); } } else { if ($post['email'] && $user->find($post['email'], 'email')) { $token = $user->getPasswordResetTokenData(); if ($token['last_email_timestamp'] <= Carbon::now()->subMinutes(pow(2, $token['email_attempts']))) { $user->incrementPasswordResetEmailCount(); $link = addQueryParams(RouteController::fqURL('resetPassword'), ['token' => $token['token']]); // Send Email $mailer = new Mailer(); $mailer->setSubject('Password Reset Token'); $mailer->addAddress($user->email); $mailer->includeHTMLTemplate('email.reset-password', ['link' => $link]); $mailer->send(); // errors handled within // Show Message $alert = new Alert(Alert::SUCCESS); $alert->addMessage('Email Sent'); } else { $alert = new Alert(Alert::ERROR); $alert->addMessage('Too Many Attempts, Please Try Again Later'); } $this->view->includeTemplate('auth.reset-password.email', ['app_name' => AppConfig::getValue('app_name'), 'alert' => $alert]); } else { $alert = new Alert(Alert::ERROR); $alert->addMessage('Email is Invalid/Non-Existent'); $this->view->includeTemplate('auth.reset-password.email', ['app_name' => AppConfig::getValue('app_name'), 'alert' => $alert]); } } } else { if ($this->request->isQueryArgSet('token')) { $user = new UserModel(); if ($user->getUserForPasswordResetToken($this->request->queryArgValue('token'))) { $this->view->includeTemplate('auth.reset-password.password', ['app_name' => AppConfig::getValue('app_name')]); } else { AppController::redirect(RouteController::fqURL('resetPassword'), ['status' => 'token-expired']); } } else { if ($this->request->isQueryArgSet('status') && $this->request->queryArgValue('status') == 'token-expired') { $alert = new Alert(Alert::ERROR); $alert->addMessage('Token is Invalid/Expired, Please Request a New One'); } $this->view->includeTemplate('auth.reset-password.email', ['app_name' => AppConfig::getValue('app_name'), 'alert' => isset($alert) ? $alert : null]); } } $this->view->render(true); }
<html lang="en"> <?php require HTMLView::pathForTemplate('layout.head'); ?> <body> <div class="container"> <h1>Payment Method</h1> <h3>Cards</h3> <?php if (!empty($cards) && is_array($cards)) { echo '<table style="width: 100%; text-align: center;"><tr><th></th><th>Expires</th></tr>'; foreach ($cards as $card) { // Create Row HTML printf('<tr><td>%s ending %s (<a href="%s">delete</a>)</td><td>%02d/%s</td></tr>', $card['brand'], $card['last4'], addQueryParams(RouteController::fqURL('subscription.payment'), ['card' => $card['id'], 'action' => 'remove-card']), $card['expiry_month'], substr($card['expiry_year'], 2)); } echo '</table>'; } ?> <h3>Add New Card</h3> <p style="color: red; font-size: 13px;">Valid TESTING Values</p> <form id="add-card" action="javascript:void(0);"> <?php CSRFPRotection::generateHTMLTag(); ?> <label>Card Number:</label> <input type="text" id="card-number" style="width: 200px;" maxlength="19" value="4242424242424242"> <br><br> <label>Expires:</label> <select id="expiry-month">
public function payment() { $user = $this->session->user(); if ($this->request->isPOST()) { $post = $this->request->postData(); if (!empty($post['token'])) { try { \Stripe\Stripe::setApiKey(AppConfig::getValue('stripe_secret_api_key')); // New Customer? if (!$user->isStripeCustomer()) { $newCustomer = true; // Create Customer $customer = \Stripe\Customer::create(['email' => $user->email]); $user->setStripeData(['customer_id' => $customer->id]); $user->save(); // save now! } else { $newCustomer = false; // Fetch Customer $customer = $this->getCustomer($user); } // Add/Create Card $customer->sources->create(['card' => $post['token']]); // Done, Redirect... AppController::redirect(addQueryParams(RouteController::fqURL($newCustomer ? 'subscription.plan' : 'subscription.payment'), ['status' => 'card-added'])); } catch (\Stripe\Error\Card $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\InvalidRequest $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\Authentication $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\ApiConnection $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\Base $exception) { $this->logStripeException($exception, $user->email); } } else { AppController::fatalError('token (required) was missing from the request'); } } else { if ($this->request->isQueryArgSet('card') && $this->request->queryArgValue('action') === 'remove-card') { try { \Stripe\Stripe::setApiKey(AppConfig::getValue('stripe_secret_api_key')); // Fetch Customer and Cards $customer = $this->getCustomer($user); $cards = $this->getCardsOnFile($customer); // Enough Cards? (backup) if ($cards && count($cards['data']) > 1) { // Remove Card $customer->sources->retrieve($this->request->queryArgValue('card'))->delete(); // Done, Redirect... AppController::redirect(addQueryParams(RouteController::fqURL('subscription.payment'), ['status' => 'card-removed'])); } else { // Need to Add a Card First (or cancel subscription) AppController::redirect(addQueryParams(RouteController::fqURL('subscription.payment'), ['status' => 'no-backup'])); } } catch (\Stripe\Error\Card $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\InvalidRequest $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\Authentication $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\ApiConnection $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\Base $exception) { $this->logStripeException($exception, $user->email); } } } try { if (!isset($customer) && $user->isStripeCustomer()) { \Stripe\Stripe::setApiKey(AppConfig::getValue('stripe_secret_api_key')); $customer = $this->getCustomer($user); $cards = $this->getCardsOnFile($customer); foreach ($cards['data'] as $card) { $cardList[] = ['id' => $card->id, 'last4' => $card->last4, 'brand' => $card->brand, 'expiry_month' => $card->exp_month, 'expiry_year' => $card->exp_year]; } } } catch (\Stripe\Error\Card $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\InvalidRequest $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\Authentication $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\ApiConnection $exception) { $this->logStripeException($exception, $user->email); } catch (\Stripe\Error\Base $exception) { $this->logStripeException($exception, $user->email); } $this->view = new HTMLView(); $this->view->includeTemplate('subscription.payment', ['app_name' => AppConfig::getValue('app_name'), 'cards' => isset($cardList) ? $cardList : null]); $this->view->render(true); }