diff --git a/app/Http/Controllers/LoginController.php b/app/Http/Controllers/LoginController.php new file mode 100644 index 0000000..c1d4143 --- /dev/null +++ b/app/Http/Controllers/LoginController.php @@ -0,0 +1,73 @@ +where('server', env('MASTODON_DOMAIN'))->first(); + + if ($app == null) + { + # Register this app with the API server. + $app_info = Mastodon::domain(env('MASTODON_DOMAIN')) + ->createApp(env('APP_NAME'), env('MASTODON_REDIRECT'), config('services.mastodon.scopes'), env('APP_URL')); + + $client_id = $app_info['client_id']; + $client_secret = $app_info['client_secret']; + + DB::table('apps')->insert([ + 'server' => env('MASTODON_DOMAIN'), + 'client_name' => env('APP_NAME'), + 'redirect_uris' => env('MASTODON_REDIRECT'), + 'scopes' => join(' ', config('services.mastodon.scopes')), + 'website' => env('APP_URL'), + 'response_id' => $app_info['id'], + 'client_id' => $client_id, + 'client_secret' => $client_secret + ]); + } + else + { + $client_id = $app->client_id; + $client_secret = $app->client_secret; + } + + # Set configs required for the redirect. + config(['services.mastodon.domain' => env('MASTODON_DOMAIN')]); + config(['services.mastodon.client_id' => $client_id]); + config(['services.mastodon.client_secret' => $client_secret]); + + # Save this info to the session. + session(['mastodon_domain' => env('MASTODON_DOMAIN')]); + session(['client_id' => $client_id]); + session(['client_secret' => $client_secret]); + + # Redirect the user to their instance to log in. + return Socialite::driver('mastodon')->redirect(); + } + + public function callback() + { + $domain = session('mastodon_domain'); + $client_id = session('client_id'); + $client_secret = session('client_secret'); + + config(['services.mastodon.domain' => $domain]); + config(['services.mastodon.client_id' => $client_id]); + config(['services.mastodon.client_secret' => $client_secret]); + + # Get user data (token, etc.) + $user = Socialite::driver('mastodon')->user(); + session(['user' => $user]); + + return redirect()->route('friends'); + } +} diff --git a/app/Http/Controllers/TimelineController.php b/app/Http/Controllers/TimelineController.php index 5c354fc..12e513d 100644 --- a/app/Http/Controllers/TimelineController.php +++ b/app/Http/Controllers/TimelineController.php @@ -7,21 +7,41 @@ use Mastodon; class TimelineController extends Controller { - public function show_timeline() + public function public_timeline() { - $public_timeline = Mastodon::domain(env('MASTODON_API')) + $timeline = Mastodon::domain(env('MASTODON_DOMAIN')) ->get('/timelines/public', ['local' => true]); - # Embed images. - foreach ($public_timeline as $index => $status) + $timeline = $this->embed_images($timeline); + + return view('timeline', ['statuses' => $timeline]); + } + + public function home_timeline() + { + $user = session('user'); + $timeline = Mastodon::domain(env('MASTODON_DOMAIN')) + ->token($user->token) + ->get('/timelines/home'); + + $timeline = $this->embed_images($timeline); + + return view('timeline', ['statuses' => $timeline]); + } + + private function embed_images($timeline) + { + foreach ($timeline as $index => $status) { - $public_timeline[$index]['content'] = preg_replace( + # Search for links to images and replace the inner HTML + # with an img tag of the image itself. + $timeline[$index]['content'] = preg_replace( '/([^<]+)<\/a>/', '${3}', $status['content'] ); } - return view('timeline', ['statuses' => $public_timeline]); + return $timeline; } } diff --git a/composer.json b/composer.json index 0f4c590..49fa722 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "fideloper/proxy": "~3.3", "laravel/framework": "5.5.*", "laravel/tinker": "~1.0", - "revolution/laravel-mastodon-api": "^1.5" + "revolution/laravel-mastodon-api": "^1.5", + "revolution/socialite-mastodon": "^1.2" }, "require-dev": { "filp/whoops": "~2.0", diff --git a/composer.lock b/composer.lock index 69344e2..45772d6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "92f25db138dc11525945a2c977eff7a9", - "content-hash": "fe6ad9502bf61c169c783babe3aac2e8", + "hash": "777e302fe64df7b4f6c3d53b0d67ca01", + "content-hash": "99e2b15adf8ee6829bad59f44cae2cef", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -723,6 +723,68 @@ ], "time": "2018-08-08 18:22:44" }, + { + "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-01 15:06:47" + }, { "name": "laravel/tinker", "version": "v1.0.7", @@ -870,6 +932,69 @@ ], "time": "2018-05-07 08:44:23" }, + { + "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-17 00:36:58" + }, { "name": "monolog/monolog", "version": "1.23.0", @@ -1550,6 +1675,59 @@ ], "time": "2018-05-17 06:29:25" }, + { + "name": "revolution/socialite-mastodon", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/kawax/socialite-mastodon.git", + "reference": "2c5f26cee466fabf5797de46f8a55b5537abfe17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kawax/socialite-mastodon/zipball/2c5f26cee466fabf5797de46f8a55b5537abfe17", + "reference": "2c5f26cee466fabf5797de46f8a55b5537abfe17", + "shasum": "" + }, + "require": { + "laravel/socialite": "*", + "php": ">=7.0.0." + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Revolution\\Socialite\\Mastodon\\MastodonServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Revolution\\Socialite\\Mastodon\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "kawax", + "email": "kawaxbiz@gmail.com" + } + ], + "description": "Socialite for Mastodon", + "keywords": [ + "laravel", + "mastodon", + "socialite" + ], + "time": "2018-05-10 03:45:17" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.1.2", diff --git a/config/services.php b/config/services.php index 4460f0e..6fcfe4c 100644 --- a/config/services.php +++ b/config/services.php @@ -35,4 +35,12 @@ return [ 'secret' => env('STRIPE_SECRET'), ], + 'mastodon' => [ + 'domain' => env('MASTODON_DOMAIN'), + 'client_id' => env('MASTODON_ID'), + 'client_secret' => env('MASTODON_SECRET'), + 'redirect' => env('MASTODON_REDIRECT'), + //'read', 'write', 'follow' + 'scope' => ['read', 'write', 'follow'], + ], ]; diff --git a/config/session.php b/config/session.php index 736fb3c..094f093 100644 --- a/config/session.php +++ b/config/session.php @@ -44,7 +44,7 @@ return [ | */ - 'encrypt' => false, + 'encrypt' => true, /* |-------------------------------------------------------------------------- diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php deleted file mode 100644 index 689cbee..0000000 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ /dev/null @@ -1,35 +0,0 @@ -increments('id'); - $table->string('name'); - $table->string('email')->unique(); - $table->string('password'); - $table->rememberToken(); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('users'); - } -} diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php deleted file mode 100644 index 0d5cb84..0000000 --- a/database/migrations/2014_10_12_100000_create_password_resets_table.php +++ /dev/null @@ -1,32 +0,0 @@ -string('email')->index(); - $table->string('token'); - $table->timestamp('created_at')->nullable(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('password_resets'); - } -} diff --git a/database/migrations/2018_08_11_175433_create_apps_table.php b/database/migrations/2018_08_11_175433_create_apps_table.php new file mode 100644 index 0000000..57ee69d --- /dev/null +++ b/database/migrations/2018_08_11_175433_create_apps_table.php @@ -0,0 +1,38 @@ +increments('id'); + $table->char('server'); + $table->char('client_name'); + $table->char('redirect_uris'); + $table->char('scopes'); + $table->char('website'); + $table->char('response_id'); + $table->char('client_id'); + $table->char('client_secret'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('apps'); + } +} diff --git a/routes/web.php b/routes/web.php index 0028f2c..fd3c6d8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,4 +11,16 @@ | */ -Route::get('/', 'TimelineController@show_timeline'); +Route::get('/', function() { + return redirect()->route('public'); +}); + +Route::get('/timeline/public', 'TimelineController@public_timeline') + ->name('public'); + +Route::get('/timeline/friends', 'TimelineController@home_timeline') + ->name('friends'); + +Route::get('/login', 'LoginController@login'); + +Route::get('/callback', 'LoginController@callback');