Skip to content

Commit

Permalink
Merge pull request #13 from tomatophp/develop
Browse files Browse the repository at this point in the history
add social media login and link
  • Loading branch information
3x1io authored Mar 26, 2024
2 parents 061dc94 + 11d24a7 commit aa3feb5
Show file tree
Hide file tree
Showing 11 changed files with 381 additions and 3 deletions.
149 changes: 148 additions & 1 deletion Modules/CircleXO/App/Http/Controllers/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,167 @@
namespace Modules\CircleXO\App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Account;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Session;
use Laravel\Socialite\Facades\Socialite;
use Modules\TomatoCrm\App\Events\AccountRegistered;
use Modules\TomatoCrm\App\Events\SendOTP;
use Modules\TomatoCrm\App\Models\Account;
use Modules\TomatoCrm\App\Models\AccountsMeta;
use ProtoneMedia\Splade\Facades\Toast;

class AuthController extends Controller
{

public function provider($provider)
{
return Socialite::driver($provider)->redirect();
}

public function callback($provider)
{
$providerHasToken = config('services.'.$provider.'.client_token');
if($providerHasToken){
$socialUser = Socialite::driver($provider)->userFromToken($providerHasToken);
}
else {
$socialUser = Socialite::driver($provider)->user();
}

if(auth('accounts')->user()){
AccountsMeta::where('key', $provider . '_id')->where('value', $socialUser->id)->delete();

$account = auth('accounts')->user();
$account->meta($provider . '_id', $socialUser->id);
if ($socialUser->token) {
$account->meta($provider . '_token', $socialUser->token);
}
if ($socialUser->refreshToken) {
$account->meta($provider . '_refresh_token', $socialUser->refreshToken);
}

if (isset($socialUser->attributes['avatar']) && !$account->getMedia('avatar')->first()) {
$account->addMediaFromUrl($socialUser->attributes['avatar'])->toMediaCollection('avatar');
}

Toast::success('Account connected successfully!')->autoDismiss(2);
return redirect()->route('profile.index');
}
else {
$findUserByProvider = Account::whereHas('accountsMetas', function ($q) use ($socialUser, $provider){
$q->where('key', $provider . "_id")->where('value', $socialUser->id);
})->first();

if($findUserByProvider){
if(isset($socialUser->attributes['avatar']) && !$findUserByProvider->getMedia('avatar')->first()){
$findUserByProvider->addMediaFromUrl($socialUser->attributes['avatar'])->toMediaCollection('avatar');
}
Toast::success('Account connected successfully!')->autoDismiss(2);

auth('accounts')->login($findUserByProvider);
return redirect()->route('profile.index');
}
else {
if($socialUser->email){
$findUserByEmail = Account::where('email', $socialUser->email)->first();
if($findUserByEmail){
$findUserByEmail->meta($provider . '_id', $socialUser->id);
if ($socialUser->token) {
$findUserByEmail->meta($provider . '_token', $socialUser->token);
}
if ($socialUser->refreshToken) {
$findUserByEmail->meta($provider . '_refresh_token', $socialUser->refreshToken);
}

if (isset($socialUser->attributes['avatar']) && !$findUserByEmail->getMedia('avatar')->first()) {
$findUserByEmail->addMediaFromUrl($socialUser->attributes['avatar'])->toMediaCollection('avatar');
}

Toast::success('Account connected successfully!')->autoDismiss(2);

auth('accounts')->login($findUserByEmail);
return redirect()->route('profile.index');
}
else {
$account = new Account();
$account->name = $socialUser->name;
$account->email = $socialUser->email;
if(isset($socialUser->attributes['nickname'])){
$username = $socialUser->attributes['nickname'];
}
else {
$username = str($socialUser->name)->slug('_');
}
$checkIfUserNameExists = Account::where('username', "@" . $username)->first();
if($checkIfUserNameExists){
$username = $username . rand(1000, 9999);
}

$account->username = "@" . $username;
$account->is_active = true;
$account->save();

$account->meta($provider . '_id', $socialUser->id);
if($socialUser->token){
$account->meta($provider . '_token', $socialUser->token);
}
if($socialUser->refreshToken){
$account->meta($provider . '_refresh_token', $socialUser->refreshToken);
}

if(isset($socialUser->attributes['avatar'])){
$account->addMediaFromUrl($socialUser->attributes['avatar'])->toMediaCollection('avatar');
}

Toast::success('Account connected successfully!')->autoDismiss(2);

auth('accounts')->login($account);
return redirect()->route('profile.index');
}
}
else {
$account = new Account();
$account->name = $socialUser->name;
$account->email = $socialUser->email;
if(isset($socialUser->attributes['nickname'])){
$username = $socialUser->attributes['nickname'];
}
else {
$username = str($socialUser->name)->slug('_');
}
$checkIfUserNameExists = Account::where('username', "@" . $username)->first();
if($checkIfUserNameExists){
$username = $username . rand(1000, 9999);
}

$account->username = "@" . $username;
$account->is_active = true;
$account->save();

$account->meta($provider . '_id', $socialUser->id);
if($socialUser->token){
$account->meta($provider . '_token', $socialUser->token);
}
if($socialUser->refreshToken){
$account->meta($provider . '_refresh_token', $socialUser->refreshToken);
}

if(isset($socialUser->attributes['avatar'])){
$account->addMediaFromUrl($socialUser->attributes['avatar'])->toMediaCollection('avatar');
}

Toast::success('Account connected successfully!')->autoDismiss(2);
auth('accounts')->login($account);
return redirect()->route('profile.index');
}
}
}
}

public function register()
{
if(auth('accounts')->user()){
Expand Down
30 changes: 30 additions & 0 deletions Modules/CircleXO/App/Http/Controllers/ProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ public function index(Request $request)
return view('circle-xo::profile.index', compact('listing'));
}

public function socialAccounts()
{
return view('circle-xo::profile.edit.social-accounts');
}

public function socialAccountsUpdate(Request $request)
{
$request->validate([
"provider" => "required|string|in:discord,twitter-oauth-2,github",
]);

$account = auth('accounts')->user();
$account->metaDestroy($request->get('provider').'_id');
$account->metaDestroy($request->get('provider').'_token');
$account->metaDestroy($request->get('provider').'_refresh_token');

Toast::success('Social account removed successfully')->autoDismiss(2);
return redirect()->back();
}

public function following(Request $request)
{
return view('circle-xo::profile.following');
Expand Down Expand Up @@ -228,4 +248,14 @@ public function logout()
auth('accounts')->logout();
return redirect()->route('account.login');
}

public function destroy()
{
$account = auth('accounts')->user();
$account->delete();

Toast::success('Account deleted successfully')->autoDismiss(2);
auth('accounts')->logout();
return redirect()->route('account.login');
}
}
26 changes: 26 additions & 0 deletions Modules/CircleXO/resources/views/auth/login.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,40 @@ class="w-full lg:w-1/2"
<x-splade-input type="text" name="username" :label="__('Username')" />
<x-splade-input type="password" name="password" :label="__('Password')" />
<x-splade-submit spinner :label="__('Login')" class="bg-main-600 border-main-400 text-zinc-900" />

<p class="mt-4 text-sm text-zinc-300 sm:mt-0">
{{__("Don't have an account?")}}
<x-splade-link href="{{route('account.register')}}" class="text-zinc-400 underline">{{__('Register')}}</x-splade-link>.
{{__("lose your password?")}}
<x-splade-link href="{{route('account.reset')}}" class="text-zinc-400 underline">{{__('Reset Password')}}</x-splade-link>.
</p>
</x-splade-form>


</x-circle-xo-card>

<div class="my-4 text-center">
<div>
{{__('Or Login with Social Media')}}
</div>
</div>
<div class="flex justify-center gap-2">
<x-tomato-admin-tooltip :text="__('Login With GitHub')">
<a href="{{ url('login/github') }}">
<i class="bx bxl-github text-4xl text-zinc-400"></i>
</a>
</x-tomato-admin-tooltip>
<x-tomato-admin-tooltip :text="__('Login With Twitter')">
<a href="{{ url('login/twitter') }}">
<i class="bx bxl-twitter text-4xl text-zinc-400"></i>
</a>
</x-tomato-admin-tooltip>
<x-tomato-admin-tooltip :text="__('Login With Discord')">
<a href="{{ url('login/discord') }}">
<i class="bx bxl-discord text-4xl text-zinc-400"></i>
</a>
</x-tomato-admin-tooltip>
</div>
</div>
</div>

Expand Down
23 changes: 23 additions & 0 deletions Modules/CircleXO/resources/views/auth/register.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ class="w-full lg:w-1/2"


</x-circle-xo-card>

<div class="my-4 text-center">
<div>
{{__('Or Register with Social Media')}}
</div>
</div>
<div class="flex justify-center gap-2">
<x-tomato-admin-tooltip :text="__('Register With GitHub')">
<a href="{{ url('login/github') }}">
<i class="bx bxl-github text-4xl text-zinc-400"></i>
</a>
</x-tomato-admin-tooltip>
<x-tomato-admin-tooltip :text="__('Register With Twitter')">
<a href="{{ url('login/twitter') }}">
<i class="bx bxl-twitter text-4xl text-zinc-400"></i>
</a>
</x-tomato-admin-tooltip>
<x-tomato-admin-tooltip :text="__('Register With Discord')">
<a href="{{ url('login/discord') }}">
<i class="bx bxl-discord text-4xl text-zinc-400"></i>
</a>
</x-tomato-admin-tooltip>
</div>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@
</x-slot:button>
<x-tomato-admin-dropdown-item modal type="link" icon="bx bx-edit" :label="__('Edit Profile')" href="{{ route('profile.info.show') }}" />
<x-tomato-admin-dropdown-item modal type="link" icon="bx bx-lock" :label="__('Edit Password')" href="{{ route('profile.password.show') }}" />
<x-tomato-admin-dropdown-item modal type="link" icon="bx bxl-twitter" :label="__('Link Social Account')" href="{{ route('profile.social-accounts.show') }}" />
<x-tomato-admin-dropdown-item modal type="link" icon="bx bx-plus-circle" :label="__('List Item')" href="{{ route('profile.listing.create') }}" />
<x-tomato-admin-dropdown-item type="link" icon="bx bx-message" :label="__('Messages')" href="{{ route('profile.messages') }}" />
<x-tomato-admin-dropdown-item type="link" icon="bx bxs-user-plus" :label="__('Following')" href="{{ route('profile.following') }}" />
<x-tomato-admin-dropdown-item type="link" method="DELETE" confirm-danger icon="bx bxs-trash" danger :label="__('Delete Account')" href="{{ route('profile.destroy') }}" />
</x-tomato-admin-dropdown>
</x-tomato-admin-tooltip>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<x-splade-modal>
<x-slot:title>
{{ __('Link Social Accounts') }}
</x-slot>
<div class="flex flex-col gap-4">
@if(!auth('accounts')->user()->meta('twitter-oauth-2_id'))
<a href="{{ url('login/twitter') }}" class="flex justify-center gap-2 text-white px-4 py-2 rounded-lg" style="background-color: #1DA1F2">
<div class="flex flex-col justify-center items-center">
<i class="bx bxl-twitter text-lg"></i>
</div>
<div>
{{__('Link Twitter Account')}}
</div>
</a>
@else
<x-splade-link confirm-danger method="POST" data="{'provider': 'twitter-oauth-2'}" href="{{ route('profile.social-accounts.update') }}" class="flex justify-center gap-2 text-white px-4 py-2 rounded-lg bg-danger-500" >
<div class="flex flex-col justify-center items-center">
<i class="bx bxl-twitter text-lg"></i>
</div>
<div>
{{__('Disconnect Twitter Account')}}
</div>
</x-splade-link>
@endif
@if(!auth('accounts')->user()->meta('github_id'))
<a href="{{ url('login/github') }}" class="flex justify-center gap-2 text-white bg-zinc-700 px-4 py-2 rounded-lg">
<div class="flex flex-col justify-center items-center">
<i class="bx bxl-github text-lg"></i>
</div>
<div>
{{__('Link GitHub Account')}}
</div>
</a>
@else
<x-splade-link confirm-danger method="POST" data="{'provider': 'github'}" href="{{ route('profile.social-accounts.update') }}" class="flex justify-center gap-2 text-white bg-danger-500 px-4 py-2 rounded-lg">
<div class="flex flex-col justify-center items-center">
<i class="bx bxl-github text-lg"></i>
</div>
<div>
{{__('Disconnect GitHub Account')}}
</div>
</x-splade-link>
@endif
@if(!auth('accounts')->user()->meta('discord_id'))
<a href="{{ url('login/discord') }}" class="flex justify-center gap-2 text-white px-4 py-2 rounded-lg" style="background-color: #7289da">
<div class="flex flex-col justify-center items-center">
<i class="bx bxl-discord text-lg"></i>
</div>
<div>
{{__('Link Discord Account')}}
</div>
</a>
@else
<x-splade-link confirm-danger method="POST" data="{'provider': 'discord'}" href="{{ route('profile.social-accounts.update') }}" class="flex justify-center gap-2 text-white px-4 py-2 rounded-lg bg-danger-500">
<div class="flex flex-col justify-center items-center">
<i class="bx bxl-discord text-lg"></i>
</div>
<div>
{{__('Disconnect Discord Account')}}
</div>
</x-splade-link>
@endif
</div>
</x-splade-modal>
8 changes: 8 additions & 0 deletions Modules/CircleXO/routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
Route::get('/', [CircleXOController::class, 'index'])->name('home');
});

