This commit is contained in:
2025-02-06 14:48:46 +05:30
parent 1ff9cba2d0
commit e319f46ac2
32 changed files with 42 additions and 5450 deletions

View File

@@ -2,7 +2,7 @@
### Xeorl - The All-In-One, Fully Free to Use Advanced Link Shortener and Management Tool - Powered by [@xodivorce](https://instagram.com/xodivorce) ✨
[![status](https://img.shields.io/badge/status-active-brightgreen.svg?style=flat)](https://github.com/xeorl/xeorl-portfolio/)
[![version](https://img.shields.io/badge/version-v4.2.5-yellow.svg?style=flat)](https://github.com/xeorl/xeorl-portfolio/)
[![version](https://img.shields.io/badge/version-v4.2.6-yellow.svg?style=flat)](https://github.com/xeorl/xeorl-portfolio/)
[![PRs](https://img.shields.io/badge/PRs-welcome-blue.svg?style=flat)](https://github.com/xeorl/xeorl-portfolio/)
<br></br>

BIN
htdocs/.DS_Store vendored

Binary file not shown.

View File

@@ -25,7 +25,9 @@ if (!isset($_SESSION['user_id'])) {
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/_monetization.css">
<link rel="stylesheet" href="assets/css/_account.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<?php include "assets/_header.php"; ?>

Binary file not shown.

View File

@@ -15,9 +15,9 @@
</script>
</p>
<div class="footer-links">
<a href="#">Privacy</a>
<a href="#">Terms</a>
<a href="#">Contact</a>
<a href="https://docs.google.com/document/d/1sZ2TwjST8nKaRl-rSteAd2XHlVZdDhgS6jHRKwjDedc/edit?usp=sharing">Privacy</a>
<a href="https://docs.google.com/document/d/1QcUohit6U3ZmWyOZbggbpUr2KrQ6pwy3X-R4zUGfZBo/edit?usp=sharing">Terms</a>
<a href="home.php">Contact</a>
<a href="https://github.com/xodivorce/xeorl" target="_blank" >Github</a>
</div>
</div>

View File

@@ -10,7 +10,7 @@ if (session_status() === PHP_SESSION_NONE) {
<div class="logo">
<img src="assets/images/url.png" alt="Xeorl Logo" class="logo-img">
<span>Xeorl</span>
<span class="version-number">4.2.5</span>
<span class="version-number">4.2.6</span>
</div>
<label class="burger">

View File

@@ -1,120 +1,12 @@
/* General Styles */
body {
font-family: "Montserrat", sans-serif;
margin: 0;
padding: 0;
display: flex;
height: 100vh;
background-color: #ffffff;
color: #111313;
color: #333333;
}
/* User Image */
.user-image {
width: 40px;
height: 40px;
margin-top: -5px;
border-radius: 50%;
margin-left: 25px;
border: 1px solid #ffffff;
}
/* Sidebar Styles */
.sidebar {
width: 20%;
background-color: #ffffff;
color: #98E5DD;
display: flex;
flex-direction: column;
border: solid 1px rgb(58, 66, 65);
padding: 20px;
}
/* Sidebar Header (Flexbox) */
.sidebar .sidebar-header {
display: flex;
flex-wrap: wrap; /* Allows wrapping when screen is small */
align-items: center; /* Ensures vertical alignment */
margin-left: -25px;
margin-right: -20px;
margin-top: 45px;
}
/* Image & Text Flexbox */
.sidebar .sidebar-header .user-image {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}
.user-info {
font-size: 14px;
margin-bottom: 20px;
line-height: 1.4;
color: #171c24;
}
.user-email {
color: #677583;
}
/* Sidebar Links */
.sidebar a {
text-decoration: none;
color: #171c24;
padding: 15px;
display: block;
font-size: 16px;
transition: background-color 0.3s ease; /* Keep only background-color for transition */
}
/* Main Content */
.content {
width: 80%;
padding: 20px;
}
.content h2, .content h3 {
color: #EEB58F;
}
/* Responsive Design */
@media screen and (max-width: 768px) {
body {
flex-direction: column;
}
.sidebar {
width: 100%;
height: auto;
display: flex;
flex-direction: row;
justify-content: space-around;
padding: 10px;
}
.sidebar .sidebar-header {
justify-content: flex-start;
text-align: center;
margin-left: 0;
margin-right: 0;
}
.sidebar .sidebar-header .user-image {
margin-left: 0;
margin-right: 10px;
}
.user-info {
font-size: 12px;
text-align: left;
}
.content {
width: 100%;
padding: 20px;
}
}
main {
padding: 60px 20px;
text-align: center;
}

BIN
htdocs/core/.DS_Store vendored

Binary file not shown.

View File

@@ -1,22 +0,0 @@
Copyright (c) 2009 Abraham Williams - http://abrah.am - abraham@abrah.am
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,35 +0,0 @@
<?php
/**
* Use to autoload needed classes without Composer.
*
* @param string $class The fully-qualified class name.
* @return void
*/
spl_autoload_register(function ($class) {
// project-specific namespace prefix
$prefix = 'Abraham\\TwitterOAuth\\';
// base directory for the namespace prefix
$base_dir = __DIR__ . '/src/';
// does the class use the namespace prefix?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// no, move to the next registered autoloader
return;
}
// get the relative class name
$relative_class = substr($class, $len);
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require $file;
}
});

View File

@@ -1,52 +0,0 @@
{
"name": "abraham/twitteroauth",
"type": "library",
"description": "The most popular PHP library for use with the Twitter OAuth REST API.",
"keywords": [
"twitter",
"api",
"oauth",
"rest",
"social",
"twitter api",
"twitter oauth"
],
"license": "MIT",
"homepage": "https://twitteroauth.com",
"authors": [
{
"name": "Abraham Williams",
"email": "abraham@abrah.am",
"homepage": "https://abrah.am",
"role": "Developer"
}
],
"support": {
"source": "https://github.com/abraham/twitteroauth",
"issues": "https://github.com/abraham/twitteroauth/issues"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/abraham/phpunit-testlistener-vcr"
}
],
"require": {
"php": "8.*",
"ext-curl": "*",
"composer/ca-bundle": "^1.2"
},
"require-dev": {
"phpunit/phpunit": "^9",
"squizlabs/php_codesniffer": "^3",
"phpmd/phpmd": "^2",
"php-vcr/php-vcr": "^1",
"php-vcr/phpunit-testlistener-vcr": "dev-php8",
"rector/rector": "^0.15.7"
},
"autoload": {
"psr-4": {
"Abraham\\TwitterOAuth\\": "src"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +0,0 @@
<?php
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
/**
* Handle setting and storing config for TwitterOAuth.
*
* @author Abraham Williams <abraham@abrah.am>
*/
class Config
{
// Update extension function when updating this list.
private const SUPPORTED_VERSIONS = ['1.1', '2'];
/** @var int How long to wait for a response from the API */
protected $timeout = 5;
/** @var int how long to wait while connecting to the API */
protected $connectionTimeout = 5;
/** @var int How many times we retry request when API is down */
protected $maxRetries = 0;
/** @var int Delay in seconds before we retry the request */
protected $retriesDelay = 1;
/** @var string Version of the Twitter API requests should target */
protected $apiVersion = '2';
/**
* Decode JSON Response as associative Array
*
* @see http://php.net/manual/en/function.json-decode.php
*
* @var bool
*/
protected $decodeJsonAsArray = false;
/** @var string User-Agent header */
protected $userAgent = 'TwitterOAuth (+https://twitteroauth.com)';
/** @var array Store proxy connection details */
protected $proxy = [];
/** @var bool Whether to encode the curl requests with gzip or not */
protected $gzipEncoding = true;
/** @var integer Size for Chunked Uploads */
protected $chunkSize = 250000; // 0.25 MegaByte
/**
* Set the the Twitter API version.
*
* @param string $apiVersion
*/
public function setApiVersion(string $apiVersion): void
{
if (in_array($apiVersion, self::SUPPORTED_VERSIONS, true)) {
$this->apiVersion = $apiVersion;
} else {
throw new TwitterOAuthException('Unsupported API version');
}
}
/**
* Set the connection and response timeouts.
*
* @param int $connectionTimeout
* @param int $timeout
*/
public function setTimeouts(int $connectionTimeout, int $timeout): void
{
$this->connectionTimeout = $connectionTimeout;
$this->timeout = $timeout;
}
/**
* Set the number of times to retry on error and how long between each.
*
* @param int $maxRetries
* @param int $retriesDelay
*/
public function setRetries(int $maxRetries, int $retriesDelay): void
{
$this->maxRetries = $maxRetries;
$this->retriesDelay = $retriesDelay;
}
/**
* @param bool $value
*/
public function setDecodeJsonAsArray(bool $value): void
{
$this->decodeJsonAsArray = $value;
}
/**
* @param string $userAgent
*/
public function setUserAgent(string $userAgent): void
{
$this->userAgent = $userAgent;
}
/**
* @param array $proxy
*/
public function setProxy(array $proxy): void
{
$this->proxy = $proxy;
}
/**
* Whether to encode the curl requests with gzip or not.
*
* @param boolean $gzipEncoding
*/
public function setGzipEncoding(bool $gzipEncoding): void
{
$this->gzipEncoding = $gzipEncoding;
}
/**
* Set the size of each part of file for chunked media upload.
*
* @param int $value
*/
public function setChunkSize(int $value): void
{
$this->chunkSize = $value;
}
}

View File

@@ -1,43 +0,0 @@
<?php
/**
* The MIT License
* Copyright (c) 2007 Andy Smith
*/
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
class Consumer
{
/** @var string */
public $key;
/** @var string */
public $secret;
/** @var string|null */
public $callbackUrl;
/**
* @param string|null $key
* @param string|null $secret
* @param null $callbackUrl
*/
public function __construct(
?string $key,
?string $secret,
?string $callbackUrl = null,
) {
$this->key = $key;
$this->secret = $secret;
$this->callbackUrl = $callbackUrl;
}
/**
* @return string
*/
public function __toString()
{
return "Consumer[key=$this->key,secret=$this->secret]";
}
}

View File

@@ -1,46 +0,0 @@
<?php
/**
* The MIT License
* Copyright (c) 2007 Andy Smith
*/
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
/**
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
* where the Signature Base String is the text and the key is the concatenated values (each first
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
* character (ASCII code 38) even if empty.
* - Chapter 9.2 ("HMAC-SHA1")
*/
class HmacSha1 extends SignatureMethod
{
/**
* {@inheritDoc}
*/
public function getName()
{
return 'HMAC-SHA1';
}
/**
* {@inheritDoc}
*/
public function buildSignature(
Request $request,
Consumer $consumer,
Token $token = null,
): string {
$signatureBase = $request->getSignatureBaseString();
$parts = [$consumer->secret, null !== $token ? $token->secret : ''];
$parts = Util::urlencodeRfc3986($parts);
$key = implode('&', $parts);
return base64_encode(hash_hmac('sha1', $signatureBase, $key, true));
}
}

View File

@@ -1,286 +0,0 @@
<?php
/**
* The MIT License
* Copyright (c) 2007 Andy Smith
*/
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
class Request
{
protected $parameters;
protected $httpMethod;
protected $httpUrl;
public static $version = '1.0';
/**
* Constructor
*
* @param string $httpMethod
* @param string $httpUrl
* @param ?array $parameters
*/
public function __construct(
string $httpMethod,
string $httpUrl,
?array $parameters = [],
) {
$parameters = array_merge(
Util::parseParameters(parse_url($httpUrl, PHP_URL_QUERY)),
$parameters,
);
$this->parameters = $parameters;
$this->httpMethod = $httpMethod;
$this->httpUrl = $httpUrl;
}
/**
* pretty much a helper function to set up the request
*
* @param Consumer $consumer
* @param Token $token
* @param string $httpMethod
* @param string $httpUrl
* @param array $parameters
*
* @return Request
*/
public static function fromConsumerAndToken(
Consumer $consumer,
Token $token = null,
string $httpMethod,
string $httpUrl,
array $parameters = [],
array $options = [],
) {
$defaults = [
'oauth_version' => Request::$version,
'oauth_nonce' => Request::generateNonce(),
'oauth_timestamp' => time(),
'oauth_consumer_key' => $consumer->key,
];
if (null !== $token) {
$defaults['oauth_token'] = $token->key;
}
// The json payload is not included in the signature on json requests,
// therefore it shouldn't be included in the parameters array.
if ($options['jsonPayload'] ?? false) {
$parameters = $defaults;
} else {
$parameters = array_merge($defaults, $parameters);
}
return new Request($httpMethod, $httpUrl, $parameters);
}
/**
* @param string $name
* @param string $value
*/
public function setParameter(string $name, string $value)
{
$this->parameters[$name] = $value;
}
/**
* @param string $name
*
* @return string|null
*/
public function getParameter(string $name): ?string
{
return $this->parameters[$name] ?? null;
}
/**
* @return array
*/
public function getParameters(): array
{
return $this->parameters;
}
/**
* @param string $name
*/
public function removeParameter(string $name): void
{
unset($this->parameters[$name]);
}
/**
* The request parameters, sorted and concatenated into a normalized string.
*
* @return string
*/
public function getSignableParameters(): string
{
// Grab all parameters
$params = $this->parameters;
// Remove oauth_signature if present
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
if (isset($params['oauth_signature'])) {
unset($params['oauth_signature']);
}
return Util::buildHttpQuery($params);
}
/**
* Returns the base string of this request
*
* The base string defined as the method, the url
* and the parameters (normalized), each urlencoded
* and the concated with &.
*
* @return string
*/
public function getSignatureBaseString(): string
{
$parts = [
$this->getNormalizedHttpMethod(),
$this->getNormalizedHttpUrl(),
$this->getSignableParameters(),
];
$parts = Util::urlencodeRfc3986($parts);
return implode('&', $parts);
}
/**
* Returns the HTTP Method in uppercase
*
* @return string
*/
public function getNormalizedHttpMethod(): string
{
return strtoupper($this->httpMethod);
}
/**
* parses the url and rebuilds it to be
* scheme://host/path
*
* @return string
*/
public function getNormalizedHttpUrl(): string
{
$parts = parse_url($this->httpUrl);
$scheme = $parts['scheme'];
$host = strtolower($parts['host']);
$path = $parts['path'];
return "$scheme://$host$path";
}
/**
* Builds a url usable for a GET request
*
* @return string
*/
public function toUrl(): string
{
$postData = $this->toPostdata();
$out = $this->getNormalizedHttpUrl();
if ($postData) {
$out .= '?' . $postData;
}
return $out;
}
/**
* Builds the data one would send in a POST request
*
* @return string
*/
public function toPostdata(): string
{
return Util::buildHttpQuery($this->parameters);
}
/**
* Builds the Authorization: header
*
* @return string
* @throws TwitterOAuthException
*/
public function toHeader(): string
{
$first = true;
$out = 'Authorization: OAuth';
foreach ($this->parameters as $k => $v) {
if (substr($k, 0, 5) != 'oauth') {
continue;
}
if (is_array($v)) {
throw new TwitterOAuthException(
'Arrays not supported in headers',
);
}
$out .= $first ? ' ' : ', ';
$out .=
Util::urlencodeRfc3986($k) .
'="' .
Util::urlencodeRfc3986($v) .
'"';
$first = false;
}
return $out;
}
/**
* @return string
*/
public function __toString(): string
{
return $this->toUrl();
}
/**
* @param SignatureMethod $signatureMethod
* @param Consumer $consumer
* @param Token $token
*/
public function signRequest(
SignatureMethod $signatureMethod,
Consumer $consumer,
Token $token = null,
) {
$this->setParameter(
'oauth_signature_method',
$signatureMethod->getName(),
);
$signature = $this->buildSignature($signatureMethod, $consumer, $token);
$this->setParameter('oauth_signature', $signature);
}
/**
* @param SignatureMethod $signatureMethod
* @param Consumer $consumer
* @param Token $token
*
* @return string
*/
public function buildSignature(
SignatureMethod $signatureMethod,
Consumer $consumer,
Token $token = null,
): string {
return $signatureMethod->buildSignature($this, $consumer, $token);
}
/**
* @return string
*/
public static function generateNonce(): string
{
return md5(microtime() . random_int(PHP_INT_MIN, PHP_INT_MAX));
}
}

View File

@@ -1,109 +0,0 @@
<?php
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
/**
* The result of the most recent API request.
*
* @author Abraham Williams <abraham@abrah.am>
*/
class Response
{
/** @var string|null API path from the most recent request */
private ?string $apiPath = null;
/** @var int HTTP status code from the most recent request */
private int $httpCode = 0;
/** @var array HTTP headers from the most recent request */
private array $headers = [];
/** @var array|object|null Response body from the most recent request */
private array|object|null $body = [];
/** @var array HTTP headers from the most recent request that start with X */
private array $xHeaders = [];
/**
* @param string $apiPath
*/
public function setApiPath(string $apiPath): void
{
$this->apiPath = $apiPath;
}
/**
* @return string|null
*/
public function getApiPath(): ?string
{
return $this->apiPath;
}
/**
* @param array|object $body
*/
public function setBody($body)
{
$this->body = $body;
}
/**
* @return array|object|string
*/
public function getBody()
{
return $this->body;
}
/**
* @param int $httpCode
*/
public function setHttpCode(int $httpCode): void
{
$this->httpCode = $httpCode;
}
/**
* @return int
*/
public function getHttpCode(): int
{
return $this->httpCode;
}
/**
* @param array $headers
*/
public function setHeaders(array $headers): void
{
foreach ($headers as $key => $value) {
if (substr($key, 0, 1) == 'x') {
$this->xHeaders[$key] = $value;
}
}
$this->headers = $headers;
}
/**
* @return array
*/
public function getsHeaders(): array
{
return $this->headers;
}
/**
* @param array $xHeaders
*/
public function setXHeaders(array $xHeaders = []): void
{
$this->xHeaders = $xHeaders;
}
/**
* @return array
*/
public function getXHeaders(): array
{
return $this->xHeaders;
}
}

View File

@@ -1,78 +0,0 @@
<?php
/**
* The MIT License
* Copyright (c) 2007 Andy Smith
*/
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
/**
* A class for implementing a Signature Method
* See section 9 ("Signing Requests") in the spec
*/
abstract class SignatureMethod
{
/**
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
*
* @return string
*/
abstract public function getName();
/**
* Build up the signature
* NOTE: The output of this function MUST NOT be urlencoded.
* the encoding is handled in OAuthRequest when the final
* request is serialized
*
* @param Request $request
* @param Consumer $consumer
* @param Token $token
*
* @return string
*/
abstract public function buildSignature(
Request $request,
Consumer $consumer,
Token $token = null,
);
/**
* Verifies that a given signature is correct
*
* @param Request $request
* @param Consumer $consumer
* @param Token $token
* @param string $signature
*
* @return bool
*/
public function checkSignature(
Request $request,
Consumer $consumer,
Token $token,
string $signature,
): bool {
$built = $this->buildSignature($request, $consumer, $token);
// Check for zero length, although unlikely here
if (strlen($built) == 0 || strlen($signature) == 0) {
return false;
}
if (strlen($built) != strlen($signature)) {
return false;
}
// Avoid a timing leak with a (hopefully) time insensitive compare
$result = 0;
for ($i = 0; $i < strlen($signature); $i++) {
$result |= ord($built[$i]) ^ ord($signature[$i]);
}
return $result == 0;
}
}

View File

@@ -1,43 +0,0 @@
<?php
/**
* The MIT License
* Copyright (c) 2007 Andy Smith
*/
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
class Token
{
/** @var string */
public $key;
/** @var string */
public $secret;
/**
* @param string $key The OAuth Token
* @param string $secret The OAuth Token Secret
*/
public function __construct(?string $key, ?string $secret)
{
$this->key = $key;
$this->secret = $secret;
}
/**
* Generates the basic string serialization of a token that a server
* would respond to request_token and access_token calls with
*
* @return string
*/
public function __toString(): string
{
return sprintf(
'oauth_token=%s&oauth_token_secret=%s',
Util::urlencodeRfc3986($this->key),
Util::urlencodeRfc3986($this->secret),
);
}
}

View File

@@ -1,837 +0,0 @@
<?php
/**
* The most popular PHP library for use with the Twitter OAuth REST API.
*
* @license MIT
*/
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
use Abraham\TwitterOAuth\{
Consumer,
HmacSha1,
Response,
Token,
Util\JsonDecoder,
};
use Composer\CaBundle\CaBundle;
/**
* TwitterOAuth class for interacting with the Twitter API.
*
* @author Abraham Williams <abraham@abrah.am>
*/
class TwitterOAuth extends Config
{
private const API_HOST = 'https://api.twitter.com';
private const UPLOAD_HOST = 'https://upload.twitter.com';
/** @var Response details about the result of the last request */
private ?Response $response = null;
/** @var string|null Application bearer token */
private ?string $bearer = null;
/** @var Consumer Twitter application details */
private Consumer $consumer;
/** @var Token|null User access token details */
private ?Token $token = null;
/** @var HmacSha1 OAuth 1 signature type used by Twitter */
private HmacSha1 $signatureMethod;
/** @var int Number of attempts we made for the request */
private int $attempts = 0;
/**
* Constructor
*
* @param string $consumerKey The Application Consumer Key
* @param string $consumerSecret The Application Consumer Secret
* @param ?string $oauthToken The Client Token (optional)
* @param ?string $oauthTokenSecret The Client Token Secret (optional)
*/
public function __construct(
string $consumerKey,
string $consumerSecret,
?string $oauthToken = null,
?string $oauthTokenSecret = null,
) {
$this->resetLastResponse();
$this->signatureMethod = new HmacSha1();
$this->consumer = new Consumer($consumerKey, $consumerSecret);
if (!empty($oauthToken) && !empty($oauthTokenSecret)) {
$this->setOauthToken($oauthToken, $oauthTokenSecret);
}
if (empty($oauthToken) && !empty($oauthTokenSecret)) {
$this->setBearer($oauthTokenSecret);
}
}
/**
* @param string $oauthToken
* @param string $oauthTokenSecret
*/
public function setOauthToken(
string $oauthToken,
string $oauthTokenSecret,
): void {
$this->token = new Token($oauthToken, $oauthTokenSecret);
$this->bearer = null;
}
/**
* @param string $oauthTokenSecret
*/
public function setBearer(string $oauthTokenSecret): void
{
$this->bearer = $oauthTokenSecret;
$this->token = null;
}
/**
* @return string|null
*/
public function getLastApiPath(): ?string
{
return $this->response->getApiPath();
}
/**
* @return int
*/
public function getLastHttpCode(): int
{
return $this->response->getHttpCode();
}
/**
* @return array
*/
public function getLastXHeaders(): array
{
return $this->response->getXHeaders();
}
/**
* @return array|object|null
*/
public function getLastBody()
{
return $this->response->getBody();
}
/**
* Resets the last response cache.
*/
public function resetLastResponse(): void
{
$this->response = new Response();
}
/**
* Resets the attempts number.
*/
private function resetAttemptsNumber(): void
{
$this->attempts = 0;
}
/**
* Delays the retries when they're activated.
*/
private function sleepIfNeeded(): void
{
if ($this->maxRetries && $this->attempts) {
sleep($this->retriesDelay);
}
}
/**
* Make URLs for user browser navigation.
*
* @param string $path
* @param array $parameters
*
* @return string
*/
public function url(string $path, array $parameters): string
{
$this->resetLastResponse();
$this->response->setApiPath($path);
$query = http_build_query($parameters);
return sprintf('%s/%s?%s', self::API_HOST, $path, $query);
}
/**
* Make /oauth/* requests to the API.
*
* @param string $path
* @param array $parameters
*
* @return array
* @throws TwitterOAuthException
*/
public function oauth(string $path, array $parameters = []): array
{
$response = [];
$this->resetLastResponse();
$this->response->setApiPath($path);
$url = sprintf('%s/%s', self::API_HOST, $path);
$result = $this->oAuthRequest($url, 'POST', $parameters);
if ($this->getLastHttpCode() != 200) {
throw new TwitterOAuthException($result);
}
parse_str($result, $response);
$this->response->setBody($response);
return $response;
}
/**
* Make /oauth2/* requests to the API.
*
* @param string $path
* @param array $parameters
*
* @return array|object
*/
public function oauth2(string $path, array $parameters = [])
{
$method = 'POST';
$this->resetLastResponse();
$this->response->setApiPath($path);
$url = sprintf('%s/%s', self::API_HOST, $path);
$request = Request::fromConsumerAndToken(
$this->consumer,
$this->token,
$method,
$url,
$parameters,
);
$authorization =
'Authorization: Basic ' .
$this->encodeAppAuthorization($this->consumer);
$result = $this->request(
$request->getNormalizedHttpUrl(),
$method,
$authorization,
$parameters,
);
$response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
$this->response->setBody($response);
return $response;
}
/**
* Make GET requests to the API.
*
* @param string $path
* @param array $parameters
*
* @return array|object
*/
public function get(string $path, array $parameters = [])
{
return $this->http('GET', self::API_HOST, $path, $parameters, [
'jsonPayload' => false,
]);
}
/**
* Make POST requests to the API.
*
* @param string $path
* @param array $parameters
* @param array $options
*
* @return array|object
*/
public function post(
string $path,
array $parameters = [],
array $options = [],
) {
if (!isset($options['jsonPayload'])) {
$options['jsonPayload'] = $this->useJsonBody();
}
return $this->http(
'POST',
self::API_HOST,
$path,
$parameters,
$options,
);
}
/**
* Make DELETE requests to the API.
*
* @param string $path
* @param array $parameters
*
* @return array|object
*/
public function delete(string $path, array $parameters = [])
{
return $this->http('DELETE', self::API_HOST, $path, $parameters, [
'jsonPayload' => false,
]);
}
/**
* Make PUT requests to the API.
*
* @param string $path
* @param array $parameters
* @param array $options
*
* @return array|object
*/
public function put(
string $path,
array $parameters = [],
array $options = [],
) {
if (!isset($options['jsonPayload'])) {
$options['jsonPayload'] = $this->useJsonBody();
}
return $this->http('PUT', self::API_HOST, $path, $parameters, $options);
}
/**
* Upload media to upload.twitter.com.
*
* @param string $path
* @param array $parameters
* @param array $options
*
* @return array|object
*/
public function upload(
string $path,
array $parameters = [],
array $options = [],
) {
if ($options['chunkedUpload'] ?? false) {
return $this->uploadMediaChunked($path, $parameters);
} else {
return $this->uploadMediaNotChunked($path, $parameters);
}
}
/**
* Progression of media upload
*
* @param string $media_id
*
* @return array|object
*/
public function mediaStatus(string $media_id)
{
return $this->http(
'GET',
self::UPLOAD_HOST,
'media/upload',
[
'command' => 'STATUS',
'media_id' => $media_id,
],
['jsonPayload' => false],
);
}
/**
* Private method to upload media (not chunked) to upload.twitter.com.
*
* @param string $path
* @param array $parameters
*
* @return array|object
*/
private function uploadMediaNotChunked(string $path, array $parameters)
{
if (
!is_readable($parameters['media']) ||
($file = file_get_contents($parameters['media'])) === false
) {
throw new \InvalidArgumentException(
'You must supply a readable file',
);
}
$parameters['media'] = base64_encode($file);
return $this->http('POST', self::UPLOAD_HOST, $path, $parameters, [
'jsonPayload' => false,
]);
}
/**
* Private method to upload media (chunked) to upload.twitter.com.
*
* @param string $path
* @param array $parameters
*
* @return array|object
*/
private function uploadMediaChunked(string $path, array $parameters)
{
/** @var object $init */
$init = $this->http(
'POST',
self::UPLOAD_HOST,
$path,
$this->mediaInitParameters($parameters),
['jsonPayload' => false],
);
if (!property_exists($init, 'media_id_string')) {
throw new TwitterOAuthException('Missing "media_id_string"');
}
// Append
$segmentIndex = 0;
$media = fopen($parameters['media'], 'rb');
while (!feof($media)) {
$this->http(
'POST',
self::UPLOAD_HOST,
'media/upload',
[
'command' => 'APPEND',
'media_id' => $init->media_id_string,
'segment_index' => $segmentIndex++,
'media_data' => base64_encode(
fread($media, $this->chunkSize),
),
],
['jsonPayload' => false],
);
}
fclose($media);
// Finalize
$finalize = $this->http(
'POST',
self::UPLOAD_HOST,
'media/upload',
[
'command' => 'FINALIZE',
'media_id' => $init->media_id_string,
],
['jsonPayload' => false],
);
return $finalize;
}
/**
* Private method to get params for upload media chunked init.
* Twitter docs: https://dev.twitter.com/rest/reference/post/media/upload-init.html
*
* @param array $parameters
*
* @return array
*/
private function mediaInitParameters(array $parameters): array
{
$allowed_keys = [
'media_type',
'additional_owners',
'media_category',
'shared',
];
$base = [
'command' => 'INIT',
'total_bytes' => filesize($parameters['media']),
];
$allowed_parameters = array_intersect_key(
$parameters,
array_flip($allowed_keys),
);
return array_merge($base, $allowed_parameters);
}
/**
* Cleanup any parameters that are known not to work.
*
* @param array $parameters
*
* @return array
*/
private function cleanUpParameters(array $parameters)
{
foreach ($parameters as $key => $value) {
// PHP coerces `true` to `"1"` which some Twitter APIs don't like.
if (is_bool($value)) {
$parameters[$key] = var_export($value, true);
}
}
return $parameters;
}
/**
* Get URL extension for current API Version.
*
* @return string
*/
private function extension()
{
return [
'1.1' => '.json',
'2' => '',
][$this->apiVersion];
}
/**
* Default content type for sending data.
*
* @return bool
*/
private function useJsonBody()
{
return [
'1.1' => false,
'2' => true,
][$this->apiVersion];
}
/**
* @param string $method
* @param string $host
* @param string $path
* @param array $parameters
* @param array $options
*
* @return array|object
*/
private function http(
string $method,
string $host,
string $path,
array $parameters,
array $options,
) {
$this->resetLastResponse();
$this->resetAttemptsNumber();
$this->response->setApiPath($path);
if (!$options['jsonPayload']) {
$parameters = $this->cleanUpParameters($parameters);
}
return $this->makeRequests(
$this->apiUrl($host, $path),
$method,
$parameters,
$options,
);
}
/**
* Generate API URL.
*
* Overriding this function is not supported and may cause unintended issues.
*
* @param string $host
* @param string $path
*
* @return string
*/
protected function apiUrl(string $host, string $path)
{
return sprintf(
'%s/%s/%s%s',
$host,
$this->apiVersion,
$path,
$this->extension(),
);
}
/**
*
* Make requests and retry them (if enabled) in case of Twitter's problems.
*
* @param string $method
* @param string $url
* @param string $method
* @param array $parameters
* @param array $options
*
* @return array|object
*/
private function makeRequests(
string $url,
string $method,
array $parameters,
array $options,
) {
do {
$this->sleepIfNeeded();
$result = $this->oAuthRequest($url, $method, $parameters, $options);
$response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
$this->response->setBody($response);
$this->attempts++;
// Retry up to our $maxRetries number if we get errors greater than 500 (over capacity etc)
} while ($this->requestsAvailable());
return $response;
}
/**
* Checks if we have to retry request if API is down.
*
* @return bool
*/
private function requestsAvailable(): bool
{
return $this->maxRetries &&
$this->attempts <= $this->maxRetries &&
$this->getLastHttpCode() >= 500;
}
/**
* Format and sign an OAuth / API request
*
* @param string $url
* @param string $method
* @param array $parameters
* @param array $options
*
* @return string
* @throws TwitterOAuthException
*/
private function oAuthRequest(
string $url,
string $method,
array $parameters,
array $options = [],
) {
$request = Request::fromConsumerAndToken(
$this->consumer,
$this->token,
$method,
$url,
$parameters,
$options,
);
if (array_key_exists('oauth_callback', $parameters)) {
// Twitter doesn't like oauth_callback as a parameter.
unset($parameters['oauth_callback']);
}
if ($this->bearer === null) {
$request->signRequest(
$this->signatureMethod,
$this->consumer,
$this->token,
);
$authorization = $request->toHeader();
if (array_key_exists('oauth_verifier', $parameters)) {
// Twitter doesn't always work with oauth in the body and in the header
// and it's already included in the $authorization header
unset($parameters['oauth_verifier']);
}
} else {
$authorization = 'Authorization: Bearer ' . $this->bearer;
}
return $this->request(
$request->getNormalizedHttpUrl(),
$method,
$authorization,
$parameters,
$options,
);
}
/**
* Set Curl options.
*
* @return array
*/
private function curlOptions(): array
{
$bundlePath = CaBundle::getSystemCaRootBundlePath();
$options = [
// CURLOPT_VERBOSE => true,
CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout,
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_USERAGENT => $this->userAgent,
$this->curlCaOpt($bundlePath) => $bundlePath,
];
if ($this->gzipEncoding) {
$options[CURLOPT_ENCODING] = 'gzip';
}
if (!empty($this->proxy)) {
$options[CURLOPT_PROXY] = $this->proxy['CURLOPT_PROXY'];
$options[CURLOPT_PROXYUSERPWD] =
$this->proxy['CURLOPT_PROXYUSERPWD'];
$options[CURLOPT_PROXYPORT] = $this->proxy['CURLOPT_PROXYPORT'];
$options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
$options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
}
return $options;
}
/**
* Make an HTTP request
*
* @param string $url
* @param string $method
* @param string $authorization
* @param array $postfields
* @param ?array $options
*
* @return string
* @throws TwitterOAuthException
*/
private function request(
string $url,
string $method,
string $authorization,
array $postfields,
?array $options = [],
): string {
$curlOptions = $this->curlOptions();
$curlOptions[CURLOPT_URL] = $url;
$curlOptions[CURLOPT_HTTPHEADER] = [
'Accept: application/json',
$authorization,
'Expect:',
];
switch ($method) {
case 'GET':
break;
case 'POST':
$curlOptions[CURLOPT_POST] = true;
$curlOptions = $this->setPostfieldsOptions(
$curlOptions,
$postfields,
$options,
);
break;
case 'DELETE':
$curlOptions[CURLOPT_CUSTOMREQUEST] = 'DELETE';
break;
case 'PUT':
$curlOptions[CURLOPT_CUSTOMREQUEST] = 'PUT';
$curlOptions = $this->setPostfieldsOptions(
$curlOptions,
$postfields,
$options,
);
break;
}
if (
in_array($method, ['GET', 'PUT', 'DELETE']) &&
!empty($postfields)
) {
$curlOptions[CURLOPT_URL] .=
'?' . Util::buildHttpQuery($postfields);
}
$curlHandle = curl_init();
curl_setopt_array($curlHandle, $curlOptions);
$response = curl_exec($curlHandle);
// Throw exceptions on cURL errors.
if (curl_errno($curlHandle) > 0) {
$error = curl_error($curlHandle);
$errorNo = curl_errno($curlHandle);
curl_close($curlHandle);
throw new TwitterOAuthException($error, $errorNo);
}
$this->response->setHttpCode(
curl_getinfo($curlHandle, CURLINFO_HTTP_CODE),
);
$parts = explode("\r\n\r\n", $response);
$responseBody = array_pop($parts);
$responseHeader = array_pop($parts);
$this->response->setHeaders($this->parseHeaders($responseHeader));
curl_close($curlHandle);
return $responseBody;
}
/**
* Get the header info to store.
*
* @param string $header
*
* @return array
*/
private function parseHeaders(string $header): array
{
$headers = [];
foreach (explode("\r\n", $header) as $line) {
if (strpos($line, ':') !== false) {
[$key, $value] = explode(': ', $line);
$key = str_replace('-', '_', strtolower($key));
$headers[$key] = trim($value);
}
}
return $headers;
}
/**
* Encode application authorization header with base64.
*
* @param Consumer $consumer
*
* @return string
*/
private function encodeAppAuthorization(Consumer $consumer): string
{
$key = rawurlencode($consumer->key);
$secret = rawurlencode($consumer->secret);
return base64_encode($key . ':' . $secret);
}
/**
* Get Curl CA option based on whether the given path is a directory or file.
*
* @param string $path
* @return int
*/
private function curlCaOpt(string $path): int
{
return is_dir($path) ? CURLOPT_CAPATH : CURLOPT_CAINFO;
}
/**
* Set options for JSON Requests
*
* @param array $options
* @param array $postfields
* @param array $options
*
* @return array
*/
private function setPostfieldsOptions(
array $curlOptions,
array $postfields,
array $options,
): array {
if ($options['jsonPayload'] ?? false) {
$curlOptions[CURLOPT_HTTPHEADER][] =
'Content-type: application/json';
$curlOptions[CURLOPT_POSTFIELDS] = json_encode(
$postfields,
JSON_THROW_ON_ERROR,
);
} else {
$curlOptions[CURLOPT_POSTFIELDS] = Util::buildHttpQuery(
$postfields,
);
}
return $curlOptions;
}
}

View File

@@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
/**
* @author Abraham Williams <abraham@abrah.am>
*/
class TwitterOAuthException extends \Exception
{
}

View File

@@ -1,122 +0,0 @@
<?php
/**
* The MIT License
* Copyright (c) 2007 Andy Smith
*/
declare(strict_types=1);
namespace Abraham\TwitterOAuth;
class Util
{
/**
* @param mixed $input
*
* @return mixed
*/
public static function urlencodeRfc3986($input)
{
$output = '';
if (is_array($input)) {
$output = array_map(
[__NAMESPACE__ . '\Util', 'urlencodeRfc3986'],
$input,
);
} elseif (is_scalar($input)) {
$output = rawurlencode((string) $input);
}
return $output;
}
/**
* @param string $string
*
* @return string
*/
public static function urldecodeRfc3986($string): string
{
return urldecode($string);
}
/**
* This function takes a input like a=b&a=c&d=e and returns the parsed
* parameters like this
* array('a' => array('b','c'), 'd' => 'e')
*
* @param string $input
*
* @return array
*/
public static function parseParameters($input): array
{
if (!is_string($input)) {
return [];
}
$pairs = explode('&', $input);
$parameters = [];
foreach ($pairs as $pair) {
$split = explode('=', $pair, 2);
$parameter = Util::urldecodeRfc3986($split[0]);
$value = isset($split[1]) ? Util::urldecodeRfc3986($split[1]) : '';
if (isset($parameters[$parameter])) {
// We have already recieved parameter(s) with this name, so add to the list
// of parameters with this name
if (is_scalar($parameters[$parameter])) {
// This is the first duplicate, so transform scalar (string) into an array
// so we can add the duplicates
$parameters[$parameter] = [$parameters[$parameter]];
}
$parameters[$parameter][] = $value;
} else {
$parameters[$parameter] = $value;
}
}
return $parameters;
}
/**
* @param array $params
*
* @return string
*/
public static function buildHttpQuery(array $params): string
{
if (empty($params)) {
return '';
}
// Urlencode both keys and values
$keys = Util::urlencodeRfc3986(array_keys($params));
$values = Util::urlencodeRfc3986(array_values($params));
$params = array_combine($keys, $values);
// Parameters are sorted by name, using lexicographical byte value ordering.
// Ref: Spec: 9.1.1 (1)
uksort($params, 'strcmp');
$pairs = [];
foreach ($params as $parameter => $value) {
if (is_array($value)) {
// If two or more parameters share the same name, they are sorted by their value
// Ref: Spec: 9.1.1 (1)
// June 12th, 2010 - changed to sort because of issue 164 by hidetaka
sort($value, SORT_STRING);
foreach ($value as $duplicateValue) {
$pairs[] = $parameter . '=' . $duplicateValue;
}
} else {
$pairs[] = $parameter . '=' . $value;
}
}
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
// Each name-value pair is separated by an '&' character (ASCII code 38)
return implode('&', $pairs);
}
}

View File

@@ -1,29 +0,0 @@
<?php
namespace Abraham\TwitterOAuth\Util;
/**
* @author louis <louis@systemli.org>
*/
class JsonDecoder
{
/**
* Decodes a JSON string to stdObject or associative array
*
* @param string $string
* @param bool $asArray
*
* @return array|object
*/
public static function decode(string $string, bool $asArray)
{
if (
version_compare(PHP_VERSION, '5.4.0', '>=') &&
!(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)
) {
return json_decode($string, $asArray, 512, JSON_BIGINT_AS_STRING);
}
return json_decode($string, $asArray, 512, JSON_THROW_ON_ERROR);
}
}

View File

@@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Reset Password</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
@@ -12,8 +13,9 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<title>Reset Password</title>
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">

View File

@@ -11,6 +11,7 @@ $success_message = $_SESSION['success_message'] ?? '';
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Reset Password</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
@@ -20,9 +21,11 @@ $success_message = $_SESSION['success_message'] ?? '';
<link rel="manifest" href="./assets/images/site.webmanifest">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Work+Sans:wght@100..900&display=swap" rel="stylesheet">
<title>Reset Password</title>
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Work+Sans:wght@100..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">

View File

@@ -10,6 +10,7 @@ $email = isset($_SESSION['email']) ? $_SESSION['email'] : '';
<head>
<meta charset="UTF-8">
<title>Enter Confirmation Code</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg" />
@@ -20,8 +21,9 @@ $email = isset($_SESSION['email']) ? $_SESSION['email'] : '';
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<title>Enter Confirmation Code</title>
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>

View File

@@ -1,6 +1,6 @@
<?php
require 'core/process.php';
require 'core/get_statistics.php';
require 'core/get_statistics.php';
error_reporting(E_ALL);
ini_set('display_errors', 1);
@@ -13,6 +13,7 @@ ini_set('display_errors', 1);
<title>Xeorl - Link Shortener and Management Tool</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Xeorl - The All-In-One, Fully Free to Use Advanced Link Shortener and Management Tool - Equipped with Multi-layered URL encryption, URL metadata remover, Mass shrinker, Quick link and Many more! - Powered by @xodivorce...">
<meta name="google-adsense-account" content="ca-pub-5747712812070455">
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg" />
<link rel="shortcut icon" href="./assets/images/favicon.ico" />
@@ -23,12 +24,12 @@ ini_set('display_errors', 1);
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/_home.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<?php include "assets/_header.php"; ?>
<main>
<!-- Shorten Section -->
<section class="shorten-section" style="user-select: none;">
<h1>Open source inits.</h1>
<h2>Lovingly hand-crafted.</h2>
@@ -42,8 +43,6 @@ ini_set('display_errors', 1);
<ul id="links-list"></ul>
</div>
</section>
<!-- Dashboard Statistics Section -->
<section class="dashboard-stats-section" style="user-select: none;">
<h1 class="section-heading">Numbers Speak For Themselves.</h1>
<h2 class="section-subheading">Challenged By URLs, Defeated By None.</h2>
@@ -53,7 +52,6 @@ ini_set('display_errors', 1);
to support and resolve any issues you have because your satisfaction
means everything to us. For any issues, email us at <a href="mailto:hey@xodivorce.in" class="contact-link">hey@xodivorce.in</a>.
</p>
<div class="dashboard-stats">
<div class="stat-item">
<img src="assets/images/total.png" alt="Total Clicks" class="stat-icon total-icon">
@@ -72,8 +70,6 @@ ini_set('display_errors', 1);
</div>
</div>
</section>
<!-- How to Start Section -->
<section class="how-to-start-section" style="user-select: none;">
<h1 class="section-heading">Just Three Simple Steps</h1>
<h2 class="section-subheading">How to Get Started?</h2>
@@ -88,10 +84,9 @@ ini_set('display_errors', 1);
</div>
</section>
</main>
<?php include 'assets/_cookies.php'; ?>
<?php include 'assets/_footer.php'; ?>
<script src="assets/js/_home.js"></script>
<script src="assets/js/_developer_tools.js"></script>
<script src="assets/js/developer_tools.js"></script>
</body>
</html>

View File

@@ -8,6 +8,7 @@ ini_set('display_errors', 1);
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
@@ -18,8 +19,9 @@ ini_set('display_errors', 1);
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Work+Sans:wght@100..900&display=swap" rel="stylesheet">
<title>Login</title>
<link rel="stylesheet" href="assets/css/_login.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<div class="container" style="user-select: none;">

View File

@@ -26,6 +26,8 @@ if (!isset($_SESSION['user_id'])) {
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/_monetization.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<?php include "assets/_header.php"; ?>

View File

@@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Password Reset Success</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
@@ -12,8 +13,9 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<title>Password Reset Success</title>
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">

View File

@@ -8,6 +8,7 @@ ini_set('display_errors', 1);
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
@@ -18,8 +19,9 @@ ini_set('display_errors', 1);
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<title>Register</title>
<link rel="stylesheet" href="assets/css/_register.css">
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<div class="container" style="user-select: none;">

View File

@@ -27,8 +27,8 @@ $redirect_url = $_SESSION['redirect_url'];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/_unzipper.css">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455"
crossorigin="anonymous"></script>
<!-- Google Adsense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
</head>
<body>
<?php include "assets/_header.php"; ?>