diff --git a/.gitignore b/.gitignore index 4510d84b7..fc855a3a9 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ package-lock.json index.php .DS_Store static/.DS_Store +vendor +composer.lock \ No newline at end of file diff --git a/.htaccess b/.htaccess index 66a37f293..c81b3e212 100644 --- a/.htaccess +++ b/.htaccess @@ -5,3 +5,5 @@ RewriteRule ^gym_data$ gym_data.php?$1 [QSA,L] RewriteRule ^motd_data$ motd_data.php?$1 [QSA,L] RewriteRule ^weather_data$ weather_data.php?$1 [QSA,L] RewriteRule ^serviceWorker.min.js$ static/dist/js/serviceWorker.min.js?$1 [QSA,L] +RewriteRule ^user$ user.php?$1 [QSA,L] +RewriteRule ^discord-login$ discord-login.php?$1 [QSA,L] \ No newline at end of file diff --git a/DiscordAuth.php b/DiscordAuth.php new file mode 100644 index 000000000..67ec2dfe6 --- /dev/null +++ b/DiscordAuth.php @@ -0,0 +1,79 @@ + 'https://discordapp.com']); + $redirector = new DiscordRedirector($this); + + global $discordBotClientId, $discordBotClientSecret, $discordBotRedirectUri; + + $clientConfig = new ClientConfig([ + 'client_id' => $discordBotClientId, + 'client_secret' => $discordBotClientSecret, + 'redirect_uri' => $discordBotRedirectUri + ]); + + $serverConfig = new ServerConfig([ + 'authorization_endpoint' => '/api/oauth2/authorize', + 'token_endpoint' => '/api/oauth2/token', + ]); + + $this->oauthSession = new AuthorizationCodeSession( + $httpClient, + $redirector, + $clientConfig, + $serverConfig + ); + + $scope = new Scope(['identify']); + $this->oauthSession->setScope($scope); + } + + public function gotoDiscord() + { + $this->setUpOAuth(); + return $this->oauthSession->authorize(); + } + + public function handleAuthorizationResponse() + { + $this->setUpOAuth(); + $authorizationResponse = new AuthorizationResponse($_GET); + $this->oauthSession->handleAuthorizationResponse($authorizationResponse); + } + + private function setUpResource() + { + if ($this->resource != null) { + return $this->resource; + } + $handler = \GuzzleHttp\HandlerStack::create(); + $handler->before('http_errors', function ($callable) { + return new \EasyBib\Guzzle\BearerAuthMiddleware($callable, $this->oauthSession); + }); + $this->resource = new \GuzzleHttp\Client([ + 'base_uri' => 'https://discordapp.com', + 'handler' => $handler, + ]); + } + + public function get($uri) + { + $this->setUpResource(); + return $this->resource->get($uri)->getBody()->getContents(); + } +} diff --git a/DiscordRedirector.php b/DiscordRedirector.php new file mode 100644 index 000000000..ce585b673 --- /dev/null +++ b/DiscordRedirector.php @@ -0,0 +1,18 @@ + https://discordapp.com/developers/applications/me + // 2. Install composer with "apt-get install composer". + // 3. Navigate to your website's root folder and type "composer install" to install the dependencies. + // 4. Add your callback-page as a REDIRECT URI to your discord bot. Should be the same as $discordBotRedirectUri. + // 5. Enter Client ID, Client Secret and Redirect URI below. +$discordBotClientId = 0; +$discordBotClientSecret = ""; +$discordBotRedirectUri = "https://example.com/discord-callback.php"; + +$adminUsers = array('admin@example.com', 'Superadmin#13337'); // You can add multiple admins by adding them to the array. +$logfile = '../members.log'; // Path to log file. Make sure this works as it will be your life saver if your db crashes. +$daysMembershipPerQuantity = 31; // How many days membership one selly quantity will give. +$sellyPage = ''; // Link to selly purchase page for membership renewal. +$sellyWebhookSecret = ''; // Add a secret key at https://selly.gg/settings to make sure the payment webhook is sent from selly to prevent fake payments. + // Add the same key to the $sellyWebhookSecret variable. + //----------------------------------------------------- // FRONTEND SETTINGS //----------------------------------------------------- +if ($noNativeLogin === true && $noDiscordLogin == true || (($noNativeLogin === false || $noDiscordLogin === false) && !empty($_SESSION['user']->expire_timestamp) && $_SESSION['user']->expire_timestamp > time())) { + + /* + THESE SETTINGS WILL BE APPLIED IF: + - LOGIN IS DISABLED + - LOGIN IS ENABLED AND THE USER IS LOGGED ON + */ + + /* Marker Settings */ + $noExcludeMinIV = false; // true/false + $noMinIV = false; // true/false + $noMinLevel = false; // true/false + $noHighLevelData = false; // true/false + + /* Notification Settings */ + $noNotifyPokemon = false; // true/false + $noNotifyRarity = false; // true/false + $noNotifyIv = false; // true/false + $noNotifyLevel = false; // true/false + $noNotifyRaid = false; // true/false + $noNotifySound = false; // true/false + $noCriesSound = false; // true/false + $noNotifyBounce = false; // true/false + $noNotifyNotification = false; // true/false + + /* Style Settings */ + $iconNotifySizeModifier = 15; // 0, 15, 30, 45 +} else { + + /* + THESE SETTINGS WILL BE APPLIED IF: + - LOGIN IS ENABLED AND THE USER IS NOT A DONATOR + */ + + /* Marker Settings */ + $noExcludeMinIV = true; // true/false + $noMinIV = true; // true/false + $noMinLevel = true; // true/false + $noHighLevelData = true; // true/false + + /* Notification Settings */ + $noNotifyPokemon = true; // true/false + $noNotifyRarity = true; // true/false + $noNotifyIv = true; // true/false + $noNotifyLevel = true; // true/false + $noNotifyRaid = true; // true/false + $noNotifySound = true; // true/false + $noCriesSound = true; // true/false + $noNotifyBounce = true; // true/false + $noNotifyNotification = true; // true/false + + /* Style Settings */ + $iconNotifySizeModifier = 0; // 0, 15, 30, 45 +} + /* Marker Settings */ $noPokemon = false; // true/false $enablePokemon = 'true'; // true/false $noPokemonNumbers = false; // true/false -$noHighLevelData = false; // true/false $noHidePokemon = false; // true/false $hidePokemon = '[10, 13, 16, 19, 21, 29, 32, 41, 46, 48, 50, 52, 56, 74, 77, 96, 111, 133, 161, 163, 167, 177, 183, 191, 194, 168]'; // [] for empty -$hidePokemonCoords = true; // true/false -$noExcludeMinIV = false; // true/false +$hidePokemonCoords = false; // true/false + $excludeMinIV = '[131, 143, 147, 148, 149, 248]'; // [] for empty -$noMinIV = false; // true/false $minIV = '0'; // "0" for empty or a number - -$noMinLevel = false; // true/false $minLevel = '0'; // "0" for empty or a number $noBigKarp = false; // true/false @@ -148,31 +223,22 @@ /* Notification Settings */ -$noNotifyPokemon = false; // true/false $notifyPokemon = '[201]'; // [] for empty -$noNotifyRarity = false; // true/false $notifyRarity = '[]'; // "Common", "Uncommon", "Rare", "Very Rare", "Ultra Rare" -$noNotifyIv = false; // true/false $notifyIv = '""'; // "" for empty or a number -$noNotifyLevel = false; // true/false $notifyLevel = '""'; // "" for empty or a number -$noNotifyRaid = false; // true/false $notifyRaid = 5; // O to disable -$noNotifySound = false; // true/false $notifySound = 'false'; // true/false -$noCriesSound = false; // true/false $criesSound = 'false'; // true/false -$noNotifyBounce = false; // true/false $notifyBounce = 'true'; // true/false -$noNotifyNotification = false; // true/false $notifyNotification = 'true'; // true/false /* Style Settings */ @@ -189,7 +255,6 @@ $iconSize = 0; // -8, 0, 10, 20 $noIconNotifySizeModifier = false; // true/false | Increase size of notified Pokemon -$iconNotifySizeModifier = 15; // 0, 15, 30, 45 $noGymStyle = false; // true/false $gymStyle = 'ingame'; // ingame, shield diff --git a/config/example.config.php b/config/example.config.php index 0b73bb85d..4f6315c1a 100644 --- a/config/example.config.php +++ b/config/example.config.php @@ -65,29 +65,103 @@ $motdTitle = "Message of the Day"; $motdContent = "This is an example MOTD
Do whatever you like with it."; +//----------------------------------------------------- +// Login +//----------------------------------------------------- + +$noNativeLogin = true; // true/false - This will enable the built in login system. +$domainName = ''; // If this is empty, reset-password emails will use the domain name taken from the URL. + +$noDiscordLogin = true; // true/false - This will enable login through discord. + // 1. Create a discord bot here -> https://discordapp.com/developers/applications/me + // 2. Install composer with "apt-get install composer". + // 3. Navigate to your website's root folder and type "composer install" to install the dependencies. + // 4. Add your callback-page as a REDIRECT URI to your discord bot. Should be the same as $discordBotRedirectUri. + // 5. Enter Client ID, Client Secret and Redirect URI below. +$discordBotClientId = 0; +$discordBotClientSecret = ""; +$discordBotRedirectUri = "https://example.com/discord-callback.php"; + +$adminUsers = array('admin@example.com', 'Superadmin#13337'); // You can add multiple admins by adding them to the array. +$logfile = '../members.log'; // Path to log file. Make sure this works as it will be your life saver if your db crashes. +$daysMembershipPerQuantity = 31; // How many days membership one selly quantity will give. +$sellyPage = ''; // Link to selly purchase page for membership renewal. +$sellyWebhookSecret = ''; // Add a secret key at https://selly.gg/settings to make sure the payment webhook is sent from selly to prevent fake payments. + // Add the same key to the $sellyWebhookSecret variable. + //----------------------------------------------------- // FRONTEND SETTINGS //----------------------------------------------------- +if ($noNativeLogin === true && $noDiscordLogin == true || (($noNativeLogin === false || $noDiscordLogin === false) && !empty($_SESSION['user']->expire_timestamp) && $_SESSION['user']->expire_timestamp > time())) { + + /* + THESE SETTINGS WILL BE APPLIED IF: + - LOGIN IS DISABLED + - LOGIN IS ENABLED AND THE USER IS LOGGED ON + */ + + /* Marker Settings */ + $noExcludeMinIV = false; // true/false + $noMinIV = false; // true/false + $noMinLevel = false; // true/false + $noHighLevelData = false; // true/false + + /* Notification Settings */ + $noNotifyPokemon = false; // true/false + $noNotifyRarity = false; // true/false + $noNotifyIv = false; // true/false + $noNotifyLevel = false; // true/false + $noNotifyRaid = false; // true/false + $noNotifySound = false; // true/false + $noCriesSound = false; // true/false + $noNotifyBounce = false; // true/false + $noNotifyNotification = false; // true/false + + /* Style Settings */ + $iconNotifySizeModifier = 15; // 0, 15, 30, 45 +} else { + + /* + THESE SETTINGS WILL BE APPLIED IF: + - LOGIN IS ENABLED AND THE USER IS _NOT_ LOGGED ON + */ + + /* Marker Settings */ + $noExcludeMinIV = true; // true/false + $noMinIV = true; // true/false + $noMinLevel = true; // true/false + $noHighLevelData = true; // true/false + + /* Notification Settings */ + $noNotifyPokemon = true; // true/false + $noNotifyRarity = true; // true/false + $noNotifyIv = true; // true/false + $noNotifyLevel = true; // true/false + $noNotifyRaid = true; // true/false + $noNotifySound = true; // true/false + $noCriesSound = true; // true/false + $noNotifyBounce = true; // true/false + $noNotifyNotification = true; // true/false + + /* Style Settings */ + $iconNotifySizeModifier = 0; // 0, 15, 30, 45 +} + /* Marker Settings */ $noPokemon = false; // true/false $enablePokemon = 'true'; // true/false $noPokemonNumbers = false; // true/false -$noHighLevelData = false; // true/false $noHidePokemon = false; // true/false $hidePokemon = '[10, 13, 16, 19, 21, 29, 32, 41, 46, 48, 50, 52, 56, 74, 77, 96, 111, 133, 161, 163, 167, 177, 183, 191, 194, 168]'; // [] for empty $hidePokemonCoords = false; // true/false -$noExcludeMinIV = false; // true/false $excludeMinIV = '[131, 143, 147, 148, 149, 248]'; // [] for empty -$noMinIV = false; // true/false $minIV = '0'; // "0" for empty or a number - -$noMinLevel = false; // true/false $minLevel = '0'; // "0" for empty or a number $noBigKarp = false; // true/false @@ -138,31 +212,22 @@ /* Notification Settings */ -$noNotifyPokemon = false; // true/false $notifyPokemon = '[201]'; // [] for empty -$noNotifyRarity = false; // true/false $notifyRarity = '[]'; // "Common", "Uncommon", "Rare", "Very Rare", "Ultra Rare" -$noNotifyIv = false; // true/false $notifyIv = '""'; // "" for empty or a number -$noNotifyLevel = false; // true/false $notifyLevel = '""'; // "" for empty or a number -$noNotifyRaid = false; // true/false $notifyRaid = 5; // O to disable -$noNotifySound = false; // true/false $notifySound = 'false'; // true/false -$noCriesSound = false; // true/false $criesSound = 'false'; // true/false -$noNotifyBounce = false; // true/false $notifyBounce = 'true'; // true/false -$noNotifyNotification = false; // true/false $notifyNotification = 'true'; // true/false /* Style Settings */ @@ -179,7 +244,6 @@ $iconSize = 0; // -8, 0, 10, 20 $noIconNotifySizeModifier = false; // true/false | Increase size of notified Pokemon -$iconNotifySizeModifier = 15; // 0, 15, 30, 45 $noGymStyle = false; // true/false $gymStyle = 'ingame'; // ingame, shield diff --git a/discord-callback.php b/discord-callback.php new file mode 100644 index 000000000..4c28562fa --- /dev/null +++ b/discord-callback.php @@ -0,0 +1,47 @@ +handleAuthorizationResponse($_GET); + $user = json_decode($auth->get("/api/users/@me")); + + $count = $db->count("users", [ + "id" => $user->{'id'}, + "login_system" => 'discord' + ]); + + if ($count === 0) { + $db->insert("users", [ + "id" => $user->{'id'}, + "user" => $user->{'username'} . "#" . $user->{'discriminator'}, + "expire_timestamp" => time(), + "login_system" => 'discord' + ]); + + $logMsg = "INSERT INTO users (id, user, expire_timestamp, login_system) VALUES ('{$user->id}', '{$user->username}" . "#" . "{$user->discriminator}', '" . time() ."', 'discord'); -- " . date('Y-m-d H:i:s') . "\r\n"; + file_put_contents($logfile, $logMsg, FILE_APPEND); + } + + setcookie("LoginCookie", session_id(), time()+60*60*24*7); + + $db->update("users", [ + "session_id" => session_id(), + "user" => $user->{'username'} . "#" . $user->{'discriminator'} + ], [ + "id" => $user->{'id'}, + "login_system" => 'discord' + ]); + } + header("Location: ."); + die(); + } catch (Exception $e) { + header("Location: ./discord-login"); + } +} else { + header("Location: ."); +} diff --git a/discord-login.php b/discord-login.php new file mode 100644 index 000000000..edf30334e --- /dev/null +++ b/discord-login.php @@ -0,0 +1,12 @@ +gotoDiscord(); +} else { + header("Location: ."); +} diff --git a/logout.php b/logout.php new file mode 100644 index 000000000..3c228058b --- /dev/null +++ b/logout.php @@ -0,0 +1,7 @@ + + + id)) { + $info = $db->query( + "SELECT expire_timestamp FROM users WHERE id = :id AND login_system = :login_system", [ + ":id" => $_SESSION['user']->id, + ":login_system" => $_SESSION['user']->login_system + ] + )->fetch(); + + $_SESSION['user']->expire_timestamp = $info['expire_timestamp']; + + if (!empty($_SESSION['user']->updatePwd) && $_SESSION['user']->updatePwd === 1) { + header("Location: ./user"); + die(); + } + + if ($info['expire_timestamp'] > time()) { + $color = "green"; + } else { + $color = "red"; + } + + echo "" . substr($_SESSION['user']->user, 0, 3) . "..."; + } else { + echo "" . i8ln('Login') . ""; + } + } + ?> @@ -594,7 +629,7 @@ class="onoffswitch-checkbox"/> } ?> ' . i8ln('Notification') . '
'; } @@ -848,6 +883,39 @@ class="onoffswitch-checkbox"/>
+ id)) { + ?> +
+
+ +
+
+
+
+ +
+

+

+ expire_timestamp); + + echo $_SESSION['user']->user . "
"; + if ($_SESSION['user']->expire_timestamp > time()) { + echo "" . i8ln('Membership expires on') . " {$time}"; + } else { + echo "" . i8ln('Membership expired on') . " {$time}"; + } ?> +

+