Route::middleware('web')->group(function (){
Route::get('/login/{provider}', [AuthController::class, 'provider'])->name('provider');
Route::get('/login/{provider}/callback', [AuthController::class, 'callback'])->name('provider.callback');
});

Route::middleware(['splade', 'throttle:10'])->name('account.')->prefix('auth')->group(function (){
Route::get('/register', [AuthController::class, 'register'])->name('register');
Route::post('/register', [AuthController::class, 'store'])->name('register.store');
Expand All @@ -43,11 +48,14 @@

Route::middleware(['splade', 'auth:accounts'])->prefix('profile')->name('profile.')->group(function (){
Route::get('/', [ProfileController::class, 'index'])->name('index');
Route::delete('/destroy', [ProfileController::class, 'destroy'])->name('destroy');
Route::get('/qr', [ProfileController::class, 'qr'])->name('qr');
Route::post('/qr', [ProfileController::class, 'qrUpdate'])->name('qr.update');
Route::get('/following', [ProfileController::class, 'following'])->name('following');
Route::get('/messages', [ProfileController::class, 'messages'])->name('messages');
Route::get('/messages/{message}', [ProfileController::class, 'message'])->name('messages.show');
Route::get('/edit/social-accounts', [ProfileController::class, 'socialAccounts'])->name('social-accounts.show');
Route::post('/edit/social-accounts', [ProfileController::class, 'socialAccountsUpdate'])->name('social-accounts.update');
Route::get('/edit/password', [ProfileController::class, 'password'])->name('password.show');
Route::post('/edit/password', [ProfileController::class, 'updatePassword'])->name('password.update');
Route::get('/edit/avatar', [ProfileController::class, 'avatar'])->name('avatar.show');
Expand Down
1 change: 1 addition & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

class AppServiceProvider extends ServiceProvider
{

/**
* Register any application services.
*/
Expand Down
Loading

0 comments on commit aa3feb5

Please sign in to comment.