170 lines
5.3 KiB
PHP
170 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\User;
|
|
use App\UserAccessToken;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use romanzipp\Twitch\Facades\Twitch;
|
|
use romanzipp\Twitch\Enums\Scope;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
const OAUTH_BASE_URI = "https://id.twitch.tv/oauth2/";
|
|
const AUTH_REDIRECT_ROUTE = "me.dashboard";
|
|
|
|
public function __construct() {
|
|
$this->middleware("guest")->only(["login", "authorized"]);
|
|
|
|
$this->middleware("auth")->except(["login", "authorized"]);
|
|
}
|
|
|
|
/**
|
|
* Redirect to the Twitch OAuth app authorization site.
|
|
*/
|
|
public function login() {
|
|
$stateToken = getToken(25);
|
|
session()->flash("stateToken", $stateToken);
|
|
|
|
return redirect()->away(Twitch::getOAuthAuthorizeUrl("code", [
|
|
Scope::USER_READ_EMAIL
|
|
], $stateToken));
|
|
}
|
|
|
|
/**
|
|
* Callback of the Twitch OAuth authorization page.
|
|
*
|
|
* @param Illuminate\Http\Request $request
|
|
*/
|
|
public function authorized(Request $request) {
|
|
if ($request->error) {
|
|
session()->flash("error", [
|
|
"title" => "Authorization error",
|
|
"description" => $request->error_description . "."
|
|
]);
|
|
|
|
return redirect(route("home"));
|
|
|
|
} else if (session("stateToken") && session("stateToken") != $request->state) {
|
|
session()->flash("error", [
|
|
"title" => "Missmatch state token",
|
|
"description" => "State tokens do not match, maybe someone tried to intercept the login attempt. Try again in sone seconds, if it persists contact with the site administrator."
|
|
]);
|
|
return redirect(route("home"));
|
|
}
|
|
|
|
$oauthTokenRequest = Twitch::getOAuthToken($request->code);
|
|
|
|
if (!$oauthTokenRequest->success) {
|
|
return response("Error " . $oauthTokenRequest->data->status . ", " . $oauthTokenRequest->data->message);
|
|
}
|
|
|
|
$userAccessToken = $oauthTokenRequest->data->access_token;
|
|
$user = $this->getAuthedUser($userAccessToken);
|
|
|
|
$dbUser = User::where("twitch_uid", $user->id)->first();
|
|
|
|
if (!$dbUser) {
|
|
$dbUser = $this->store($user);
|
|
}
|
|
|
|
$dbUser->accessTokens()->create([
|
|
"access_token" => $userAccessToken,
|
|
"refresh_token" => $oauthTokenRequest->data->refresh_token,
|
|
"expires_in" => $oauthTokenRequest->data->expires_in
|
|
]);
|
|
|
|
Auth::login($dbUser);
|
|
session(["oauthToken" => $userAccessToken]);
|
|
|
|
return redirect(route(self::AUTH_REDIRECT_ROUTE));
|
|
}
|
|
|
|
/**
|
|
* Get data of a user given a user access token
|
|
*
|
|
* @param string $userAccessToken A valid user access token obtained from a OAuth token request.
|
|
*/
|
|
private function getAuthedUser($userAccessToken) {
|
|
$userRequest = Twitch::withToken($userAccessToken)->getAuthedUser();
|
|
|
|
if (!$userRequest->success) {
|
|
session()->flash("error", [
|
|
"title" => "Could not get user data",
|
|
"description" => "Something failed while trying to get the user data, is Twitch API down?"
|
|
]);
|
|
|
|
return redirect(route("home"));
|
|
}
|
|
|
|
return $userRequest->data[0];
|
|
}
|
|
|
|
/**
|
|
* Creates a user record on the database given his data
|
|
*
|
|
* @param Array $data Array that contains the data of the user (id, display_name, email and profile_image_url).
|
|
*/
|
|
private function store($data) {
|
|
$user = new User;
|
|
|
|
$user->twitch_uid = $data->id;
|
|
$user->username = $data->display_name;
|
|
$user->email = $data->email;
|
|
$user->profile_image = $data->profile_image_url;
|
|
|
|
$user->save();
|
|
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* Logout the user from the session and destroy the user access token created for the session.
|
|
*
|
|
* @param Illuminate\Http\Request $request
|
|
*/
|
|
public function logout(Request $request) {
|
|
$logoutRequest = $this->invalidateUserOauthToken(session("oauthToken"));
|
|
|
|
if (!$logoutRequest->success) {
|
|
session()->flash("error", [
|
|
"title" => "Session could not be ended",
|
|
"description" => "The user oauth token could not be invalidated, is Twitch API down?"
|
|
]);
|
|
return redirect(route("home"));
|
|
}
|
|
|
|
Auth::user()->accessTokens()->where("access_token", session("oauthToken"))->first()->delete();
|
|
Auth::logout();
|
|
|
|
session()->forget("oauthToken");
|
|
|
|
return redirect(route("home"));
|
|
}
|
|
|
|
/**
|
|
* Invalidates the given user oauth token.
|
|
*
|
|
* @param string $oauthToken user oauth token to be invalidated.
|
|
*/
|
|
private function invalidateUserOauthToken($oauthToken) {
|
|
return Twitch::post(self::OAUTH_BASE_URI . "revoke", [
|
|
"client_id" => Twitch::getClientId(),
|
|
"token" => $oauthToken
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Display the user dashboard.
|
|
*/
|
|
public function showDashboard() {
|
|
return view("me.dashboard", [
|
|
"followHook" => Auth::user()->twitchWebhooks()->where("type", "follow")->first(),
|
|
"streamHook" => Auth::user()->twitchWebhooks()->where("type", "stream")->first(),
|
|
"subscriptionHook" => Auth::user()->twitchWebhooks()->where("type", "subscription")->first(),
|
|
]);
|
|
}
|
|
}
|