From af317c38481317a8508828d8c2f396c0c4003bf4 Mon Sep 17 00:00:00 2001 From: Curtis Delicata Date: Thu, 13 Jun 2024 03:39:42 +0000 Subject: [PATCH] Missing Jetstream/Socialstream code --- app/Actions/Fortify/CreateNewUser.php | 40 +++++++++ .../Fortify/PasswordValidationRules.php | 18 +++++ app/Actions/Fortify/ResetUserPassword.php | 29 +++++++ app/Actions/Fortify/UpdateUserPassword.php | 32 ++++++++ .../Fortify/UpdateUserProfileInformation.php | 58 +++++++++++++ app/Actions/Jetstream/DeleteUser.php | 22 +++++ .../Socialstream/CreateConnectedAccount.php | 31 +++++++ .../Socialstream/CreateUserFromProvider.php | 47 +++++++++++ .../GenerateRedirectForProvider.php | 18 +++++ .../Socialstream/HandleInvalidState.php | 18 +++++ .../Socialstream/ResolveSocialiteUser.php | 25 ++++++ app/Actions/Socialstream/SetUserPassword.php | 25 ++++++ .../Socialstream/UpdateConnectedAccount.php | 54 +++++++++++++ app/Models/ConnectedAccount.php | 55 +++++++++++++ app/Policies/ConnectedAccountPolicy.php | 52 ++++++++++++ app/Providers/FortifyServiceProvider.php | 46 +++++++++++ app/Providers/SocialstreamServiceProvider.php | 36 +++++++++ .../factories/ConnectedAccountFactory.php | 26 ++++++ .../0001_01_01_000000_create_users_table.php | 51 ++++++++++++ ..._make_password_nullable_on_users_table.php | 28 +++++++ ...000002_create_connected_accounts_table.php | 42 ++++++++++ resources/views/auth/login.blade.php | 52 ++++++++++++ resources/views/auth/register.blade.php | 64 +++++++++++++++ .../views/components/action-link.blade.php | 3 + .../components/connected-account.blade.php | 35 ++++++++ .../socialstream-icons/bitbucket.blade.php | 10 +++ .../socialstream-icons/facebook.blade.php | 3 + .../socialstream-icons/github.blade.php | 3 + .../socialstream-icons/gitlab.blade.php | 9 +++ .../socialstream-icons/google.blade.php | 6 ++ .../socialstream-icons/linkedin.blade.php | 4 + .../provider-icon.blade.php | 38 +++++++++ .../socialstream-icons/slack.blade.php | 20 +++++ .../socialstream-icons/twitter.blade.php | 3 + .../views/components/socialstream.blade.php | 23 ++++++ .../components/validation-errors.blade.php | 12 +++ .../profile/connected-accounts-form.blade.php | 81 +++++++++++++++++++ .../views/profile/set-password-form.blade.php | 33 ++++++++ resources/views/profile/show.blade.php | 62 ++++++++++++++ routes/socialstream.php | 9 +++ routes/web.php | 2 +- 41 files changed, 1224 insertions(+), 1 deletion(-) create mode 100644 app/Actions/Fortify/CreateNewUser.php create mode 100644 app/Actions/Fortify/PasswordValidationRules.php create mode 100644 app/Actions/Fortify/ResetUserPassword.php create mode 100644 app/Actions/Fortify/UpdateUserPassword.php create mode 100644 app/Actions/Fortify/UpdateUserProfileInformation.php create mode 100644 app/Actions/Jetstream/DeleteUser.php create mode 100644 app/Actions/Socialstream/CreateConnectedAccount.php create mode 100644 app/Actions/Socialstream/CreateUserFromProvider.php create mode 100644 app/Actions/Socialstream/GenerateRedirectForProvider.php create mode 100644 app/Actions/Socialstream/HandleInvalidState.php create mode 100644 app/Actions/Socialstream/ResolveSocialiteUser.php create mode 100644 app/Actions/Socialstream/SetUserPassword.php create mode 100644 app/Actions/Socialstream/UpdateConnectedAccount.php create mode 100644 app/Models/ConnectedAccount.php create mode 100644 app/Policies/ConnectedAccountPolicy.php create mode 100644 app/Providers/FortifyServiceProvider.php create mode 100644 app/Providers/SocialstreamServiceProvider.php create mode 100644 database/factories/ConnectedAccountFactory.php create mode 100644 database/migrations/0001_01_01_000000_create_users_table.php create mode 100644 database/migrations/0001_01_01_000001_make_password_nullable_on_users_table.php create mode 100644 database/migrations/0001_01_01_000002_create_connected_accounts_table.php create mode 100644 resources/views/auth/login.blade.php create mode 100644 resources/views/auth/register.blade.php create mode 100644 resources/views/components/action-link.blade.php create mode 100644 resources/views/components/connected-account.blade.php create mode 100644 resources/views/components/socialstream-icons/bitbucket.blade.php create mode 100644 resources/views/components/socialstream-icons/facebook.blade.php create mode 100644 resources/views/components/socialstream-icons/github.blade.php create mode 100644 resources/views/components/socialstream-icons/gitlab.blade.php create mode 100644 resources/views/components/socialstream-icons/google.blade.php create mode 100644 resources/views/components/socialstream-icons/linkedin.blade.php create mode 100644 resources/views/components/socialstream-icons/provider-icon.blade.php create mode 100644 resources/views/components/socialstream-icons/slack.blade.php create mode 100644 resources/views/components/socialstream-icons/twitter.blade.php create mode 100644 resources/views/components/socialstream.blade.php create mode 100644 resources/views/components/validation-errors.blade.php create mode 100644 resources/views/profile/connected-accounts-form.blade.php create mode 100644 resources/views/profile/set-password-form.blade.php create mode 100644 resources/views/profile/show.blade.php create mode 100644 routes/socialstream.php diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php new file mode 100644 index 00000000..7bf18d0a --- /dev/null +++ b/app/Actions/Fortify/CreateNewUser.php @@ -0,0 +1,40 @@ + $input + */ + public function create(array $input): User + { + Validator::make($input, [ + 'name' => ['required', 'string', 'max:255'], + 'email' => [ + 'required', + 'string', + 'email', + 'max:255', + Rule::unique(User::class), + ], + 'password' => $this->passwordRules(), + ])->validate(); + + return User::create([ + 'name' => $input['name'], + 'email' => $input['email'], + 'password' => Hash::make($input['password']), + ]); + } +} diff --git a/app/Actions/Fortify/PasswordValidationRules.php b/app/Actions/Fortify/PasswordValidationRules.php new file mode 100644 index 00000000..76b19d33 --- /dev/null +++ b/app/Actions/Fortify/PasswordValidationRules.php @@ -0,0 +1,18 @@ +|string> + */ + protected function passwordRules(): array + { + return ['required', 'string', Password::default(), 'confirmed']; + } +} diff --git a/app/Actions/Fortify/ResetUserPassword.php b/app/Actions/Fortify/ResetUserPassword.php new file mode 100644 index 00000000..7a57c503 --- /dev/null +++ b/app/Actions/Fortify/ResetUserPassword.php @@ -0,0 +1,29 @@ + $input + */ + public function reset(User $user, array $input): void + { + Validator::make($input, [ + 'password' => $this->passwordRules(), + ])->validate(); + + $user->forceFill([ + 'password' => Hash::make($input['password']), + ])->save(); + } +} diff --git a/app/Actions/Fortify/UpdateUserPassword.php b/app/Actions/Fortify/UpdateUserPassword.php new file mode 100644 index 00000000..70056390 --- /dev/null +++ b/app/Actions/Fortify/UpdateUserPassword.php @@ -0,0 +1,32 @@ + $input + */ + public function update(User $user, array $input): void + { + Validator::make($input, [ + 'current_password' => ['required', 'string', 'current_password:web'], + 'password' => $this->passwordRules(), + ], [ + 'current_password.current_password' => __('The provided password does not match your current password.'), + ])->validateWithBag('updatePassword'); + + $user->forceFill([ + 'password' => Hash::make($input['password']), + ])->save(); + } +} diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php new file mode 100644 index 00000000..0930ddf3 --- /dev/null +++ b/app/Actions/Fortify/UpdateUserProfileInformation.php @@ -0,0 +1,58 @@ + $input + */ + public function update(User $user, array $input): void + { + Validator::make($input, [ + 'name' => ['required', 'string', 'max:255'], + + 'email' => [ + 'required', + 'string', + 'email', + 'max:255', + Rule::unique('users')->ignore($user->id), + ], + ])->validateWithBag('updateProfileInformation'); + + if ($input['email'] !== $user->email && + $user instanceof MustVerifyEmail) { + $this->updateVerifiedUser($user, $input); + } else { + $user->forceFill([ + 'name' => $input['name'], + 'email' => $input['email'], + ])->save(); + } + } + + /** + * Update the given verified user's profile information. + * + * @param array $input + */ + protected function updateVerifiedUser(User $user, array $input): void + { + $user->forceFill([ + 'name' => $input['name'], + 'email' => $input['email'], + 'email_verified_at' => null, + ])->save(); + + $user->sendEmailVerificationNotification(); + } +} diff --git a/app/Actions/Jetstream/DeleteUser.php b/app/Actions/Jetstream/DeleteUser.php new file mode 100644 index 00000000..090b4f40 --- /dev/null +++ b/app/Actions/Jetstream/DeleteUser.php @@ -0,0 +1,22 @@ +deleteProfilePhoto(); + $user->tokens->each->delete(); + $user->connectedAccounts->each->delete(); + $user->delete(); + } +} diff --git a/app/Actions/Socialstream/CreateConnectedAccount.php b/app/Actions/Socialstream/CreateConnectedAccount.php new file mode 100644 index 00000000..df6b4289 --- /dev/null +++ b/app/Actions/Socialstream/CreateConnectedAccount.php @@ -0,0 +1,31 @@ + $user->id, + 'provider' => strtolower($provider), + 'provider_id' => $providerUser->getId(), + 'name' => $providerUser->getName(), + 'nickname' => $providerUser->getNickname(), + 'email' => $providerUser->getEmail(), + 'avatar_path' => $providerUser->getAvatar(), + 'token' => $providerUser->token, + 'secret' => $providerUser->tokenSecret ?? null, + 'refresh_token' => $providerUser->refreshToken ?? null, + 'expires_at' => property_exists($providerUser, 'expiresIn') ? now()->addSeconds($providerUser->expiresIn) : null, + ]); + } +} diff --git a/app/Actions/Socialstream/CreateUserFromProvider.php b/app/Actions/Socialstream/CreateUserFromProvider.php new file mode 100644 index 00000000..2982efcf --- /dev/null +++ b/app/Actions/Socialstream/CreateUserFromProvider.php @@ -0,0 +1,47 @@ +createsConnectedAccounts = $createsConnectedAccounts; + } + + /** + * Create a new user from a social provider user. + */ + public function create(string $provider, ProviderUser $providerUser): User + { + return DB::transaction(function () use ($provider, $providerUser) { + return tap(User::create([ + 'name' => $providerUser->getName() ?? $providerUser->getNickname(), + 'email' => $providerUser->getEmail(), + ]), function (User $user) use ($provider, $providerUser) { + $user->markEmailAsVerified(); + + if (Socialstream::hasProviderAvatarsFeature() && $providerUser->getAvatar()) { + $user->setProfilePhotoFromUrl($providerUser->getAvatar()); + } + + $this->createsConnectedAccounts->create($user, $provider, $providerUser); + }); + }); + } +} diff --git a/app/Actions/Socialstream/GenerateRedirectForProvider.php b/app/Actions/Socialstream/GenerateRedirectForProvider.php new file mode 100644 index 00000000..bba65834 --- /dev/null +++ b/app/Actions/Socialstream/GenerateRedirectForProvider.php @@ -0,0 +1,18 @@ +redirect(); + } +} diff --git a/app/Actions/Socialstream/HandleInvalidState.php b/app/Actions/Socialstream/HandleInvalidState.php new file mode 100644 index 00000000..ef7f779e --- /dev/null +++ b/app/Actions/Socialstream/HandleInvalidState.php @@ -0,0 +1,18 @@ +user(); + + if (Socialstream::generatesMissingEmails()) { + $user->email = $user->getEmail() ?? ("{$user->id}@{$provider}".config('app.domain')); + } + + return $user; + } +} diff --git a/app/Actions/Socialstream/SetUserPassword.php b/app/Actions/Socialstream/SetUserPassword.php new file mode 100644 index 00000000..34538447 --- /dev/null +++ b/app/Actions/Socialstream/SetUserPassword.php @@ -0,0 +1,25 @@ + ['required', 'string', Password::default(), 'confirmed'], + ])->validateWithBag('setPassword'); + + $user->forceFill([ + 'password' => Hash::make($input['password']), + ])->save(); + } +} diff --git a/app/Actions/Socialstream/UpdateConnectedAccount.php b/app/Actions/Socialstream/UpdateConnectedAccount.php new file mode 100644 index 00000000..3aefaec1 --- /dev/null +++ b/app/Actions/Socialstream/UpdateConnectedAccount.php @@ -0,0 +1,54 @@ +authorize('update', $connectedAccount); + + $connectedAccount->forceFill([ + 'provider' => strtolower($provider), + 'provider_id' => $providerUser->getId(), + 'name' => $providerUser->getName(), + 'nickname' => $providerUser->getNickname(), + 'email' => $providerUser->getEmail(), + 'avatar_path' => $providerUser->getAvatar(), + 'token' => $providerUser->token, + 'secret' => $providerUser->tokenSecret ?? null, + 'refresh_token' => $providerUser->refreshToken ?? null, + 'expires_at' => property_exists($providerUser, 'expiresIn') ? now()->addSeconds($providerUser->expiresIn) : null, + ])->save(); + + return $connectedAccount; + } + + /** + * Update the refresh token for the given account. + */ + public function updateRefreshToken(ConnectedAccount $connectedAccount): ConnectedAccount + { + $refreshedCredentials = Socialstream::refreshConnectedAccountToken( + $connectedAccount, + ); + + $connectedAccount->forceFill([ + 'token' => $refreshedCredentials->getToken(), + 'secret' => $refreshedCredentials->getTokenSecret(), + 'refresh_token' => $refreshedCredentials->getRefreshToken(), + 'expires_at' => $refreshedCredentials->getExpiry(), + ])->save(); + + return $connectedAccount; + } +} diff --git a/app/Models/ConnectedAccount.php b/app/Models/ConnectedAccount.php new file mode 100644 index 00000000..88d81d39 --- /dev/null +++ b/app/Models/ConnectedAccount.php @@ -0,0 +1,55 @@ + 'datetime', + 'expires_at' => 'datetime', + ]; + + /** + * The event map for the model. + * + * @var array + */ + protected $dispatchesEvents = [ + 'created' => ConnectedAccountCreated::class, + 'updated' => ConnectedAccountUpdated::class, + 'deleted' => ConnectedAccountDeleted::class, + ]; +} diff --git a/app/Policies/ConnectedAccountPolicy.php b/app/Policies/ConnectedAccountPolicy.php new file mode 100644 index 00000000..c66cabb8 --- /dev/null +++ b/app/Policies/ConnectedAccountPolicy.php @@ -0,0 +1,52 @@ +ownsConnectedAccount($connectedAccount); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, ConnectedAccount $connectedAccount): bool + { + return $user->ownsConnectedAccount($connectedAccount); + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, ConnectedAccount $connectedAccount): bool + { + return $user->ownsConnectedAccount($connectedAccount); + } +} diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php new file mode 100644 index 00000000..2d741e38 --- /dev/null +++ b/app/Providers/FortifyServiceProvider.php @@ -0,0 +1,46 @@ +input(Fortify::username())).'|'.$request->ip()); + + return Limit::perMinute(5)->by($throttleKey); + }); + + RateLimiter::for('two-factor', function (Request $request) { + return Limit::perMinute(5)->by($request->session()->get('login.id')); + }); + } +} diff --git a/app/Providers/SocialstreamServiceProvider.php b/app/Providers/SocialstreamServiceProvider.php new file mode 100644 index 00000000..894954c6 --- /dev/null +++ b/app/Providers/SocialstreamServiceProvider.php @@ -0,0 +1,36 @@ + + */ +class ConnectedAccountFactory extends Factory +{ + protected $model = ConnectedAccount::class; + + public function definition(): array + { + return [ + 'provider' => $this->faker->randomElement(Providers::all()), + 'provider_id' => $this->faker->numerify('########'), + 'token' => Str::random(432), + 'refresh_token' => Str::random(432), + ]; + } +} diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php new file mode 100644 index 00000000..31d78072 --- /dev/null +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -0,0 +1,51 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->rememberToken(); + $table->foreignId('current_team_id')->nullable(); + $table->string('profile_photo_path', 2048)->nullable(); + $table->timestamps(); + }); + + Schema::create('password_reset_tokens', function (Blueprint $table) { + $table->string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + + Schema::create('sessions', function (Blueprint $table) { + $table->string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('users'); + Schema::dropIfExists('password_reset_tokens'); + Schema::dropIfExists('sessions'); + } +}; diff --git a/database/migrations/0001_01_01_000001_make_password_nullable_on_users_table.php b/database/migrations/0001_01_01_000001_make_password_nullable_on_users_table.php new file mode 100644 index 00000000..3bd91b0b --- /dev/null +++ b/database/migrations/0001_01_01_000001_make_password_nullable_on_users_table.php @@ -0,0 +1,28 @@ +string('password')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->string('password')->nullable(false)->change(); + }); + } +}; diff --git a/database/migrations/0001_01_01_000002_create_connected_accounts_table.php b/database/migrations/0001_01_01_000002_create_connected_accounts_table.php new file mode 100644 index 00000000..5bb3883f --- /dev/null +++ b/database/migrations/0001_01_01_000002_create_connected_accounts_table.php @@ -0,0 +1,42 @@ +id(); + $table->foreignId('user_id'); + $table->string('provider'); + $table->string('provider_id'); + $table->string('name')->nullable(); + $table->string('nickname')->nullable(); + $table->string('email')->nullable(); + $table->string('telephone')->nullable(); + $table->text('avatar_path')->nullable(); + $table->string('token', 1000); + $table->string('secret')->nullable(); // OAuth1 + $table->string('refresh_token', 1000)->nullable(); // OAuth2 + $table->dateTime('expires_at')->nullable(); // OAuth2 + $table->timestamps(); + + $table->index(['user_id', 'id']); + $table->index(['provider', 'provider_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('connected_accounts'); + } +}; diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php new file mode 100644 index 00000000..8689ce2c --- /dev/null +++ b/resources/views/auth/login.blade.php @@ -0,0 +1,52 @@ + + + + + + + + + @if (session('status')) +
+ {{ session('status') }} +
+ @endif + +
+ @csrf + +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ @if (Route::has('password.request')) + + {{ __('Forgot your password?') }} + + @endif + + + {{ __('Login') }} + +
+
+ + @if (JoelButcher\Socialstream\Socialstream::show()) + + @endif +
+
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php new file mode 100644 index 00000000..526eeff7 --- /dev/null +++ b/resources/views/auth/register.blade.php @@ -0,0 +1,64 @@ + + + + + + + + +
+ @csrf + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + @if (Laravel\Jetstream\Jetstream::hasTermsAndPrivacyPolicyFeature()) +
+ +
+ + +
+ {!! __('I agree to the :terms_of_service and :privacy_policy', [ + 'terms_of_service' => ''.__('Terms of Service').'', + 'privacy_policy' => ''.__('Privacy Policy').'', + ]) !!} +
+
+
+
+ @endif + +
+ + {{ __('Already registered?') }} + + + + {{ __('Register') }} + +
+
+ + @if (JoelButcher\Socialstream\Socialstream::show()) + + @endif +
+
diff --git a/resources/views/components/action-link.blade.php b/resources/views/components/action-link.blade.php new file mode 100644 index 00000000..ab27f800 --- /dev/null +++ b/resources/views/components/action-link.blade.php @@ -0,0 +1,3 @@ +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 }} + diff --git a/resources/views/components/connected-account.blade.php b/resources/views/components/connected-account.blade.php new file mode 100644 index 00000000..3d84cce4 --- /dev/null +++ b/resources/views/components/connected-account.blade.php @@ -0,0 +1,35 @@ +@props(['provider', 'createdAt' => null]) + +
+
+
+ + +
+
+ {{ __($provider['name']) }} +
+ + @if (! empty($createdAt)) +
+ {{ __('Connected :createdAt', ['createdAt' => $createdAt]) }} +
+ @else +
+ {{ __('Not connected.') }} +
+ @endif +
+
+ +
+ {{ $action }} +
+
+ + @error($provider['id'].'_connect_error') +
+ {{ $message }} +
+ @enderror +
diff --git a/resources/views/components/socialstream-icons/bitbucket.blade.php b/resources/views/components/socialstream-icons/bitbucket.blade.php new file mode 100644 index 00000000..7c02f71e --- /dev/null +++ b/resources/views/components/socialstream-icons/bitbucket.blade.php @@ -0,0 +1,10 @@ + diff --git a/resources/views/components/socialstream-icons/facebook.blade.php b/resources/views/components/socialstream-icons/facebook.blade.php new file mode 100644 index 00000000..d93b9ea2 --- /dev/null +++ b/resources/views/components/socialstream-icons/facebook.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/views/components/socialstream-icons/github.blade.php b/resources/views/components/socialstream-icons/github.blade.php new file mode 100644 index 00000000..c77911b8 --- /dev/null +++ b/resources/views/components/socialstream-icons/github.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/views/components/socialstream-icons/gitlab.blade.php b/resources/views/components/socialstream-icons/gitlab.blade.php new file mode 100644 index 00000000..062a09ce --- /dev/null +++ b/resources/views/components/socialstream-icons/gitlab.blade.php @@ -0,0 +1,9 @@ + diff --git a/resources/views/components/socialstream-icons/google.blade.php b/resources/views/components/socialstream-icons/google.blade.php new file mode 100644 index 00000000..dc4f88e2 --- /dev/null +++ b/resources/views/components/socialstream-icons/google.blade.php @@ -0,0 +1,6 @@ + diff --git a/resources/views/components/socialstream-icons/linkedin.blade.php b/resources/views/components/socialstream-icons/linkedin.blade.php new file mode 100644 index 00000000..3bf39342 --- /dev/null +++ b/resources/views/components/socialstream-icons/linkedin.blade.php @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/resources/views/components/socialstream-icons/provider-icon.blade.php b/resources/views/components/socialstream-icons/provider-icon.blade.php new file mode 100644 index 00000000..3b26b13f --- /dev/null +++ b/resources/views/components/socialstream-icons/provider-icon.blade.php @@ -0,0 +1,38 @@ +
+ @switch($provider) + @case(\JoelButcher\Socialstream\Providers::bitbucket()) + + @break + + @case (JoelButcher\Socialstream\Providers::facebook()) + + @break + + @case (JoelButcher\Socialstream\Providers::github()) + + @break + + @case (JoelButcher\Socialstream\Providers::gitlab()) + + @break + + @case (JoelButcher\Socialstream\Providers::google()) + + @break + + @case (JoelButcher\Socialstream\Providers::linkedin()) + @case (JoelButcher\Socialstream\Providers::linkedinOpenId()) + + @break + + @case (JoelButcher\Socialstream\Providers::slack()) + + @break + + @case (JoelButcher\Socialstream\Providers::twitterOAuth1()) + @case (JoelButcher\Socialstream\Providers::twitterOAuth2()) + @case (JoelButcher\Socialstream\Providers::twitter()) + + @break + @endswitch +
diff --git a/resources/views/components/socialstream-icons/slack.blade.php b/resources/views/components/socialstream-icons/slack.blade.php new file mode 100644 index 00000000..7221e470 --- /dev/null +++ b/resources/views/components/socialstream-icons/slack.blade.php @@ -0,0 +1,20 @@ + diff --git a/resources/views/components/socialstream-icons/twitter.blade.php b/resources/views/components/socialstream-icons/twitter.blade.php new file mode 100644 index 00000000..e2dc8df0 --- /dev/null +++ b/resources/views/components/socialstream-icons/twitter.blade.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/resources/views/components/socialstream.blade.php b/resources/views/components/socialstream.blade.php new file mode 100644 index 00000000..4f6d1b64 --- /dev/null +++ b/resources/views/components/socialstream.blade.php @@ -0,0 +1,23 @@ +
+ @if(! empty(\JoelButcher\Socialstream\Socialstream::providers())) +
+
+ + {{ config('socialstream.prompt', 'Or Login Via') }} + +
+
+ @endif + + + +
+ @foreach (\JoelButcher\Socialstream\Socialstream::providers() as $provider) + + + {{ $provider['buttonLabel'] }} + + @endforeach +
+
diff --git a/resources/views/components/validation-errors.blade.php b/resources/views/components/validation-errors.blade.php new file mode 100644 index 00000000..a62b46e9 --- /dev/null +++ b/resources/views/components/validation-errors.blade.php @@ -0,0 +1,12 @@ +@if ($errors->has('socialstream')) +@elseif ($errors->any()) +
+
{{ __('Whoops! Something went wrong.') }}
+ +
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+@endif diff --git a/resources/views/profile/connected-accounts-form.blade.php b/resources/views/profile/connected-accounts-form.blade.php new file mode 100644 index 00000000..be79e7ca --- /dev/null +++ b/resources/views/profile/connected-accounts-form.blade.php @@ -0,0 +1,81 @@ + + + {{ __('Connected Accounts') }} + + + + {{ __('Connect your social media accounts to enable Sign In with OAuth.') }} + + + +
+ {{ __('If you feel any of your connected accounts have been compromised, you should disconnect them immediately and change your password.') }} +
+ +
+ @foreach ($this->providers as $provider) + @php + $account = null; + $account = $this->accounts->where('provider', $provider['id'])->first(); + @endphp + + + + @if (! is_null($account)) +
+ @if (Laravel\Jetstream\Jetstream::managesProfilePhotos() && ! is_null($account->avatar_path)) + + @endif + + @if (($this->accounts->count() > 1 || ! is_null(auth()->user()->getAuthPassword()))) + + {{ __('Remove') }} + + @endif +
+ @else + + {{ __('Connect') }} + + @endif +
+ +
+ @endforeach +
+ + + + + {{ __('Are you sure you want to remove this account?') }} + + + + {{ __('Please enter your password to confirm you would like to remove this account.') }} + +
+ + + +
+
+ + + + {{ __('Cancel') }} + + + + {{ __('Remove Account') }} + + +
+
+
diff --git a/resources/views/profile/set-password-form.blade.php b/resources/views/profile/set-password-form.blade.php new file mode 100644 index 00000000..569524d1 --- /dev/null +++ b/resources/views/profile/set-password-form.blade.php @@ -0,0 +1,33 @@ + + + {{ __('Set Password') }} + + + + {{ __('Ensure your account is using a long, random password to stay secure.') }} + + + +
+ + + +
+ +
+ + + +
+
+ + + + {{ __('Password saved, please refresh.') }} + + + + {{ __('Save') }} + + +
diff --git a/resources/views/profile/show.blade.php b/resources/views/profile/show.blade.php new file mode 100644 index 00000000..dc70a3ab --- /dev/null +++ b/resources/views/profile/show.blade.php @@ -0,0 +1,62 @@ + + +

