Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.x] Socialite Support #444

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
521fcd3
Added socialite support
Nov 13, 2020
200f421
fix socialite feature options
Nov 13, 2020
c9c2c61
added fill=currentColor to all SVGs
Nov 16, 2020
be50e3c
only show delete account if the user has a password
Nov 19, 2020
f8e1642
simplify logic in show profile views
Nov 19, 2020
b16d075
fix feature flag
Nov 19, 2020
aa7e6b2
bugfix
Nov 20, 2020
e3dbc72
update authentication process
Nov 20, 2020
80438b6
fixes to authentication
Nov 20, 2020
775ec47
handle access denied
Nov 20, 2020
2694563
display danger banner if permission to connect is denied from user/pr…
Nov 20, 2020
86a4833
Use dropIfExists
joelbutcher Nov 21, 2020
148544d
refactor
Nov 22, 2020
ad63438
redirect if provider user is existing and belongs to a different user
Nov 22, 2020
28b4c59
don't create dupe accounts
Nov 22, 2020
436082e
use dangerBanner
Nov 22, 2020
32f58aa
style fixes
Nov 22, 2020
9eb8161
remove connected accounts if a password is set
Nov 22, 2020
fad264e
fix 500 when denying access
Nov 22, 2020
6091544
show banner on setting password. Fix bottom section border if no pass…
Nov 22, 2020
e26cf2c
more updates to section borders
Nov 22, 2020
dd40dc3
emit saved instead of refresh
Nov 22, 2020
7314158
added banner interaction when account removed
Nov 25, 2020
fcf6472
fix duplicate keys
Nov 28, 2020
19b7d8c
fix inertia 'not connected' message
Nov 28, 2020
ad45cf2
fix profile/Show.vue not expecting the hasPassword prop
Nov 28, 2020
bf92457
added missing 'set-password' route for inertia stack
Nov 28, 2020
135cbfa
Update resources/views/components/socialite.blade.php
joelbutcher Nov 29, 2020
9ed24be
define supported socialite provides in src\jetstream.php and reuse
Dec 2, 2020
31571c1
type check linked in icon
Dec 6, 2020
9480d3d
rename route from 'socialite' to 'oauth'
Dec 6, 2020
06bce2b
Update ConnectedAccount.vue
joelbutcher Dec 8, 2020
79a6d13
refactor controller logic
Dec 17, 2020
9304459
remove unused trait
Dec 17, 2020
f92aed9
allow users email to be updated
Dec 17, 2020
af92c6e
Style CI fixes
Dec 17, 2020
256f1ba
Style CI fixes
Dec 17, 2020
ba79d43
fix call to undefined method
Dec 17, 2020
ccd2d55
mark users email as verified
Dec 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
"ext-json": "*",
"illuminate/support": "^8.0",
"jenssegers/agent": "^2.6",
"league/commonmark": "^1.3",
"laravel/fortify": "^1.6.1"
"laravel/fortify": "^1.6.1",
"laravel/socialite": "^5.0",
"league/commonmark": "^1.3"
},
"require-dev": {
"inertiajs/inertia-laravel": "^0.3",
Expand Down
1 change: 1 addition & 0 deletions config/jetstream.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

'features' => [
// Features::termsAndPrivacyPolicy(),
// Features::socialite(['facebook' => true, 'github' => true]),
// Features::profilePhotos(),
// Features::api(),
// Features::teams(['invitations' => true]),
Expand Down
5 changes: 4 additions & 1 deletion database/migrations/2014_10_12_000000_create_users_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Laravel\Jetstream\Features;

class CreateUsersTable extends Migration
{
Expand All @@ -18,7 +19,9 @@ public function up()
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('password')->nullable(
Features::hasSocialiteFeatures()
joelbutcher marked this conversation as resolved.
Show resolved Hide resolved
);
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->text('profile_photo_path')->nullable();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateConnectedAccountsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('connected_accounts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id');
$table->string('provider_name');
$table->string('provider_id');
$table->string('token');
$table->string('secret')->nullable(); // OAuth1
$table->string('refresh_token')->nullable(); // OAuth2
$table->dateTime('expires_at')->nullable(); // OAuth2
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('connected_accounts');
}
}
3 changes: 3 additions & 0 deletions resources/views/components/action-link.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<a {{ $attributes->merge(['class' => 'inline-flex items-center px-4 py-2 bg-white border border-gray-800 rounded-md font-semibold text-xs text-gray-800 uppercase tracking-widest hover:bg-gray-200 hover:border-gray-600 active:border-gray-900 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray disabled:opacity-25 transition ease-in-out duration-150'])}}>
{{ $slot }}
</a>
10 changes: 10 additions & 0 deletions resources/views/components/bitbucket-icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<svg fill="currentColor" xmlns="http:https://www.w3.org/2000/svg" viewBox="0 0 24 24" {{ $attributes }}>
<polygon points="9.5,15.5 14.5,15.5 15.7,8.5 8.2,8.5" fill="none"/>
<path d="M0.8,1.2C0.4,1.2,0,1.5,0,2c0,0,0,0.1,0,0.1l3.3,19.8c0.1,0.5,0.5,0.9,1,0.9H20c0.4,0,0.7-0.3,0.8-0.6l3.3-20 c0.1-0.4-0.2-0.8-0.6-0.9c0,0-0.1,0-0.1,0L0.8,1.2z M14.5,15.5h-5L8.2,8.5h7.6L14.5,15.5z" fill="#2684FF"/>

<linearGradient id="grad1" gradientUnits="userSpaceOnUse" x1="24.6235" y1="16.2853" x2="12.6969" y2="6.977" gradientTransform="matrix(1 0 0 -1 0 26.73)">
<stop offset="0.18" style="stop-color:#0052CC"/>
<stop offset="1" style="stop-color:#2684FF"/>
</linearGradient>
<path d="M23,8.5h-7.2l-1.2,7.1h-5l-5.9,7c0.2,0.2,0.4,0.3,0.7,0.3H20c0.4,0,0.7-0.3,0.8-0.6L23,8.5z" fill="url(#grad1)"/>
</svg>
44 changes: 44 additions & 0 deletions resources/views/components/connected-account.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@props(['provider', 'createdAt'])

<div class="px-3 flex items-center justify-between">
<div class="flex items-center">
@switch($provider)
@case('facebook')
<x-jet-facebook-icon class="h-6 w-6 mr-2" />
@break
@case('google')
<x-jet-google-icon class="h-6 w-6 mr-2" />
@break
@case('twitter')
<x-jet-twitter-icon class="h-6 w-6 mr-2" />
@break
@case('linkedin')
<x-jet-linked-in-icon class="h-6 w-6 mr-2" />
@break
@case('github')
<x-jet-github-icon class="h-6 w-6 mr-2" />
@break
@case('gitlab')
<x-jet-gitlab-icon class="h-6 w-6 mr-2" />
@break
@case('bitbucket')
<x-jet-bitbucket-icon class="h-6 w-6 mr-2" />
@break
@default
@endswitch

<div>
<div class="text-sm font-semibold text-gray-600">
{{ ucfirst($provider) }}
</div>

<div class="text-xs text-gray-500">
{{ $createdAt }}
</div>
</div>
</div>

<div>
{{ $action }}
</div>
</div>
3 changes: 3 additions & 0 deletions resources/views/components/facebook-icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http:https://www.w3.org/2000/svg" style="color: #1778F2;" {{ $attributes }}>
<path d="M23.9981 11.9991C23.9981 5.37216 18.626 0 11.9991 0C5.37216 0 0 5.37216 0 11.9991C0 17.9882 4.38789 22.9522 10.1242 23.8524V15.4676H7.07758V11.9991H10.1242V9.35553C10.1242 6.34826 11.9156 4.68714 14.6564 4.68714C15.9692 4.68714 17.3424 4.92149 17.3424 4.92149V7.87439H15.8294C14.3388 7.87439 13.8739 8.79933 13.8739 9.74824V11.9991H17.2018L16.6698 15.4676H13.8739V23.8524C19.6103 22.9522 23.9981 17.9882 23.9981 11.9991Z"/>
</svg>
3 changes: 3 additions & 0 deletions resources/views/components/github-icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http:https://www.w3.org/2000/svg" {{ $attributes }}>
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
</svg>
9 changes: 9 additions & 0 deletions resources/views/components/gitlab-icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<svg fill="currentColor" xmlns="http:https://www.w3.org/2000/svg" fill-rule="evenodd" viewBox="0 0 24 24" {{ $attributes }}>
<path d="M12,23.1l4.4-13.6H7.6L12,23.1z" fill="#E24329"/>
<path d="M12,23.1L7.6,9.4H1.4L12,23.1z" fill="#FC6D26"/>
<path d="M1.4,9.4L0,13.6c-0.1,0.4,0,0.8,0.3,1L12,23.1L1.4,9.4z" fill="#FCA326"/>
<path d="M1.4,9.4h6.2L4.9,1.3C4.8,0.8,4.2,0.8,4,1.3L1.4,9.4z" fill="#E24329"/>
<path d="M12,23.1l4.4-13.6h6.2L12,23.1z" fill="#FC6D26"/>
<path d="M22.6,9.4l1.3,4.1c0.1,0.4,0,0.8-0.3,1L12,23.1L22.6,9.4z" fill="#FCA326"/>
<path d="M22.6,9.4h-6.2l2.7-8.2c0.1-0.4,0.7-0.4,0.9,0L22.6,9.4z" fill="#E24329"/>
</svg>
6 changes: 6 additions & 0 deletions resources/views/components/google-icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<svg fill="currentColor" viewBox="0 0 533.5 544.3" xmlns="http:https://www.w3.org/2000/svg" {{ $attributes }}>
<path d="M533.5 278.4c0-18.5-1.5-37.1-4.7-55.3H272.1v104.8h147c-6.1 33.8-25.7 63.7-54.4 82.7v68h87.7c51.5-47.4 81.1-117.4 81.1-200.2z" fill="#4285f4"/>
<path d="M272.1 544.3c73.4 0 135.3-24.1 180.4-65.7l-87.7-68c-24.4 16.6-55.9 26-92.6 26-71 0-131.2-47.9-152.8-112.3H28.9v70.1c46.2 91.9 140.3 149.9 243.2 149.9z" fill="#34a853"/>
<path d="M119.3 324.3c-11.4-33.8-11.4-70.4 0-104.2V150H28.9c-38.6 76.9-38.6 167.5 0 244.4l90.4-70.1z" fill="#fbbc04"/>
<path d="M272.1 107.7c38.8-.6 76.3 14 104.4 40.8l77.7-77.7C405 24.6 339.7-.8 272.1 0 169.2 0 75.1 58 28.9 150l90.4 70.1c21.5-64.5 81.8-112.4 152.8-112.4z" fill="#ea4335"/>
</svg>
3 changes: 3 additions & 0 deletions resources/views/components/linked-in-icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http:https://www.w3.org/2000/svg" style="color: #0e76a8;" {{ $attributes }}>
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-2 16h-2v-6h2v6zm-1-6.891c-.607 0-1.1-.496-1.1-1.109 0-.612.492-1.109 1.1-1.109s1.1.497 1.1 1.109c0 .613-.493 1.109-1.1 1.109zm8 6.891h-1.998v-2.861c0-1.881-2.002-1.722-2.002 0v2.861h-2v-6h2v1.093c.872-1.616 4-1.736 4 1.548v3.359z"/>
</svg>
49 changes: 49 additions & 0 deletions resources/views/components/socialite.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<div class="flex flex-row items-center justify-between py-4 text-gray-500">
<hr class="w-full mr-2">
{{ __('Or') }}
<hr class="w-full ml-2">
</div>

<div class="flex items-center justify-center">
@if (Laravel\Jetstream\JetStream::hasSocialiteSupportFor('facebook'))
<a href="{{ route('oauth.redirect', ['provider' => 'facebook']) }}">
<x-jet-facebook-icon class="h-6 w-6 mx-2" />
</a>
@endif

@if (Laravel\Jetstream\JetStream::hasSocialiteSupportFor('google'))
<a href="{{ route('oauth.redirect', ['provider' => 'google']) }}" >
<x-jet-google-icon class="h-6 w-6 mx-2" />
</a>
@endif

@if (Laravel\Jetstream\JetStream::hasSocialiteSupportFor('twitter'))
<a href="{{ route('oauth.redirect', ['provider' => 'twitter']) }}">
<x-jet-twitter-icon class="h-6 w-6 mx-2" />
</a>
@endif

@if (Laravel\Jetstream\JetStream::hasSocialiteSupportFor('linkedin'))
<a href="{{ route('oauth.redirect', ['provider' => 'linkedin']) }}">
<x-jet-linked-in-icon class="h-6 w-6 mx-2" />
</a>
@endif

@if (Laravel\Jetstream\JetStream::hasSocialiteSupportFor('github'))
<a href="{{ route('oauth.redirect', ['provider' => 'github']) }}">
<x-jet-github-icon class="h-6 w-6 mx-2" />
</a>
@endif

@if (Laravel\Jetstream\JetStream::hasSocialiteSupportFor('gitlab'))
<a href="{{ route('oauth.redirect', ['provider' => 'gitlab']) }}">
<x-jet-gitlab-icon class="h-6 w-6 mx-2" />
</a>
@endif

@if (Laravel\Jetstream\JetStream::hasSocialiteSupportFor('bitbucket'))
<a href="{{ route('oauth.redirect', ['provider' => 'bitbucket']) }}">
<x-jet-bitbucket-icon />
</a>
@endif
</div>
3 changes: 3 additions & 0 deletions resources/views/components/twitter-icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http:https://www.w3.org/2000/svg" style="color: #00acee;" {{ $attributes }}>
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm6.066 9.645c.183 4.04-2.83 8.544-8.164 8.544-1.622 0-3.131-.476-4.402-1.291 1.524.18 3.045-.244 4.252-1.189-1.256-.023-2.317-.854-2.684-1.995.451.086.895.061 1.298-.049-1.381-.278-2.335-1.522-2.304-2.853.388.215.83.344 1.301.359-1.279-.855-1.641-2.544-.889-3.835 1.416 1.738 3.533 2.881 5.92 3.001-.419-1.796.944-3.527 2.799-3.527.825 0 1.572.349 2.096.907.654-.128 1.27-.368 1.824-.697-.215.671-.67 1.233-1.263 1.589.581-.07 1.135-.224 1.649-.453-.384.578-.87 1.084-1.433 1.489z"/>
</svg>
19 changes: 19 additions & 0 deletions routes/inertia.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<?php

use Illuminate\Support\Facades\Route;
use Laravel\Jetstream\Features;
use Laravel\Jetstream\Http\Controllers\CurrentTeamController;
use Laravel\Jetstream\Http\Controllers\Inertia\ApiTokenController;
use Laravel\Jetstream\Http\Controllers\Inertia\CurrentUserController;
use Laravel\Jetstream\Http\Controllers\Inertia\OtherBrowserSessionsController;
use Laravel\Jetstream\Http\Controllers\Inertia\PasswordController;
use Laravel\Jetstream\Http\Controllers\Inertia\PrivacyPolicyController;
use Laravel\Jetstream\Http\Controllers\Inertia\ProfilePhotoController;
use Laravel\Jetstream\Http\Controllers\Inertia\RemoveConnectedAccountsController;
use Laravel\Jetstream\Http\Controllers\Inertia\TeamController;
use Laravel\Jetstream\Http\Controllers\Inertia\TeamMemberController;
use Laravel\Jetstream\Http\Controllers\Inertia\TermsOfServiceController;
use Laravel\Jetstream\Http\Controllers\Inertia\UserProfileController;
use Laravel\Jetstream\Http\Controllers\SocialiteController;
use Laravel\Jetstream\Http\Controllers\TeamInvitationController;
use Laravel\Jetstream\Jetstream;

Expand All @@ -28,6 +32,12 @@
Route::delete('/user/other-browser-sessions', [OtherBrowserSessionsController::class, 'destroy'])
->name('other-browser-sessions.destroy');

Route::delete('/user/connected-account/{id}', [RemoveConnectedAccountsController::class, 'destroy'])
->name('connected-accounts.destroy');

Route::delete('/user', [CurrentUserController::class, 'destroy'])
->name('current-user.destroy');

Route::delete('/user/profile-photo', [ProfilePhotoController::class, 'destroy'])
->name('current-user-photo.destroy');

Expand Down Expand Up @@ -64,4 +74,13 @@
->name('team-invitations.destroy');
}
});

