pixelfed/app/Http/Controllers/RemoteAuthController.php

700 wiersze
23 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\RemoteAuth;
2024-03-12 07:03:33 +00:00
use App\Services\Account\RemoteAuthService;
use App\Services\EmailService;
use App\Services\MediaStorageService;
2024-03-12 07:03:33 +00:00
use App\User;
use App\Util\ActivityPub\Helpers;
2024-03-12 07:03:33 +00:00
use App\Util\Lexer\RestrictedNames;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
Staging (#5978) * Added current title as value for input so that the current value remains stored by default * Added parameter 'show_legal_notice_link' => (bool) config_cache('instance.has_legal_notice'), * Added conditional display of a link to legal notice if the page is active * Added key 'legalNotice' * feat translate story * translate auth - register - login * add remove follow * Update ApiV1Controller.php Co-Authored-By: Mathieu <385764+Casmo@users.noreply.github.com> * New translations web.php (Chinese Simplified) [ci skip] * Added current title as value for input so that the current value remains stored by default * Added parameter 'show_legal_notice_link' => (bool) config_cache('instance.has_legal_notice'), * Added conditional display of a link to legal notice if the page is active * Added key 'legalNotice' * add missing key * add missing keys * New translations web.php (Portuguese, Brazilian) [ci skip] * New translations web.php (Turkish) [ci skip] * New translations web.php (Italian) [ci skip] * translate custom filter * New translations web.php (Italian) [ci skip] * use configured alt text length limit when uploading multiple photos * in notifications sidebar, show popover on shared posts too, not just liked posts * use case insensitive search when tagging accounts * New translations web.php (Portuguese, Brazilian) [ci skip] * Generic OIDC Support * Everything should be configurable by env variables * Basic request tests * Fixes for items highlighted by review.ai * Consider using `hash_equals()` instead of `==` when comparing the state values to prevent timing attacks: `abort_unless(hash_equals($request->input('state'), $request->session()->pull('oauth2state')), 400, 'invalid state');` * For better data integrity, consider adding a foreign key constraint to the user_id column: `$table- >foreign('user_id')->references('id')->on('users')->onDelete('cascade');` * Does the OIDC provider guarantee that the username field exists in the userInfo data? Consider adding a null check or fallback: `$userInfoData[config('remote-auth.oidc.field_username')] ?? null` * field isnt accessTokenResourceOwnerId but responseResourceOwnerId * New translations web.php (Dutch) [ci skip] * Fix components * Update LandingService and Config util to properly support the legal_notice setting * Update footer to use legalNotice i18n * Update i18n * Update sidebar with gap padding for footer links * Update compiled assets * Update i18n json * Update OIDC config with comments, and disable tests as we dont have db tests configured * Update remove_from_followers api endpoint * Update i18n * Update compiled assets * Update changelog * New supported formats, Preserve ICC Color Profiles, libvips support Update image pipeline to handle avif, heic and webp and preserve ICC color profiles and added libvips support. * Fix tests * Update CHANGELOG.md --------- Co-authored-by: Samy Elshamy <elshamy@coderbutze.de> Co-authored-by: Felipe Mateus <eu@felipemateus.com> Co-authored-by: Mathieu <385764+Casmo@users.noreply.github.com> Co-authored-by: Mackenzie Morgan <macoafi@gmail.com> Co-authored-by: Gavin Mogan <git@gavinmogan.com>
2025-05-13 08:25:23 +00:00
use App\Rules\PixelfedUsername;
use InvalidArgumentException;
2024-03-12 07:03:33 +00:00
use Purify;
class RemoteAuthController extends Controller
{
public function start(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
2024-03-12 07:03:33 +00:00
if ($request->user()) {
return redirect('/');
}
2024-03-12 07:03:33 +00:00
return view('auth.remote.start');
}
public function startRedirect(Request $request)
{
return redirect('/login');
}
public function getAuthDomains(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
2024-03-12 07:03:33 +00:00
if (config('remote-auth.mastodon.domains.only_custom')) {
$res = config('remote-auth.mastodon.domains.custom');
2024-03-12 07:03:33 +00:00
if (! $res || ! strlen($res)) {
return [];
}
$res = explode(',', $res);
2024-03-12 07:03:33 +00:00
return response()->json($res);
}
2024-03-12 07:03:33 +00:00
if (config('remote-auth.mastodon.domains.custom') &&
! config('remote-auth.mastodon.domains.only_default') &&
strlen(config('remote-auth.mastodon.domains.custom')) > 3 &&
strpos(config('remote-auth.mastodon.domains.custom'), '.') > -1
) {
$res = config('remote-auth.mastodon.domains.custom');
2024-03-12 07:03:33 +00:00
if (! $res || ! strlen($res)) {
return [];
}
$res = explode(',', $res);
2024-03-12 07:03:33 +00:00
return response()->json($res);
}
$res = config('remote-auth.mastodon.domains.default');
$res = explode(',', $res);
return response()->json($res);
}
public function redirect(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
$this->validate($request, ['domain' => 'required']);
$domain = $request->input('domain');
2024-03-12 07:03:33 +00:00
if (str_starts_with(strtolower($domain), 'http')) {
$res = [
'domain' => $domain,
'ready' => false,
2024-03-12 07:03:33 +00:00
'action' => 'incompatible_domain',
];
2024-03-12 07:03:33 +00:00
return response()->json($res);
}
2024-03-12 07:03:33 +00:00
$validateInstance = Helpers::validateUrl('https://'.$domain.'/?block-check='.time());
2024-03-12 07:03:33 +00:00
if (! $validateInstance) {
$res = [
'domain' => $domain,
'ready' => false,
2024-03-12 07:03:33 +00:00
'action' => 'blocked_domain',
];
2024-03-12 07:03:33 +00:00
return response()->json($res);
}
$compatible = RemoteAuthService::isDomainCompatible($domain);
2024-03-12 07:03:33 +00:00
if (! $compatible) {
$res = [
'domain' => $domain,
'ready' => false,
2024-03-12 07:03:33 +00:00
'action' => 'incompatible_domain',
];
2024-03-12 07:03:33 +00:00
return response()->json($res);
}
2024-03-12 07:03:33 +00:00
if (config('remote-auth.mastodon.domains.only_default')) {
$defaultDomains = explode(',', config('remote-auth.mastodon.domains.default'));
2024-03-12 07:03:33 +00:00
if (! in_array($domain, $defaultDomains)) {
$res = [
'domain' => $domain,
'ready' => false,
2024-03-12 07:03:33 +00:00
'action' => 'incompatible_domain',
];
2024-03-12 07:03:33 +00:00
return response()->json($res);
}
}
2024-03-12 07:03:33 +00:00
if (config('remote-auth.mastodon.domains.only_custom') && config('remote-auth.mastodon.domains.custom')) {
$customDomains = explode(',', config('remote-auth.mastodon.domains.custom'));
2024-03-12 07:03:33 +00:00
if (! in_array($domain, $customDomains)) {
$res = [
'domain' => $domain,
'ready' => false,
2024-03-12 07:03:33 +00:00
'action' => 'incompatible_domain',
];
2024-03-12 07:03:33 +00:00
return response()->json($res);
}
}
$client = RemoteAuthService::getMastodonClient($domain);
abort_unless($client, 422, 'Invalid mastodon client');
$request->session()->put('state', $state = Str::random(40));
$request->session()->put('oauth_domain', $domain);
$query = http_build_query([
'client_id' => $client->client_id,
'redirect_uri' => $client->redirect_uri,
'response_type' => 'code',
'scope' => 'read',
'state' => $state,
]);
2024-03-12 07:03:33 +00:00
$request->session()->put('oauth_redirect_to', 'https://'.$domain.'/oauth/authorize?'.$query);
$dsh = Str::random(17);
$res = [
'domain' => $domain,
'ready' => true,
2024-03-12 07:03:33 +00:00
'dsh' => $dsh,
];
return response()->json($res);
}
public function preflight(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
2024-03-12 07:03:33 +00:00
if (! $request->filled('d') || ! $request->filled('dsh') || ! $request->session()->exists('oauth_redirect_to')) {
return redirect('/login');
}
return redirect()->away($request->session()->pull('oauth_redirect_to'));
}
public function handleCallback(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
$domain = $request->session()->get('oauth_domain');
2024-03-12 07:03:33 +00:00
if ($request->filled('code')) {
$code = $request->input('code');
$state = $request->session()->pull('state');
throw_unless(
strlen($state) > 0 && $state === $request->state,
InvalidArgumentException::class,
'Invalid state value.'
);
$res = RemoteAuthService::getToken($domain, $code);
2024-03-12 07:03:33 +00:00
if (! $res || ! isset($res['access_token'])) {
$request->session()->regenerate();
2024-03-12 07:03:33 +00:00
return redirect('/login');
}
$request->session()->put('oauth_remote_session_token', $res['access_token']);
2024-03-12 07:03:33 +00:00
return redirect('/auth/mastodon/getting-started');
}
return redirect('/login');
}
public function onboarding(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
2024-03-12 07:03:33 +00:00
if ($request->user()) {
return redirect('/');
}
2024-03-12 07:03:33 +00:00
return view('auth.remote.onboarding');
}
public function sessionCheck(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_if($request->user(), 403);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
$domain = $request->session()->get('oauth_domain');
$token = $request->session()->get('oauth_remote_session_token');
$res = RemoteAuthService::getVerifyCredentials($domain, $token);
2024-03-12 07:03:33 +00:00
abort_if(! $res || ! isset($res['acct']), 403, 'Invalid credentials');
2024-03-12 07:03:33 +00:00
$webfinger = strtolower('@'.$res['acct'].'@'.$domain);
$request->session()->put('oauth_masto_webfinger', $webfinger);
2024-03-12 07:03:33 +00:00
if (config('remote-auth.mastodon.max_uses.enabled')) {
$limit = config('remote-auth.mastodon.max_uses.limit');
$uses = RemoteAuthService::lookupWebfingerUses($webfinger);
2024-03-12 07:03:33 +00:00
if ($uses >= $limit) {
return response()->json([
'code' => 200,
'msg' => 'Success!',
2024-03-12 07:03:33 +00:00
'action' => 'max_uses_reached',
]);
}
}
$exists = RemoteAuth::whereDomain($domain)->where('webfinger', $webfinger)->whereNotNull('user_id')->first();
2024-03-12 07:03:33 +00:00
if ($exists && $exists->user_id) {
return response()->json([
'code' => 200,
'msg' => 'Success!',
2024-03-12 07:03:33 +00:00
'action' => 'redirect_existing_user',
]);
}
return response()->json([
'code' => 200,
'msg' => 'Success!',
2024-03-12 07:03:33 +00:00
'action' => 'onboard',
]);
}
public function sessionGetMastodonData(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_if($request->user(), 403);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
$domain = $request->session()->get('oauth_domain');
$token = $request->session()->get('oauth_remote_session_token');
$res = RemoteAuthService::getVerifyCredentials($domain, $token);
2024-03-12 07:03:33 +00:00
$res['_webfinger'] = strtolower('@'.$res['acct'].'@'.$domain);
$res['_domain'] = strtolower($domain);
$request->session()->put('oauth_remasto_id', $res['id']);
$ra = RemoteAuth::updateOrCreate([
'domain' => $domain,
'webfinger' => $res['_webfinger'],
], [
'software' => 'mastodon',
'ip_address' => $request->ip(),
'bearer_token' => $token,
'verify_credentials' => $res,
'last_verify_credentials_at' => now(),
2024-03-12 07:03:33 +00:00
'last_successful_login_at' => now(),
]);
$request->session()->put('oauth_masto_raid', $ra->id);
return response()->json($res);
}
public function sessionValidateUsername(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_if($request->user(), 403);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
$this->validate($request, [
'username' => [
'required',
'min:2',
'max:30',
Staging (#5978) * Added current title as value for input so that the current value remains stored by default * Added parameter 'show_legal_notice_link' => (bool) config_cache('instance.has_legal_notice'), * Added conditional display of a link to legal notice if the page is active * Added key 'legalNotice' * feat translate story * translate auth - register - login * add remove follow * Update ApiV1Controller.php Co-Authored-By: Mathieu <385764+Casmo@users.noreply.github.com> * New translations web.php (Chinese Simplified) [ci skip] * Added current title as value for input so that the current value remains stored by default * Added parameter 'show_legal_notice_link' => (bool) config_cache('instance.has_legal_notice'), * Added conditional display of a link to legal notice if the page is active * Added key 'legalNotice' * add missing key * add missing keys * New translations web.php (Portuguese, Brazilian) [ci skip] * New translations web.php (Turkish) [ci skip] * New translations web.php (Italian) [ci skip] * translate custom filter * New translations web.php (Italian) [ci skip] * use configured alt text length limit when uploading multiple photos * in notifications sidebar, show popover on shared posts too, not just liked posts * use case insensitive search when tagging accounts * New translations web.php (Portuguese, Brazilian) [ci skip] * Generic OIDC Support * Everything should be configurable by env variables * Basic request tests * Fixes for items highlighted by review.ai * Consider using `hash_equals()` instead of `==` when comparing the state values to prevent timing attacks: `abort_unless(hash_equals($request->input('state'), $request->session()->pull('oauth2state')), 400, 'invalid state');` * For better data integrity, consider adding a foreign key constraint to the user_id column: `$table- >foreign('user_id')->references('id')->on('users')->onDelete('cascade');` * Does the OIDC provider guarantee that the username field exists in the userInfo data? Consider adding a null check or fallback: `$userInfoData[config('remote-auth.oidc.field_username')] ?? null` * field isnt accessTokenResourceOwnerId but responseResourceOwnerId * New translations web.php (Dutch) [ci skip] * Fix components * Update LandingService and Config util to properly support the legal_notice setting * Update footer to use legalNotice i18n * Update i18n * Update sidebar with gap padding for footer links * Update compiled assets * Update i18n json * Update OIDC config with comments, and disable tests as we dont have db tests configured * Update remove_from_followers api endpoint * Update i18n * Update compiled assets * Update changelog * New supported formats, Preserve ICC Color Profiles, libvips support Update image pipeline to handle avif, heic and webp and preserve ICC color profiles and added libvips support. * Fix tests * Update CHANGELOG.md --------- Co-authored-by: Samy Elshamy <elshamy@coderbutze.de> Co-authored-by: Felipe Mateus <eu@felipemateus.com> Co-authored-by: Mathieu <385764+Casmo@users.noreply.github.com> Co-authored-by: Mackenzie Morgan <macoafi@gmail.com> Co-authored-by: Gavin Mogan <git@gavinmogan.com>
2025-05-13 08:25:23 +00:00
new PixelfedUsername(),
2024-03-12 07:03:33 +00:00
],
]);
$username = strtolower($request->input('username'));
$exists = User::where('username', $username)->exists();
return response()->json([
'code' => 200,
'username' => $username,
2024-03-12 07:03:33 +00:00
'exists' => $exists,
]);
}
public function sessionValidateEmail(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_if($request->user(), 403);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
$this->validate($request, [
'email' => [
'required',
'email:strict,filter_unicode,dns,spoof',
2024-03-12 07:03:33 +00:00
],
]);
$email = $request->input('email');
$banned = EmailService::isBanned($email);
$exists = User::where('email', $email)->exists();
return response()->json([
'code' => 200,
'email' => $email,
'exists' => $exists,
2024-03-12 07:03:33 +00:00
'banned' => $banned,
]);
}
public function sessionGetMastodonFollowers(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
abort_unless($request->session()->exists('oauth_remasto_id'), 403);
$domain = $request->session()->get('oauth_domain');
$token = $request->session()->get('oauth_remote_session_token');
$id = $request->session()->get('oauth_remasto_id');
$res = RemoteAuthService::getFollowing($domain, $token, $id);
2024-03-12 07:03:33 +00:00
if (! $res) {
return response()->json([
'code' => 200,
2024-03-12 07:03:33 +00:00
'following' => [],
]);
}
2024-03-12 07:03:33 +00:00
$res = collect($res)->filter(fn ($acct) => Helpers::validateUrl($acct['url']))->values()->toArray();
return response()->json([
'code' => 200,
2024-03-12 07:03:33 +00:00
'following' => $res,
]);
}
public function handleSubmit(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
abort_unless($request->session()->exists('oauth_remasto_id'), 403);
abort_unless($request->session()->exists('oauth_masto_webfinger'), 403);
abort_unless($request->session()->exists('oauth_masto_raid'), 403);
$this->validate($request, [
'email' => 'required|email:strict,filter_unicode,dns,spoof',
'username' => [
'required',
'min:2',
'max:30',
'unique:users,username',
function ($attribute, $value, $fail) {
$dash = substr_count($value, '-');
$underscore = substr_count($value, '_');
$period = substr_count($value, '.');
2024-03-12 07:03:33 +00:00
if (ends_with($value, ['.php', '.js', '.css'])) {
return $fail('Username is invalid.');
}
2024-03-12 07:03:33 +00:00
if (($dash + $underscore + $period) > 1) {
return $fail('Username is invalid. Can only contain one dash (-), period (.) or underscore (_).');
}
2024-03-12 07:03:33 +00:00
if (! ctype_alnum($value[0])) {
return $fail('Username is invalid. Must start with a letter or number.');
}
2024-03-12 07:03:33 +00:00
if (! ctype_alnum($value[strlen($value) - 1])) {
return $fail('Username is invalid. Must end with a letter or number.');
}
$val = str_replace(['_', '.', '-'], '', $value);
2024-03-12 07:03:33 +00:00
if (! ctype_alnum($val)) {
return $fail('Username is invalid. Username must be alpha-numeric and may contain dashes (-), periods (.) and underscores (_).');
}
$restricted = RestrictedNames::get();
if (in_array(strtolower($value), array_map('strtolower', $restricted))) {
return $fail('Username cannot be used.');
}
2024-03-12 07:03:33 +00:00
},
],
'password' => 'required|string|min:8|confirmed',
2024-03-12 07:03:33 +00:00
'name' => 'nullable|max:30',
]);
$email = $request->input('email');
$username = $request->input('username');
$password = $request->input('password');
$name = $request->input('name');
$user = $this->createUser([
'name' => $name,
'username' => $username,
'password' => $password,
2024-03-12 07:03:33 +00:00
'email' => $email,
]);
$raid = $request->session()->pull('oauth_masto_raid');
$webfinger = $request->session()->pull('oauth_masto_webfinger');
$token = $user->createToken('Onboarding')->accessToken;
$ra = RemoteAuth::where('id', $raid)->where('webfinger', $webfinger)->firstOrFail();
$ra->user_id = $user->id;
$ra->save();
return [
'code' => 200,
'msg' => 'Success',
2024-03-12 07:03:33 +00:00
'token' => $token,
];
}
public function storeBio(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_unless($request->user(), 404);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
abort_unless($request->session()->exists('oauth_remasto_id'), 403);
$this->validate($request, [
'bio' => 'required|nullable|max:500',
]);
$profile = $request->user()->profile;
$profile->bio = Purify::clean($request->input('bio'));
$profile->save();
return [200];
}
public function accountToId(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_if($request->user(), 404);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
abort_unless($request->session()->exists('oauth_remasto_id'), 403);
$this->validate($request, [
2024-03-12 07:03:33 +00:00
'account' => 'required|url',
]);
$account = $request->input('account');
abort_unless(substr(strtolower($account), 0, 8) === 'https://', 404);
$host = strtolower(config('pixelfed.domain.app'));
$domain = strtolower(parse_url($account, PHP_URL_HOST));
2024-03-12 07:03:33 +00:00
if ($domain == $host) {
$username = Str::of($account)->explode('/')->last();
$user = User::where('username', $username)->first();
2024-03-12 07:03:33 +00:00
if ($user) {
return ['id' => (string) $user->profile_id];
} else {
return [];
}
} else {
try {
$profile = Helpers::profileFetch($account);
2024-03-12 07:03:33 +00:00
if ($profile) {
return ['id' => (string) $profile->id];
} else {
return [];
}
} catch (\GuzzleHttp\Exception\RequestException $e) {
return;
} catch (Exception $e) {
return [];
}
}
}
public function storeAvatar(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_unless($request->user(), 404);
$this->validate($request, [
'avatar_url' => 'required|active_url',
]);
$user = $request->user();
$profile = $user->profile;
2024-03-12 07:03:33 +00:00
abort_if(! $profile->avatar, 404, 'Missing avatar');
$avatar = $profile->avatar;
$avatar->remote_url = $request->input('avatar_url');
$avatar->save();
2024-03-12 07:03:33 +00:00
MediaStorageService::avatar($avatar, (bool) config_cache('pixelfed.cloud_storage') == false);
return [200];
}
public function finishUp(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_unless($request->user(), 404);
2024-03-12 07:03:33 +00:00
$currentWebfinger = '@'.$request->user()->username.'@'.config('pixelfed.domain.app');
$ra = RemoteAuth::where('user_id', $request->user()->id)->firstOrFail();
RemoteAuthService::submitToBeagle(
$ra->webfinger,
$ra->verify_credentials['url'],
$currentWebfinger,
$request->user()->url()
);
return [200];
}
public function handleLogin(Request $request)
{
abort_unless((
config_cache('pixelfed.open_registration') &&
config('remote-auth.mastodon.enabled')
) || (
config('remote-auth.mastodon.ignore_closed_state') &&
config('remote-auth.mastodon.enabled')
), 404);
abort_if($request->user(), 404);
abort_unless($request->session()->exists('oauth_domain'), 403);
abort_unless($request->session()->exists('oauth_remote_session_token'), 403);
abort_unless($request->session()->exists('oauth_masto_webfinger'), 403);
$domain = $request->session()->get('oauth_domain');
$wf = $request->session()->get('oauth_masto_webfinger');
$ra = RemoteAuth::where('webfinger', $wf)->where('domain', $domain)->whereNotNull('user_id')->firstOrFail();
$user = User::findOrFail($ra->user_id);
abort_if($user->is_admin || $user->status != null, 422, 'Invalid auth action');
Auth::loginUsingId($ra->user_id);
2024-03-12 07:03:33 +00:00
return [200];
}
protected function createUser($data)
{
event(new Registered($user = User::create([
2024-03-12 07:03:33 +00:00
'name' => Purify::clean($data['name']),
'username' => $data['username'],
2024-03-12 07:03:33 +00:00
'email' => $data['email'],
'password' => Hash::make($data['password']),
'email_verified_at' => config('remote-auth.mastodon.contraints.skip_email_verification') ? now() : null,
'app_register_ip' => request()->ip(),
2024-03-12 07:03:33 +00:00
'register_source' => 'mastodon',
])));
$this->guarder()->login($user);
return $user;
}
protected function guarder()
{
return Auth::guard();
}
}