diff --git a/app/Helpers/ConfigHelper.php b/app/Helpers/ConfigHelper.php index c1579b4..168b7a2 100644 --- a/app/Helpers/ConfigHelper.php +++ b/app/Helpers/ConfigHelper.php @@ -104,6 +104,10 @@ class ConfigHelper 'date_format' => $this->allowedDateFormats()[0], 'default_album_view' => $this->allowedAlbumViews()[0], 'enable_visitor_hits' => false, + 'facebook_app_id' => '', + 'facebook_app_secret' => '', + 'google_app_id' => '', + 'google_app_secret' => '', 'hotlink_protection' => false, 'items_per_page' => 12, 'items_per_page_admin' => 10, @@ -120,8 +124,13 @@ class ConfigHelper 'smtp_password' => '', 'smtp_port' => 25, 'smtp_username' => '', + 'social_facebook_login' => false, + 'social_google_login' => false, + 'social_twitter_login' => false, 'social_user_profiles' => false, - 'theme' => 'default' + 'theme' => 'default', + 'twitter_app_id' => '', + 'twitter_app_secret' => '', ); } @@ -168,4 +177,10 @@ class ConfigHelper return $config; } + + public function isSocialMediaLoginEnabled() + { + return $this->get('social_facebook_login') || + $this->get('social_twitter_login'); + } } \ No newline at end of file diff --git a/app/Http/Controllers/Admin/DefaultController.php b/app/Http/Controllers/Admin/DefaultController.php index 815de1b..ad75047 100644 --- a/app/Http/Controllers/Admin/DefaultController.php +++ b/app/Http/Controllers/Admin/DefaultController.php @@ -29,10 +29,19 @@ use Illuminate\Support\Facades\View; class DefaultController extends Controller { + private $passwordSettingKeys; + public function __construct() { $this->middleware('auth'); View::share('is_admin', true); + + $this->passwordSettingKeys = [ + 'smtp_password', + 'facebook_app_secret', + 'google_app_secret', + 'twitter_app_secret' + ]; } public function about() @@ -211,9 +220,6 @@ class DefaultController extends Controller { $this->authorizeAccessToAdminPanel('admin:configure'); - $passwordKeys = [ - 'smtp_password' - ]; $checkboxKeys = [ 'albums_menu_parents_only', 'allow_self_registration', @@ -224,12 +230,19 @@ class DefaultController extends Controller 'require_email_verification', 'restrict_original_download', 'smtp_encryption', + 'social_facebook_login', + 'social_google_login', + 'social_twitter_login', 'social_user_profiles' ]; $updateKeys = [ 'albums_menu_number_items', 'app_name', 'date_format', + 'facebook_app_id', + 'facebook_app_secret', + 'google_app_id', + 'google_app_secret', 'sender_address', 'sender_name', 'smtp_server', @@ -237,6 +250,8 @@ class DefaultController extends Controller 'smtp_username', 'smtp_password', 'theme', + 'twitter_app_id', + 'twitter_app_secret', 'recaptcha_site_key', 'recaptcha_secret_key', 'analytics_code' @@ -261,7 +276,7 @@ class DefaultController extends Controller } $config->value = $request->request->get($key); - if (in_array($key, $passwordKeys) && strlen($config->value) > 0) + if (in_array($key, $this->passwordSettingKeys) && strlen($config->value) > 0) { $config->value = encrypt($config->value); } @@ -310,6 +325,14 @@ class DefaultController extends Controller $dateFormatsLookup[$dateFormat] = date($dateFormat); } + foreach ($this->passwordSettingKeys as $passwordSettingKey) + { + if (isset($config[$passwordSettingKey]) && !empty($config[$passwordSettingKey])) + { + $config[$passwordSettingKey] = decrypt($config[$passwordSettingKey]); + } + } + $themeNamesLookup = UserConfig::allowedThemeNames(); return Theme::render('admin.settings', [ diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 30fdda1..53009e4 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -3,9 +3,16 @@ namespace App\Http\Controllers\Auth; use App\Facade\Theme; +use App\Facade\UserConfig; use App\Http\Controllers\Controller; +use App\User; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; +use Laravel\Socialite\One\TwitterProvider; +use Laravel\Socialite\Two\FacebookProvider; +use Laravel\Socialite\Two\GoogleProvider; +use League\OAuth1\Client\Server\Twitter as TwitterServer; +use Socialite; class LoginController extends Controller { @@ -39,6 +46,31 @@ class LoginController extends Controller $this->middleware('guest', ['except' => 'logout']); } + protected function attemptLogin(Request $request) + { + $isSuccessful = $this->guard()->attempt($this->credentials($request)); + + if ($isSuccessful) + { + /** @var User $user */ + $user = $this->guard()->user(); + + // Update the social media ID if successful login and it was referred by the SSO provider + $loginData = $request->getSession()->get('ssoLoginData'); + if (!is_null($loginData)) + { + unset($loginData['name']); + unset($loginData['email']); + $user->fill($loginData); + $user->save(); + + $request->getSession()->remove('ssoLoginData'); + } + } + + return $isSuccessful; + } + protected function credentials(Request $request) { $result = $request->only($this->username(), 'password'); @@ -58,7 +90,187 @@ class LoginController extends Controller { return Theme::render('auth.v2_unified', [ 'active_tab' => 'login', - 'info' => $request->session()->get('info') + 'info' => $request->session()->get('info'), + 'is_sso' => false ]); } + + /** + * Show the application's login form (for a social media-linked account). + * + * @return \Illuminate\Http\Response + */ + public function showLoginFormSso(Request $request) + { + // Social media login info + $loginData = $request->getSession()->get('ssoLoginData'); + if (is_null($loginData)) + { + // No SSO data in session, use the normal login screen + return redirect(route('login')); + } + + return Theme::render('auth.v2_unified', [ + 'active_tab' => 'login', + 'info' => $request->session()->get('info'), + 'is_sso' => true, + 'login_data' => $loginData + ]); + } + + /** + * Redirect the user to the Facebook authentication page. + * + * @return \Illuminate\Http\Response + */ + public function redirectToFacebook() + { + $socialite = $this->setSocialiteConfigs(); + return $socialite->driver('facebook')->redirect(); + } + + /** + * Redirect the user to the Google authentication page. + * + * @return \Illuminate\Http\Response + */ + public function redirectToGoogle() + { + $socialite = $this->setSocialiteConfigs(); + return $socialite->driver('google')->redirect(); + } + + /** + * Redirect the user to the Twitter authentication page. + * + * @return \Illuminate\Http\Response + */ + public function redirectToTwitter() + { + $socialite = $this->setSocialiteConfigs(); + return $socialite->driver('twitter')->redirect(); + } + + /** + * Obtain the user information from Facebook. + * + * @return \Illuminate\Http\Response + */ + public function handleFacebookCallback(Request $request) + { + $socialite = $this->setSocialiteConfigs(); + $facebookUser = $socialite->driver('facebook')->user(); + + return $this->processSocialMediaLogin($request, 'facebook_id', $facebookUser); + } + + /** + * Obtain the user information from Google. + * + * @return \Illuminate\Http\Response + */ + public function handleGoogleCallback(Request $request) + { + $socialite = $this->setSocialiteConfigs(); + $googleUser = $socialite->driver('google')->user(); + + return $this->processSocialMediaLogin($request, 'google_id', $googleUser); + } + + /** + * Obtain the user information from Twitter. + * + * @return \Illuminate\Http\Response + */ + public function handleTwitterCallback(Request $request) + { + $socialite = $this->setSocialiteConfigs(); + $twitterUser = $socialite->driver('twitter')->user(); + + return $this->processSocialMediaLogin($request, 'twitter_id', $twitterUser); + } + + private function processSocialMediaLogin(Request $request, $socialMediaIdField, $socialMediaUser) + { + $userBySocialMediaId = User::where($socialMediaIdField, $socialMediaUser->getId())->first(); + + if (!is_null($userBySocialMediaId)) + { + // We have an existing user for this Facebook ID - log them in + $this->guard()->login($userBySocialMediaId); + return redirect(route('home')); + } + + // Some providers (*cough*Twitter*cough*) don't give e-mail addresses without explicit permission/additional + // verification + if (!is_null($socialMediaUser->email)) + { + $userByEmailAddress = User::where('email', $socialMediaUser->getEmail())->first(); + + if (!is_null($userByEmailAddress)) + { + // We have an existing user with the e-mail address associated with the Facebook account + // Prompt for the password for that account + $request->getSession()->put('ssoLoginData', [ + 'name' => $socialMediaUser->getName(), + 'email' => $socialMediaUser->getEmail(), + $socialMediaIdField => $socialMediaUser->getId(), + 'is_activated' => true + ]); + + return redirect(route('auth.login_sso')); + } + } + + // We don't have an existing user - prompt for registration + $request->getSession()->put('ssoRegisterData', [ + 'name' => $socialMediaUser->getName(), + 'email' => $socialMediaUser->getEmail(), + $socialMediaIdField => $socialMediaUser->getId(), + 'is_activated' => true + ]); + + return redirect(route('auth.register_sso')); + } + + private function setSocialiteConfigs() + { + // Force Socialite to use our config from the database instead of hard-coded in config/services.php + $socialite = app()->make(\Laravel\Socialite\Contracts\Factory::class); + $socialite->extend( + 'facebook', + function ($app) use ($socialite) { + $config = [ + 'client_id' => trim(UserConfig::get('facebook_app_id')), + 'client_secret' => trim(decrypt(UserConfig::get('facebook_app_secret'))), + 'redirect' => route('login_callback.facebook') + ]; + return $socialite->buildProvider(FacebookProvider::class, $config); + } + ); + $socialite->extend( + 'google', + function ($app) use ($socialite) { + $config = [ + 'client_id' => trim(UserConfig::get('google_app_id')), + 'client_secret' => trim(decrypt(UserConfig::get('google_app_secret'))), + 'redirect' => route('login_callback.google') + ]; + return $socialite->buildProvider(GoogleProvider::class, $config); + } + ); + $socialite->extend( + 'twitter', + function ($app) use ($socialite) { + $config = [ + 'identifier' => trim(UserConfig::get('twitter_app_id')), + 'secret' => trim(decrypt(UserConfig::get('twitter_app_secret'))), + 'callback_uri' => route('login_callback.twitter') + ]; + return new TwitterProvider($app['request'], new TwitterServer($config)); + } + ); + + return $socialite; + } } diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 7dd3d60..1155fa7 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -85,25 +85,22 @@ class RegisterController extends Controller */ protected function create(array $data) { - $activationData = [ - 'is_activated' => true - ]; - - if (UserConfig::get('require_email_verification')) + if (!isset($data['is_activated'])) { - $activationData['is_activated'] = false; - $activationData['activation_token'] = MiscHelper::randomString(); + $data['is_activated'] = true; + + if (UserConfig::get('require_email_verification')) + { + $data['is_activated'] = false; + $data['activation_token'] = MiscHelper::randomString(); + } } - return User::create(array_merge( - [ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => bcrypt($data['password']), - 'is_admin' => false - ], - $activationData - )); + $data['password'] = bcrypt($data['password']); + $data['is_admin'] = false; + unset($data['password_confirmation']); + + return User::create($data); } public function register(Request $request) @@ -115,8 +112,18 @@ class RegisterController extends Controller $this->validator($request)->validate(); + $userData = $request->all(); + + // Social media login info + $registerData = $request->getSession()->get('ssoRegisterData'); + if (!is_null($registerData)) + { + $userData = array_merge($registerData, $userData); + $request->getSession()->remove('ssoRegisterData'); + } + /** @var User $user */ - $user = $this->create($request->all()); + $user = $this->create($userData); if ($user->is_activated) { @@ -137,7 +144,7 @@ class RegisterController extends Controller * * @return \Illuminate\Http\Response */ - public function showRegistrationForm() + public function showRegistrationForm(Request $request) { if (!UserConfig::get('allow_self_registration')) { @@ -145,7 +152,35 @@ class RegisterController extends Controller } return Theme::render('auth.v2_unified', [ - 'active_tab' => 'register' + 'active_tab' => 'register', + 'is_sso' => false + ]); + } + + /** + * Show the application registration form (for a social media-linked account). + * + * @return \Illuminate\Http\Response + */ + public function showRegistrationFormSso(Request $request) + { + if (!UserConfig::get('allow_self_registration')) + { + return redirect(route('home')); + } + + // Social media login info + $registerData = $request->getSession()->get('ssoRegisterData'); + if (is_null($registerData)) + { + // No SSO data in session, use the normal registration screen + return redirect(route('register')); + } + + return Theme::render('auth.v2_unified', [ + 'active_tab' => 'register', + 'is_sso' => true, + 'register_data' => $registerData ]); } } diff --git a/app/User.php b/app/User.php index 6cf4a92..0e7f501 100644 --- a/app/User.php +++ b/app/User.php @@ -16,7 +16,7 @@ class User extends Authenticatable * @var array */ protected $fillable = [ - 'name', 'email', 'password', 'is_admin', 'is_activated', 'activation_token', 'profile_alias' + 'name', 'email', 'password', 'is_admin', 'is_activated', 'activation_token', 'enable_profile_page', 'profile_alias', 'facebook_id', 'twitter_id', 'google_id' ]; /** diff --git a/composer.json b/composer.json index c594bea..32bb1db 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "laravel/framework": "5.5.*", "rackspace/php-opencloud": "^1.16", "doctrine/dbal": "^2.5", - "aws/aws-sdk-php": "^3.19" + "aws/aws-sdk-php": "^3.19", + "laravel/socialite": "^3.0" }, "require-dev": { "filp/whoops": "~2.0", diff --git a/composer.lock b/composer.lock index ca1bee2..4497bb3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2469338aa47d9194dc0c44bc788fb070", + "content-hash": "7e1113109ae57d549a01afba28bdb219", "packages": [ { "name": "aws/aws-sdk-php", @@ -948,6 +948,68 @@ ], "time": "2018-03-30T13:29:30+00:00" }, + { + "name": "laravel/socialite", + "version": "v3.0.12", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f", + "reference": "b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~6.0", + "illuminate/contracts": "~5.4", + "illuminate/http": "~5.4", + "illuminate/support": "~5.4", + "league/oauth1-client": "~1.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0|~5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ], + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "keywords": [ + "laravel", + "oauth" + ], + "time": "2018-06-01T15:06:47+00:00" + }, { "name": "league/flysystem", "version": "1.0.45", @@ -1032,6 +1094,69 @@ ], "time": "2018-05-07T08:44:23+00:00" }, + { + "name": "league/oauth1-client", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/fca5f160650cb74d23fc11aa570dd61f86dcf647", + "reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "php": ">=5.5.0" + }, + "require-dev": { + "mockery/mockery": "^0.9", + "phpunit/phpunit": "^4.0", + "squizlabs/php_codesniffer": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "time": "2016-08-17T00:36:58+00:00" + }, { "name": "mikemccabe/json-patch-php", "version": "0.1.0", diff --git a/database/migrations/2018_08_13_211541_add_user_facebook_id_column.php b/database/migrations/2018_08_13_211541_add_user_facebook_id_column.php new file mode 100644 index 0000000..685d15f --- /dev/null +++ b/database/migrations/2018_08_13_211541_add_user_facebook_id_column.php @@ -0,0 +1,34 @@ +string('facebook_id')->nullable(true); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) + { + $table->dropColumn('facebook_id'); + }); + } +} diff --git a/database/migrations/2018_08_16_132300_add_user_twitter_id_column.php b/database/migrations/2018_08_16_132300_add_user_twitter_id_column.php new file mode 100644 index 0000000..092d8df --- /dev/null +++ b/database/migrations/2018_08_16_132300_add_user_twitter_id_column.php @@ -0,0 +1,34 @@ +string('twitter_id')->nullable(true); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) + { + $table->dropColumn('twitter_id'); + }); + } +} diff --git a/database/migrations/2018_08_17_133429_add_user_google_id_column.php b/database/migrations/2018_08_17_133429_add_user_google_id_column.php new file mode 100644 index 0000000..9d80321 --- /dev/null +++ b/database/migrations/2018_08_17_133429_add_user_google_id_column.php @@ -0,0 +1,34 @@ +string('google_id')->nullable(true); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) + { + $table->dropColumn('google_id'); + }); + } +} diff --git a/resources/lang/en/admin.php b/resources/lang/en/admin.php index 18bc923..9358efc 100644 --- a/resources/lang/en/admin.php +++ b/resources/lang/en/admin.php @@ -211,7 +211,10 @@ return [ 'analytics_tab' => 'Analytics', 'security_allow_self_registration' => 'Allow self-registration', 'security_allow_self_registration_description' => 'With this option enabled, users can sign up for their own accounts. You can grant permissions to accounts to allow users to upload their own photos or manage yours.', - 'social_tab' => 'Social' + 'social_facebook' => 'Facebook', + 'social_google' => 'Google', + 'social_tab' => 'Social', + 'social_twitter' => 'Twitter' ], 'select_all_action' => 'Select all', 'select_all_album_active' => 'Any action you select in the list below will apply to all photos in this album.', diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php index 5a61ca2..545f1b6 100644 --- a/resources/lang/en/auth.php +++ b/resources/lang/en/auth.php @@ -22,6 +22,11 @@ return [ 'Please click the link in this e-mail to activate your account.', 'change_password_action' => 'Change password', 'change_password_title' => 'Change your password', + 'email_password_login' => 'Alternatively, login with your e-mail address and password:', + 'email_password_login_sso' => 'The social media account you logged in with has not been used here before, however an account with the e-mail address already exists.', + 'email_password_login_sso_2' => 'Please enter the password for this account to link your social media account to it.', + 'email_password_register' => 'Alternatively, create an account using your e-mail address and a password:', + 'email_password_register_sso' => 'Please confirm your name and set a password for your account:', 'forgot_password_action' => 'Send Reset E-mail', 'forgot_password_link' => 'Forgotten your password?', 'forgot_password_title' => 'Send password reset link', @@ -29,5 +34,7 @@ return [ 'recaptcha_failed_message' => 'The reCAPTCHA verfication failed. Please ensure you have completed the reCAPTCHA challenge and try again.', 'register_page_title' => 'Create an account', 'reset_password_action' => 'Reset Password', - 'reset_password_title' => 'Reset your password' + 'reset_password_title' => 'Reset your password', + 'social_login' => 'Feeling sociable? Login with:', + 'social_register' => 'Feeling sociable? Register with:' ]; diff --git a/resources/lang/en/forms.php b/resources/lang/en/forms.php index eaabb28..0473b7f 100644 --- a/resources/lang/en/forms.php +++ b/resources/lang/en/forms.php @@ -45,6 +45,18 @@ return [ 'settings_hotlink_protection_help' => 'With this option enabled, direct linking to images is not allowed. Photos can only be viewed through Blue Twilight.', 'settings_restrict_originals_download' => 'Restrict access to original images', 'settings_restrict_originals_download_help' => 'With this option enabled, only the photo\'s owner can download the original high-resolution images.', + 'settings_social_facebook_app_id' => 'Facebook App ID:', + 'settings_social_facebook_app_secret' => 'Facebook App Secret:', + 'settings_social_facebook_login' => 'Allow login/registration with a Facebook account.', + 'settings_social_facebook_login_help' => 'With this option enabled, users can register (if enabled) and login with their Facebook account.', + 'settings_social_google_app_id' => 'Google App ID:', + 'settings_social_google_app_secret' => 'Google App Secret:', + 'settings_social_google_login' => 'Allow login/registration with a Google account.', + 'settings_social_google_login_help' => 'With this option enabled, users can register (if enabled) and login with their Google account.', + 'settings_social_twitter_app_id' => 'Twitter App ID:', + 'settings_social_twitter_app_secret' => 'Twitter App Secret:', + 'settings_social_twitter_login' => 'Allow login/registration with a Twitter account', + 'settings_social_twitter_login_help' => 'With this option enabled, users can register (if enabled) and login with their Twitter account.', 'settings_social_user_profiles' => 'Enable public user profiles', 'settings_social_user_profiles_help' => 'Display public pages for users showing their albums, cameras used and activity.', 'storage_access_key_label' => 'Access key:', diff --git a/resources/views/themes/base/admin/settings.blade.php b/resources/views/themes/base/admin/settings.blade.php index faab460..89deec9 100644 --- a/resources/views/themes/base/admin/settings.blade.php +++ b/resources/views/themes/base/admin/settings.blade.php @@ -324,6 +324,145 @@ @lang('forms.settings_social_user_profiles_help') + +
+ + {{-- Facebook --}} +
+
+ +
+ +
+
+ + @lang('admin.settings.social_facebook') + + +
+ + +
+ +
+ + + + @if ($errors->has('facebook_app_id')) +
+ {{ $errors->first('facebook_app_id') }} +
+ @endif +
+ +
+ + + + @if ($errors->has('facebook_app_secret')) +
+ {{ $errors->first('facebook_app_secret') }} +
+ @endif +
+
+
+
+ +
+ + {{-- Twitter --}} +
+
+ +
+ +
+
+ + @lang('admin.settings.social_twitter') + + +
+ + +
+ +
+ + + + @if ($errors->has('twitter_app_id')) +
+ {{ $errors->first('twitter_app_id') }} +
+ @endif +
+ +
+ + + + @if ($errors->has('twitter_app_secret')) +
+ {{ $errors->first('twitter_app_secret') }} +
+ @endif +
+
+
+
+ + {{-- Google+ --}} +
+
+ +
+ +
+
+ + @lang('admin.settings.social_google') + + +
+ + +
+ +
+ + + + @if ($errors->has('google_app_id')) +
+ {{ $errors->first('google_app_id') }} +
+ @endif +
+ +
+ + + + @if ($errors->has('google_app_secret')) +
+ {{ $errors->first('google_app_secret') }} +
+ @endif +
+
+
+
diff --git a/resources/views/themes/base/auth/v2_unified.blade.php b/resources/views/themes/base/auth/v2_unified.blade.php index f1d7f24..200d7f3 100644 --- a/resources/views/themes/base/auth/v2_unified.blade.php +++ b/resources/views/themes/base/auth/v2_unified.blade.php @@ -8,13 +8,25 @@
diff --git a/resources/views/themes/base/partials/login.blade.php b/resources/views/themes/base/partials/login.blade.php index bc7c194..542302d 100644 --- a/resources/views/themes/base/partials/login.blade.php +++ b/resources/views/themes/base/partials/login.blade.php @@ -1,3 +1,15 @@ +@if (!$is_sso) + @if (UserConfig::isSocialMediaLoginEnabled()) +

@lang('auth.social_login')

+ @include(Theme::viewName('partials.social_login_providers')) + @endif + +

@lang('auth.email_password_login')

+@else +

@lang('auth.email_password_login_sso')

+

@lang('auth.email_password_login_sso_2')

+@endif +
{{ csrf_field() }} @@ -5,7 +17,12 @@
- + @if ($is_sso) + + + @else + + @endif @if ($errors->has('email'))
@@ -19,7 +36,7 @@
- + @if ($errors->has('password'))
@@ -29,16 +46,18 @@
-
-
-
-
- - + @if (!$is_sso) +
+
+
+
+ + +
-
+ @endif
diff --git a/resources/views/themes/base/partials/register.blade.php b/resources/views/themes/base/partials/register.blade.php index a2198f4..8e7157e 100644 --- a/resources/views/themes/base/partials/register.blade.php +++ b/resources/views/themes/base/partials/register.blade.php @@ -1,3 +1,14 @@ +@if (!$is_sso) + @if (UserConfig::isSocialMediaLoginEnabled()) +

@lang('auth.social_register')

+ @include(Theme::viewName('partials.social_login_providers')) + @endif + +

@lang('auth.email_password_register')

+@else +

@lang('auth.email_password_register_sso')

+@endif + {{ csrf_field() }} @@ -5,7 +16,7 @@
- + @if ($errors->has('name'))
@@ -19,7 +30,12 @@
- + @if ($is_sso && !empty($register_data['email'])) + + + @else + + @endif @if ($errors->has('email'))
@@ -33,7 +49,7 @@
- + @if ($errors->has('password'))
diff --git a/resources/views/themes/base/partials/social_login_providers.blade.php b/resources/views/themes/base/partials/social_login_providers.blade.php new file mode 100644 index 0000000..13b9377 --- /dev/null +++ b/resources/views/themes/base/partials/social_login_providers.blade.php @@ -0,0 +1,11 @@ +

+ @if (UserConfig::get('social_facebook_login')) + + @endif + @if (UserConfig::get('social_twitter_login')) + + @endif + @if (UserConfig::get('social_google_login')) + + @endif +

\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index f0357fe..4fd0430 100644 --- a/routes/web.php +++ b/routes/web.php @@ -74,6 +74,16 @@ Route::group(['prefix' => 'install'], function () { Route::post('/database', 'InstallController@database')->name('install.database'); }); +// Social media SSO +Route::get('login/facebook', 'Auth\LoginController@redirectToFacebook')->name('login.facebook'); +Route::get('login/facebook/callback', 'Auth\LoginController@handleFacebookCallback')->name('login_callback.facebook'); +Route::get('login/google', 'Auth\LoginController@redirectToGoogle')->name('login.google'); +Route::get('login/google/callback', 'Auth\LoginController@handleGoogleCallback')->name('login_callback.google'); +Route::get('login/sso', 'Auth\LoginController@showLoginFormSso')->name('auth.login_sso'); +Route::get('login/twitter', 'Auth\LoginController@redirectToTwitter')->name('login.twitter'); +Route::get('login/twitter/callback', 'Auth\LoginController@handleTwitterCallback')->name('login_callback.twitter'); +Route::get('register/sso', 'Auth\RegisterController@showRegistrationFormSso')->name('auth.register_sso'); + // Gallery Route::get('/', 'Gallery\DefaultController@index')->name('home'); Route::get('/activate/{token}', 'Auth\ActivateController@activate')->name('auth.activate');