// Socialite...
if (Jetstream::hasSocialiteFeatures()) {
Route::get('/oauth/{provider}', [SocialiteController::class, 'redirectToProvider'])->name('oauth.redirect');
Route::get('/oauth/{provider}/callback', [SocialiteController::class, 'handleProviderCallback'])->name('oauth.callback');

// Set user password
Route::put('/user/set-password', [PasswordController::class, 'store'])->name('user-password.set');
}
});
7 changes: 7 additions & 0 deletions routes/livewire.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Laravel\Jetstream\Http\Controllers\Livewire\TeamController;
use Laravel\Jetstream\Http\Controllers\Livewire\TermsOfServiceController;
use Laravel\Jetstream\Http\Controllers\Livewire\UserProfileController;
use Laravel\Jetstream\Http\Controllers\SocialiteController;
use Laravel\Jetstream\Http\Controllers\TeamInvitationController;
use Laravel\Jetstream\Jetstream;

Expand Down Expand Up @@ -37,4 +38,10 @@
->name('team-invitations.accept');
}
});

// Socialite...
if (Jetstream::hasSocialiteFeatures()) {
Route::get('/oauth/{provider}', [SocialiteController::class, 'redirectToProvider'])->name('oauth.redirect');
Route::get('/oauth/{provider}/callback', [SocialiteController::class, 'handleProviderCallback'])->name('oauth.callback');
}
});
31 changes: 31 additions & 0 deletions src/Actions/SetUserPassword.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Laravel\Jetstream\Actions;

use App\Actions\Fortify\PasswordValidationRules;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Jetstream\Contracts\SetsUserPasswords;

class SetUserPassword implements SetsUserPasswords
{
use PasswordValidationRules;

/**
* Validate and update the user's password.
*
* @param mixed $user
* @param array $input
* @return void
*/
public function set($user, array $input)
{
Validator::make($input, [
'password' => $this->passwordRules(),
])->validateWithBag('setPassword');

$user->forceFill([
'password' => Hash::make($input['password']),
])->save();
}
}
18 changes: 18 additions & 0 deletions src/ConnectedAccount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Laravel\Jetstream;

use Illuminate\Database\Eloquent\Model;

abstract class ConnectedAccount extends Model
{
/**
* Get user of the connected account.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(Jetstream::userModel(), 'user_id');
}
}
Loading