+ {{ __('Profile') }} +

+
+ +
+
+ @if (Laravel\Fortify\Features::canUpdateProfileInformation()) + @livewire('profile.update-profile-information-form') + + + @endif + + @if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::updatePasswords()) && ! is_null($user->getAuthPassword())) +
+ @livewire('profile.update-password-form') +
+ + + @else +
+ @livewire('profile.set-password-form') +
+ + + @endif + + @if (Laravel\Fortify\Features::canManageTwoFactorAuthentication() && ! is_null($user->getAuthPassword())) +
+ @livewire('profile.two-factor-authentication-form') +
+ + + @endif + + @if (JoelButcher\Socialstream\Socialstream::show()) +
+ @livewire('profile.connected-accounts-form') +
+ @endif + + + @if ( ! is_null($user->getAuthPassword())) + + +
+ @livewire('profile.logout-other-browser-sessions-form') +
+ @endif + + @if (Laravel\Jetstream\Jetstream::hasAccountDeletionFeatures() && ! is_null($user->getAuthPassword())) + + +
+ @livewire('profile.delete-user-form') +
+ @endif +
+
+
diff --git a/routes/socialstream.php b/routes/socialstream.php new file mode 100644 index 00000000..25de99c9 --- /dev/null +++ b/routes/socialstream.php @@ -0,0 +1,9 @@ + config('socialstream.middleware', ['web'])], function () { + Route::get('/oauth/{provider}', [OAuthController::class, 'redirect'])->name('oauth.redirect'); + Route::match(['get', 'post'], '/oauth/{provider}/callback', [OAuthController::class, 'callback'])->name('oauth.callback'); +}); diff --git a/routes/web.php b/routes/web.php index 5b63601f..029b8c98 100644 --- a/routes/web.php +++ b/routes/web.php @@ -16,4 +16,4 @@ Route::get('/', function () { return view('welcome'); }); -require __DIR__.'/socialstream.php'; \ No newline at end of file +require __DIR__.'/socialstream.php';require __DIR__.'/socialstream.php'; \ No newline at end of file