1
0
mirror of https://github.com/Kovah/LinkAce.git synced 2025-01-17 13:18:21 +01:00

WIP implementation of SSO login via OAuth / OIDC (#174 #194)

This commit is contained in:
Kovah 2024-09-17 13:45:19 +02:00
parent 25a915f8f0
commit 72a210d2be
No known key found for this signature in database
GPG Key ID: AAAA031BA9830D7B
20 changed files with 1064 additions and 6 deletions

View File

@ -0,0 +1,65 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
class SocialiteController extends Controller
{
public function redirect(string $provider)
{
$this->authorizeOauthRequest($provider);
return Socialite::driver($provider)->redirect()->setTargetUrl(
route('auth.oauth.callback', ['provider' => $provider])
);
}
public function callback(string $provider)
{
$this->authorizeOauthRequest($provider);
$authUser = Socialite::driver($provider)->user();
// If a user with the provided email address already exists, register the oauth login
// @TODO what about users who try to login to a different OAuth provider?
if (User::where('email', $authUser->getEmail())->exists()) {
$user = User::where('email', $authUser->getEmail())->first();
$user->update([
'oauth_id' => $authUser->id,
'oauth_provider' => $provider,
'oauth_token' => $authUser->token ?? null,
'oauth_token_secret' => $authUser->tokenSecret ?? null,
'oauth_refresh_token' => $authUser->refreshToken ?? null,
]);
} else {
// otherwise, either update an existing oauth user or register a new user
$user = User::updateOrCreate([
'email' => $authUser->getEmail(),
'oauth_id' => $authUser->getId(),
'oauth_provider' => $provider,
], [
'name' => $authUser->getNickname(),
'email' => $authUser->getEmail(),
'oauth_id' => $authUser->getId(),
'oauth_provider' => $provider,
'oauth_token' => $authUser->token ?? null,
'oauth_token_secret' => $authUser->tokenSecret ?? null,
'oauth_refresh_token' => $authUser->refreshToken ?? null,
]);
}
Auth::login($user);
return redirect()->route('dashboard');
}
protected function authorizeOauthRequest(string $provider): void
{
if (config('auth.oauth.enabled') !== true || !in_array($provider, config('auth.oauth.providers'))) {
abort(403, 'Login unauthorized');
}
}
}

View File

@ -23,6 +23,11 @@ use Spatie\Permission\Traits\HasRoles;
* @property string $email
* @property string $password
* @property string|null $remember_token
* @property string|null $oauth_id
* @property string|null $oauth_provider
* @property string|null $oauth_token
* @property string|null $oauth_token_secret
* @property string|null $oauth_refresh_token
* @property string|null $two_factor_recovery_codes
* @property string|null $two_factor_secret
* @property Carbon|null $created_at
@ -43,11 +48,19 @@ class User extends Authenticatable implements Auditable
'email',
'password',
'blocked_at',
'oauth_id',
'oauth_provider',
'oauth_token',
'oauth_token_secret',
'oauth_refresh_token',
];
protected $hidden = [
'password',
'remember_token',
'oauth_token',
'oauth_token_secret',
'oauth_refresh_token',
];
protected $casts = [

View File

@ -4,6 +4,7 @@ namespace App\Providers;
use App\Listeners\SavingSettingsListener;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use SocialiteProviders\Manager\SocialiteWasCalled;
use Spatie\LaravelSettings\Events\SavingSettings;
class EventServiceProvider extends ServiceProvider
@ -20,6 +21,16 @@ class EventServiceProvider extends ServiceProvider
SavingSettings::class => [
SavingSettingsListener::class,
],
SocialiteWasCalled::class => [
\SocialiteProviders\Auth0\Auth0ExtendSocialite::class . '@handle',
\SocialiteProviders\Authentik\AuthentikExtendSocialite::class . '@handle',
\SocialiteProviders\Azure\AzureExtendSocialite::class . '@handle',
\SocialiteProviders\Cognito\CognitoExtendSocialite::class . '@handle',
\SocialiteProviders\FusionAuth\FusionAuthExtendSocialite::class . '@handle',
\SocialiteProviders\Keycloak\KeycloakExtendSocialite::class . '@handle',
\SocialiteProviders\Okta\OktaExtendSocialite::class . '@handle',
//\SocialiteProviders\Zitadel\ZitadelExtendSocialite::class . '@handle',
],
];
/**

View File

@ -5,9 +5,9 @@
"type": "project",
"require": {
"php": "^8.1 | ^8.2 | ^8.3",
"ext-pdo": "*",
"ext-ftp": "*",
"ext-dom": "*",
"ext-ftp": "*",
"ext-pdo": "*",
"composer/semver": "^3.3.1",
"doctrine/dbal": "^3.7",
"guzzlehttp/guzzle": "^7.0",
@ -16,6 +16,7 @@
"laravel/fortify": "^1.7",
"laravel/framework": "^v10.43",
"laravel/sanctum": "^v3.3",
"laravel/socialite": "^5.16",
"league/csv": "^9.6",
"league/flysystem-aws-s3-v3": "^3.0",
"league/flysystem-ftp": "^3.0",
@ -26,6 +27,14 @@
"rap2hpoutre/laravel-log-viewer": "^2.2",
"sentry/sentry-laravel": "^4.2.0",
"shaarli/netscape-bookmark-parser": "dev-master",
"socialiteproviders/auth0": "^4.2",
"socialiteproviders/authentik": "^5.2",
"socialiteproviders/cognito": "*",
"socialiteproviders/fusionauth": "^5.0",
"socialiteproviders/keycloak": "^5.3",
"socialiteproviders/microsoft-azure": "^5.2",
"socialiteproviders/okta": "^4.4",
"socialiteproviders/zitadel": "*",
"spatie/laravel-activitylog": "^4.5",
"spatie/laravel-backup": "^8.1.2",
"spatie/laravel-permission": "^6.3.0",

686
composer.lock generated
View File

@ -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": "5305a18bd7ecf3e5081fefb62b5784d7",
"content-hash": "b6189b53cf142ded12f56ea8042bb896",
"packages": [
{
"name": "aws/aws-crt-php",
@ -1187,6 +1187,69 @@
],
"time": "2023-10-06T06:47:41+00:00"
},
{
"name": "firebase/php-jwt",
"version": "v6.10.1",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
"reference": "500501c2ce893c824c801da135d02661199f60c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5",
"reference": "500501c2ce893c824c801da135d02661199f60c5",
"shasum": ""
},
"require": {
"php": "^8.0"
},
"require-dev": {
"guzzlehttp/guzzle": "^7.4",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.5",
"psr/cache": "^2.0||^3.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0"
},
"suggest": {
"ext-sodium": "Support EdDSA (Ed25519) signatures",
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
},
"type": "library",
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"keywords": [
"jwt",
"php"
],
"support": {
"issues": "https://github.com/firebase/php-jwt/issues",
"source": "https://github.com/firebase/php-jwt/tree/v6.10.1"
},
"time": "2024-05-18T18:05:11+00:00"
},
{
"name": "fruitcake/php-cors",
"version": "v1.3.0",
@ -2377,6 +2440,78 @@
},
"time": "2024-08-02T07:48:17+00:00"
},
{
"name": "laravel/socialite",
"version": "v5.16.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/socialite.git",
"reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/socialite/zipball/40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
"reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
"shasum": ""
},
"require": {
"ext-json": "*",
"firebase/php-jwt": "^6.4",
"guzzlehttp/guzzle": "^6.0|^7.0",
"illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
"illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
"league/oauth1-client": "^1.10.1",
"php": "^7.2|^8.0",
"phpseclib/phpseclib": "^3.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0|^9.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^8.0|^9.3|^10.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.x-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.",
"homepage": "https://laravel.com",
"keywords": [
"laravel",
"oauth"
],
"support": {
"issues": "https://github.com/laravel/socialite/issues",
"source": "https://github.com/laravel/socialite"
},
"time": "2024-09-03T09:46:57+00:00"
},
{
"name": "league/commonmark",
"version": "2.5.2",
@ -2995,6 +3130,82 @@
],
"time": "2024-01-28T23:22:08+00:00"
},
{
"name": "league/oauth1-client",
"version": "v1.10.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/oauth1-client.git",
"reference": "d6365b901b5c287dd41f143033315e2f777e1167"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167",
"reference": "d6365b901b5c287dd41f143033315e2f777e1167",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-openssl": "*",
"guzzlehttp/guzzle": "^6.0|^7.0",
"guzzlehttp/psr7": "^1.7|^2.0",
"php": ">=7.1||>=8.0"
},
"require-dev": {
"ext-simplexml": "*",
"friendsofphp/php-cs-fixer": "^2.17",
"mockery/mockery": "^1.3.3",
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5||9.5"
},
"suggest": {
"ext-simplexml": "For decoding XML-based responses."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev",
"dev-develop": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"League\\OAuth1\\Client\\": "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"
],
"support": {
"issues": "https://github.com/thephpleague/oauth1-client/issues",
"source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1"
},
"time": "2022-04-15T14:02:14+00:00"
},
{
"name": "masterminds/html5",
"version": "2.9.0",
@ -5299,6 +5510,475 @@
],
"time": "2024-02-05T20:31:01+00:00"
},
{
"name": "socialiteproviders/auth0",
"version": "4.2.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Auth0.git",
"reference": "2f280a2f90d050b391e938b6ccaaa5bbec5ac699"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Auth0/zipball/2f280a2f90d050b391e938b6ccaaa5bbec5ac699",
"reference": "2f280a2f90d050b391e938b6ccaaa5bbec5ac699",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^8.0",
"socialiteproviders/manager": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"SocialiteProviders\\Auth0\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chase Coney",
"email": "chase.coney@gmail.com"
}
],
"description": "Auth0 OAuth2 Provider for Laravel Socialite",
"keywords": [
"auth0",
"laravel",
"oauth",
"provider",
"socialite"
],
"support": {
"docs": "https://socialiteproviders.com/auth0",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2024-05-20T23:48:59+00:00"
},
{
"name": "socialiteproviders/authentik",
"version": "5.2.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Authentik.git",
"reference": "4cf129cf04728a38e0531c54454464b162f0fa66"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Authentik/zipball/4cf129cf04728a38e0531c54454464b162f0fa66",
"reference": "4cf129cf04728a38e0531c54454464b162f0fa66",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^8.0",
"socialiteproviders/manager": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"SocialiteProviders\\Authentik\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "rf152",
"email": "git@rf152.co.uk"
}
],
"description": "Authentik OAuth2 Provider for Laravel Socialite",
"keywords": [
"authentik",
"laravel",
"oauth",
"provider",
"socialite"
],
"support": {
"docs": "https://socialiteproviders.com/authentik",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2023-11-07T22:21:16+00:00"
},
{
"name": "socialiteproviders/cognito",
"version": "4.1.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Cognito.git",
"reference": "d35cc4f3dc34f35d65dbd36508880d6d59af4a9d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Cognito/zipball/d35cc4f3dc34f35d65dbd36508880d6d59af4a9d",
"reference": "d35cc4f3dc34f35d65dbd36508880d6d59af4a9d",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^7.4 || ^8.0",
"socialiteproviders/manager": "~4.0"
},
"type": "library",
"autoload": {
"psr-4": {
"SocialiteProviders\\Cognito\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "James Siebert",
"email": "js@media360.com.au"
}
],
"description": "Cognito OAuth2 Provider for Laravel Socialite",
"keywords": [
"Cognito",
"aws",
"laravel",
"oauth",
"provider",
"socialite"
],
"support": {
"docs": "https://socialiteproviders.com/cognito",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2022-07-18T08:41:37+00:00"
},
{
"name": "socialiteproviders/fusionauth",
"version": "5.0.3",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/FusionAuth.git",
"reference": "48e2983c77b1072e405ea78d534cfa36690020cb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/FusionAuth/zipball/48e2983c77b1072e405ea78d534cfa36690020cb",
"reference": "48e2983c77b1072e405ea78d534cfa36690020cb",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^7.2 || ^8.0",
"socialiteproviders/manager": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"SocialiteProviders\\FusionAuth\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Danilo Polani",
"email": "danilo.polani@gmail.com"
}
],
"description": "FusionAuth OAuth2 Provider for Laravel Socialite",
"keywords": [
"fusionauth",
"laravel",
"oauth",
"provider",
"socialite"
],
"support": {
"docs": "https://socialiteproviders.com/fusionauth",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2023-08-29T22:39:24+00:00"
},
{
"name": "socialiteproviders/keycloak",
"version": "5.3.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Keycloak.git",
"reference": "87d13f8a411a6f8f5010ecbaff9aedd4494863e4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Keycloak/zipball/87d13f8a411a6f8f5010ecbaff9aedd4494863e4",
"reference": "87d13f8a411a6f8f5010ecbaff9aedd4494863e4",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^7.4 || ^8.0",
"socialiteproviders/manager": "~4.0"
},
"type": "library",
"autoload": {
"psr-4": {
"SocialiteProviders\\Keycloak\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oleg Kuchumov",
"email": "voenniy@gmail.com"
}
],
"description": "Keycloak OAuth2 Provider for Laravel Socialite",
"keywords": [
"keycloak",
"laravel",
"oauth",
"provider",
"socialite"
],
"support": {
"docs": "https://socialiteproviders.com/keycloak",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2023-04-10T05:50:49+00:00"
},
{
"name": "socialiteproviders/manager",
"version": "v4.6.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Manager.git",
"reference": "dea5190981c31b89e52259da9ab1ca4e2b258b21"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/dea5190981c31b89e52259da9ab1ca4e2b258b21",
"reference": "dea5190981c31b89e52259da9ab1ca4e2b258b21",
"shasum": ""
},
"require": {
"illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0",
"laravel/socialite": "^5.5",
"php": "^8.0"
},
"require-dev": {
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^9.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"SocialiteProviders\\Manager\\ServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"SocialiteProviders\\Manager\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Andy Wendt",
"email": "andy@awendt.com"
},
{
"name": "Anton Komarev",
"email": "a.komarev@cybercog.su"
},
{
"name": "Miguel Piedrafita",
"email": "soy@miguelpiedrafita.com"
},
{
"name": "atymic",
"email": "atymicq@gmail.com",
"homepage": "https://atymic.dev"
}
],
"description": "Easily add new or override built-in providers in Laravel Socialite.",
"homepage": "https://socialiteproviders.com",
"keywords": [
"laravel",
"manager",
"oauth",
"providers",
"socialite"
],
"support": {
"issues": "https://github.com/socialiteproviders/manager/issues",
"source": "https://github.com/socialiteproviders/manager"
},
"time": "2024-05-04T07:57:39+00:00"
},
{
"name": "socialiteproviders/microsoft-azure",
"version": "5.2.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Microsoft-Azure.git",
"reference": "453d62c9d7e3b3b76e94c913fb46e68a33347b16"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Microsoft-Azure/zipball/453d62c9d7e3b3b76e94c913fb46e68a33347b16",
"reference": "453d62c9d7e3b3b76e94c913fb46e68a33347b16",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^8.0",
"socialiteproviders/manager": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"SocialiteProviders\\Azure\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Hemmings",
"email": "chris@hemmin.gs"
}
],
"description": "Microsoft Azure OAuth2 Provider for Laravel Socialite",
"keywords": [
"azure",
"laravel",
"microsoft",
"oauth",
"provider",
"socialite"
],
"support": {
"docs": "https://socialiteproviders.com/microsoft-azure",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2024-03-15T03:02:10+00:00"
},
{
"name": "socialiteproviders/okta",
"version": "4.4.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Okta.git",
"reference": "5e47cd7b4c19da94ecafbd91fa430e4151c09806"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Okta/zipball/5e47cd7b4c19da94ecafbd91fa430e4151c09806",
"reference": "5e47cd7b4c19da94ecafbd91fa430e4151c09806",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^8.0",
"socialiteproviders/manager": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"SocialiteProviders\\Okta\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chase Coney",
"email": "chase.coney@gmail.com"
}
],
"description": "Okta OAuth2 Provider for Laravel Socialite",
"keywords": [
"laravel",
"oauth",
"okta",
"provider",
"socialite"
],
"support": {
"docs": "https://socialiteproviders.com/okta",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2023-12-12T01:59:17+00:00"
},
{
"name": "socialiteproviders/zitadel",
"version": "4.1.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Zitadel.git",
"reference": "2e1c0843a9531eb0e31a04b31683a63f1a7d1865"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SocialiteProviders/Zitadel/zipball/2e1c0843a9531eb0e31a04b31683a63f1a7d1865",
"reference": "2e1c0843a9531eb0e31a04b31683a63f1a7d1865",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^8.1",
"socialiteproviders/manager": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Socialiteproviders\\Zitadel\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gurkirat Singh",
"email": "tbhaxor@gmail.com"
}
],
"description": "Zitadel OAuth2 Provider for Laravel Socialite",
"support": {
"docs": "https://socialiteproviders.com/zoho",
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
"time": "2024-08-26T06:14:57+00:00"
},
{
"name": "spatie/db-dumper",
"version": "3.6.0",
@ -12672,9 +13352,9 @@
"prefer-lowest": false,
"platform": {
"php": "^8.1 | ^8.2 | ^8.3",
"ext-pdo": "*",
"ext-dom": "*",
"ext-ftp": "*",
"ext-dom": "*"
"ext-pdo": "*"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"

View File

@ -231,6 +231,7 @@ return [
/*
* Package Service Providers...
*/
\SocialiteProviders\Manager\ServiceProvider::class,
/*
* Application Service Providers...

View File

@ -18,6 +18,30 @@ return [
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| OAuth Settings
|--------------------------------------------------------------------------
*/
'oauth' => [
'enabled' => env('OAUTH_ENABLED', false),
'regular_login_disabled' => env('REGULAR_LOGIN_DISABLED', false),
'providers' => [
'auth0',
'authentik',
'azure',
'cognito',
'fusionauth',
'google',
'github',
'gitlab',
'keycloak',
'okta',
'zitadel',
],
],
/*
|--------------------------------------------------------------------------
| Authentication Guards

View File

@ -31,4 +31,99 @@ return [
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
// OAuth and SSO
'auth0' => [
'enabled' => env('OAUTH_AUTH0_ENABLED', false),
'base_url' => env('OAUTH_AUTH0_BASE_URL'),
'client_id' => env('OAUTH_AUTH0_CLIENT_ID'),
'client_secret' => env('OAUTH_AUTH0_CLIENT_SECRET'),
'redirect' => '/auth/oauth/auth0/callback',
],
'authentik' => [
'enabled' => env('OAUTH_AUTHENTIK_ENABLED', false),
'base_url' => env('OAUTH_AUTHENTIK_BASE_URL'),
'client_id' => env('OAUTH_AUTHENTIK_CLIENT_ID'),
'client_secret' => env('OAUTH_AUTHENTIK_CLIENT_SECRET'),
'redirect' => '/auth/oauth/authentik/callback',
],
'azure' => [
'enabled' => env('OAUTH_AZURE_ENABLED', false),
'client_id' => env('OAUTH_AZURE_CLIENT_ID'),
'client_secret' => env('OAUTH_AZURE_CLIENT_SECRET'),
'tenant' => env('OAUTH_AZURE_TENANT_ID'),
'proxy' => env('PROXY'),
'redirect' => '/auth/oauth/azure/callback',
],
'cognito' => [
'enabled' => env('OAUTH_COGNITO_ENABLED', false),
'host' => env('OAUTH_COGNITO_HOST'),
'client_id' => env('OAUTH_COGNITO_CLIENT_ID'),
'client_secret' => env('OAUTH_COGNITO_CLIENT_SECRET'),
'redirect' => env('OAUTH_COGNITO_CALLBACK_URL'),
'scope' => explode(',', env('OAUTH_COGNITO_LOGIN_SCOPE', '')),
'logout_uri' => env('OAUTH_COGNITO_SIGN_OUT_URL'),
],
'fusionauth' => [
'enabled' => env('OAUTH_FUSIONAUTH_ENABLED', false),
'base_url' => env('OAUTH_FUSIONAUTH_BASE_URL'),
'client_id' => env('OAUTH_FUSIONAUTH_CLIENT_ID'),
'client_secret' => env('OAUTH_FUSIONAUTH_CLIENT_SECRET'),
'redirect' => '/auth/oauth/fusionauth/callback',
],
'google' => [
'enabled' => env('OAUTH_GOOGLE_ENABLED', false),
'client_id' => env('OAUTH_GOOGLE_CLIENT_ID'),
'client_secret' => env('OAUTH_GOOGLE_CLIENT_SECRET'),
'redirect' => '/auth/oauth/{provider}/callback',
],
'github' => [
'enabled' => env('OAUTH_GITHUB_ENABLED', false),
'client_id' => env('OAUTH_GITHUB_CLIENT_ID'),
'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'),
'redirect' => '/auth/oauth/github/callback',
],
'gitlab' => [
'enabled' => env('OAUTH_GITLAB_ENABLED', false),
'host' => env('OAUTH_GITLAB_HOST'),
'client_id' => env('OAUTH_GITLAB_CLIENT_ID'),
'client_secret' => env('OAUTH_GITLAB_CLIENT_SECRET'),
'redirect' => '/auth/oauth/gitlab/callback',
],
'keycloak' => [
'enabled' => env('OAUTH_KEYCLOAK_ENABLED', false),
'client_id' => env('OAUTH_KEYCLOAK_CLIENT_ID'),
'client_secret' => env('OAUTH_KEYCLOAK_CLIENT_SECRET'),
'realms' => env('OAUTH_KEYCLOAK_REALM'),
'redirect' => '/auth/oauth/keycloak/callback',
],
'okta' => [
'enabled' => env('OAUTH_OKTA_ENABLED', false),
'base_url' => env('OAUTH_OKTA_BASE_URL'),
'client_id' => env('OAUTH_OKTA_CLIENT_ID'),
'client_secret' => env('OAUTH_OKTA_CLIENT_SECRET'),
'redirect' => '/auth/oauth/okta/callback',
],
'zitadel' => [
'enabled' => env('OAUTH_ZITADEL_ENABLED', false),
'client_id' => env('OAUTH_ZITADEL_CLIENT_ID'),
'client_secret' => env('OAUTH_ZITADEL_CLIENT_SECRET'),
'base_url' => env('OAUTH_ZITADEL_BASE_URL'),
'organization_id' => env('OAUTH_ZITADEL_ORGANIZATION_ID'),
'project_id' => env('OAUTH_ZITADEL_PROJECT_ID'),
'post_logout_redirect_uri' => env('OAUTH_ZITADEL_POST_LOGOUT_REDIRECT_URI', '/'),
'redirect' => '/auth/oauth/zitadel/callback',
],
];

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->after('remember_token', function (Blueprint $table) {
$table->string('oauth_id')->nullable();
$table->string('oauth_provider')->nullable();
$table->string('oauth_token')->nullable();
$table->string('oauth_token_secret')->nullable();
$table->string('oauth_refresh_token')->nullable();
});
$table->string('password')->nullable()->change();
});
}
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn([
'oauth_id',
'oauth_provider',
'oauth_token',
'oauth_token_secret',
'oauth_refresh_token',
]);
$table->string('password')->nullable(false)->change();
});
}
};

View File

@ -152,6 +152,12 @@ code {
path {
fill: currentColor;
}
rect {
fill: currentColor;
}
circle {
fill: currentColor;
}
&.fw {
width: 1em;

View File

@ -8,7 +8,12 @@
<div class="alert alert-info small">@lang('linkace.demo_login_hint')</div>
@endif
@include('partials.alerts')
@include('auth.login-form')
@if(config('auth.oauth.regular_login_disabled') !== true)
@include('auth.login-form')
@endif
@if(config('auth.oauth.enabled') === true)
@include('auth.oauth')
@endif
</div>
</div>

View File

@ -0,0 +1,14 @@
<div class="card {{ config('auth.oauth.regular_login_disabled') ? '' : 'mt-4' }}">
<div class="card-body">
<h2 class="h6">Login with</h2>
<div class="d-flex flex-wrap gap-2">
@foreach(config('auth.oauth.providers') as $provider)
@if(config('services.'.$provider.'.enabled') === true)
<a href="{{ route('auth.oauth.redirect', ['provider' => $provider]) }}" class="btn btn-outline-primary">
<x-dynamic-component :component="'icon.brand.'.$provider" class="me-1"/> {{ ucwords($provider) }}
</a>
@endif
@endforeach
</div>
</div>
</div>

View File

@ -0,0 +1,14 @@
<svg {{ $attributes->merge(['class' => 'icon', 'aria-label' => 'Auth0']) }} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 40" fill="none">
<path
d="M1.68997 17.8918C6.93659 17.0276 11.0459 12.6902 11.9101 7.44679L12.1993 4.92469C12.27 4.52308 12.0001 3.96725 11.4924 4.00581C7.52776 4.31424 3.79119 5.62188 1.70604 6.47329C0.674703 6.89418 0 7.89981 0 9.01467V17.2396C0 17.728 0.43695 18.0975 0.918881 18.0203L1.68997 17.895V17.8918Z"
fill="#FFFEFA"></path>
<path
d="M14.4397 7.44608C15.304 12.6927 19.4133 17.0269 24.6599 17.8911L25.431 18.0164C25.9129 18.0967 26.3498 17.724 26.3498 17.2357V9.01074C26.3498 7.89588 25.6751 6.89346 24.6438 6.46937C22.5619 5.61796 18.8221 4.31032 14.8574 4.00188C14.3498 3.96333 14.0863 4.52558 14.1474 4.92076L14.4365 7.44286L14.4397 7.44608Z"
fill="#FFFEFA"></path>
<path
d="M24.6566 20.1924C17.4887 21.6061 14.1602 26.3708 14.1602 35.3925C14.1602 35.8455 14.61 36.1572 14.9859 35.9066C18.2823 33.6833 25.5369 27.8808 26.2855 20.6197C26.3145 19.7041 25.1707 20.1346 24.6566 20.1924Z"
fill="#FFFEFA"></path>
<path
d="M1.69196 20.1963C8.85988 21.61 12.1884 26.3747 12.1884 35.3964C12.1884 35.8494 11.7386 36.1611 11.3627 35.9105C8.0663 33.6872 0.811637 27.8847 0.0630382 20.6236C0.0341223 19.708 1.1779 20.1385 1.69196 20.1963Z"
fill="#FFFEFA"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,18 @@
<svg {{ $attributes->merge(['class' => 'icon', 'aria-label' => 'Authentik']) }} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 151.65">
<rect x="107.1" y="34.93" width="6.37" height="18.2"/>
<rect x="123.67" y="34.16" width="6.37" height="14.23"/>
<path
d="M30.83,55A23.23,23.23,0,0,0,10.41,67.13h10.8C26,63,32.94,61.8,38,67.13H49.39C44.93,61.09,38.24,55,30.83,55Z"/>
<path
d="M46.25,78.11c-14.89,31.15-41,4.6-25-11H10.41c-8.47,14.76,3.24,34.68,20.42,34.23,13.28,0,24.24-19.72,24.24-23.21,0-1.54-2.14-6.25-5.68-11H38A40.52,40.52,0,0,1,46.25,78.11Zm.4-.91Z"/>
<path
d="M189.62,34.71V117A28.62,28.62,0,0,1,161,145.54H148.89v-28H90.94v28H78.81A28.62,28.62,0,0,1,50.22,117V91.08h91.87V41.62H97.74V69.41H50.22V34.71a27.43,27.43,0,0,1,.19-3.29,27.09,27.09,0,0,1,.71-3.84c.1-.41.22-.82.34-1.21a2.13,2.13,0,0,1,.09-.3c.07-.21.13-.4.2-.59s.14-.4.21-.59.16-.44.25-.65.18-.43.26-.64a29.35,29.35,0,0,1,2.6-4.82l0-.05c.26-.37.53-.75.81-1.12s.47-.61.7-.91.57-.67.86-1,.56-.63.86-.93l0,0a4.53,4.53,0,0,1,.49-.49,29.23,29.23,0,0,1,3.4-2.84c.32-.24.66-.46,1-.68s.77-.49,1.17-.72a23.78,23.78,0,0,1,2.29-1.21l.75-.34a27.84,27.84,0,0,1,3.35-1.21c.44-.13.88-.24,1.33-.35a6.19,6.19,0,0,1,.65-.15,28.86,28.86,0,0,1,3.87-.57l.56,0h.28c.43,0,.87,0,1.31,0H161c.43,0,.87,0,1.3,0h.28l.56,0a29.25,29.25,0,0,1,3.88.57c.22,0,.43.09.65.15.45.11.88.22,1.32.35a27.23,27.23,0,0,1,3.35,1.21l.75.34a25.19,25.19,0,0,1,2.3,1.21c.39.23.78.47,1.16.72s.69.44,1,.68a29.23,29.23,0,0,1,3.91,3.36q.45.45.87.93c.29.32.57.66.85,1l.71.91c.28.37.54.75.8,1.12l0,.05a28.61,28.61,0,0,1,2.6,4.82l.27.64.24.65c.08.19.15.39.22.59l.19.59c0,.09.06.19.1.3.11.39.23.8.34,1.21a28.56,28.56,0,0,1,.7,3.84A27.42,27.42,0,0,1,189.62,34.71Z"/>
<path d="M184.76,18.78H55.07A28.59,28.59,0,0,1,78.8,6.12H161A28.59,28.59,0,0,1,184.76,18.78Z"/>
<path d="M189.43,31.43H50.4a28.29,28.29,0,0,1,4.67-12.65H184.76A28.17,28.17,0,0,1,189.43,31.43Z"/>
<path
d="M189.63,34.71v9.37H142.09V41.62H97.74v2.46H50.21V34.71a27.43,27.43,0,0,1,.19-3.29h139A27.42,27.42,0,0,1,189.63,34.71Z"/>
<rect x="50.21" y="44.08" width="47.54" height="12.66"/>
<rect x="142.09" y="44.08" width="47.54" height="12.66"/>
<rect x="50.21" y="56.74" width="47.54" height="12.65"/>
<rect x="142.09" y="56.74" width="47.54" height="12.65"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1 @@
<svg {{ $attributes->merge(['class' => 'icon', 'viewBox' =>'0 0 448 512', 'xmlns' => 'http://www.w3.org/2000/svg', 'aria-hidden' => 'true', 'focusable' => 'false']) }}><path d="M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"/></svg>

After

Width:  |  Height:  |  Size: 294 B

View File

@ -0,0 +1,14 @@
<svg {{ $attributes->merge(['class' => 'icon', 'aria-label' => 'FusionAuth']) }} viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<g id="fa_logo_purple" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="logo-white-only-copy" transform="translate(25, 22)" fill="#1E293B" fill-rule="nonzero">
<path d="M42.1484996,137.66991 C36.6833384,134.528952 31.6963641,130.62121 27.3395673,126.065783 C26.0759931,127.650679 24.5313734,128.98935 22.7829727,130.014831 C21.8172658,130.560079 20.7996702,131.007821 19.745243,131.351432 C43.3171444,157.092035 81.514904,163.202418 111.940339,146.09961 C113.379034,145.273539 114.266165,143.741199 114.266165,142.082212 C114.266165,140.423226 113.379034,138.890886 111.940339,138.064815 L111.940339,138.064815 C110.544127,137.227231 108.807093,137.19828 107.383745,137.988872 C87.1145338,149.434804 62.3048166,149.313499 42.1484996,137.66991 Z" id="Path"></path>
<path d="M42.1333109,23.8158008 C47.6002209,20.6627518 53.4933346,18.3147143 59.630634,16.8442112 C58.8680272,14.909435 58.4764302,12.8483979 58.4762967,10.7687518 C58.4791507,9.64672184 58.5910603,8.52762578 58.810447,7.42724912 C24.7434872,14.9918105 0.377235926,45.0279979 0,79.9226684 C0.00543281109,81.5804168 0.893430551,83.1097751 2.33044934,83.9362957 C3.76746812,84.7628163 5.53593485,84.7613592 6.97158966,83.9324716 L6.97158966,83.9324716 C8.38121575,83.1404765 9.26556465,81.6607816 9.29545288,80.0441776 C9.54382298,56.8175629 22.0258546,35.4445375 42.1333109,23.8158008 Z" id="Path"></path>
<path d="M140.722828,80.7428554 C140.720716,87.0525704 139.810183,93.3291152 138.019249,99.3793271 C140.061684,99.6786894 142.029781,100.358765 143.821313,101.384229 C144.782663,101.934288 145.692586,102.569709 146.540081,103.28281 C156.995816,69.9970709 143.153599,33.894052 113.125054,16.1303447 C111.686863,15.3769003 109.959746,15.4285699 108.569167,16.2666418 C107.178589,17.1047137 106.326144,18.6076906 106.32029,20.2312798 L106.32029,20.2312798 C106.303683,21.8447185 107.14136,23.346761 108.522894,24.1803284 C128.489516,36.0273698 140.728313,57.526086 140.722828,80.7428554 Z" id="Path"></path>
<path d="M75.0167349,49.4846131 C87.6608927,49.4784729 99.0634414,57.0904017 103.906409,68.7703173 C108.749376,80.4502329 106.078804,93.8974491 97.1402067,102.840392 C88.201609,111.783335 74.7556924,114.460443 63.0734243,109.623153 C51.3911563,104.785862 43.773685,93.3870146 43.773685,80.7428554 C43.7904148,63.4922697 57.7661594,49.5097309 75.0167349,49.4846131 M75.0167349,40.2043497 C52.627938,40.2043497 34.4782321,58.3540585 34.4782321,80.7428554 C34.4782321,103.131652 52.627938,121.281358 75.0167349,121.281358 C97.4055318,121.281358 115.555241,103.131652 115.555241,80.7428554 C115.559269,69.9901407 111.289555,59.6766717 103.686237,52.0733537 C96.0829187,44.4700357 85.7694496,40.2003216 75.0167349,40.2043497 Z" id="Shape"></path>
<circle id="Oval" cx="75.0015463" cy="10.8143177" r="10.8143177"></circle>
<circle id="Oval" cx="14.4444047" cy="115.691936" r="10.8143177"></circle>
<circle id="Oval" cx="135.558688" cy="115.691936" r="10.8143177"></circle>
<path d="M83.9780918,73.3459836 C83.9840178,68.9845719 80.8491326,65.2522279 76.5522173,64.5049213 C72.255302,63.7576148 68.0443705,66.2123964 66.5774916,70.319733 C65.1106126,74.4270697 66.8138325,78.9940094 70.6120269,81.1377603 L67.7869382,95.4606558 C67.6945357,95.9128511 67.8127575,96.3825292 68.1082279,96.7370937 C68.4036983,97.0916582 68.8443581,97.2926379 69.3058031,97.2836056 L80.80361,97.2836056 C81.265055,97.2926379 81.7057148,97.0916582 82.0011852,96.7370937 C82.2966556,96.3825292 82.4148774,95.9128511 82.3224749,95.4606558 L79.4821976,81.1377603 C82.2726337,79.5376403 83.9892107,76.5626267 83.9780918,73.3459836 L83.9780918,73.3459836 Z" id="Path"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1 @@
<svg {{ $attributes->merge(['class' => 'icon', 'aria-label' => 'Keycloak']) }} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M336 352c97.2 0 176-78.8 176-176S433.2 0 336 0S160 78.8 160 176c0 18.7 2.9 36.8 8.3 53.7L7 391c-4.5 4.5-7 10.6-7 17l0 80c0 13.3 10.7 24 24 24l80 0c13.3 0 24-10.7 24-24l0-40 40 0c13.3 0 24-10.7 24-24l0-40 40 0c6.4 0 12.5-2.5 17-7l33.3-33.3c16.9 5.4 35 8.3 53.7 8.3zM376 96a40 40 0 1 1 0 80 40 40 0 1 1 0-80z"/></svg>

After

Width:  |  Height:  |  Size: 461 B

View File

@ -0,0 +1,3 @@
<svg {{ $attributes->merge(['class' => 'icon', 'aria-label' => 'Okta']) }} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
<path d="M19.8,.26l-.74,9.12c-.35-.04-.7-.06-1.06-.06-.45,0-.89,.03-1.32,.1l-.42-4.42c-.01-.14,.1-.26,.24-.26h.75l-.36-4.47c-.01-.14,.1-.26,.23-.26h2.45c.14,0,.25,.12,.23,.26h0Zm-6.18,.45c-.04-.13-.18-.21-.31-.16l-2.3,.84c-.13,.05-.19,.2-.13,.32l1.87,4.08-.71,.26c-.13,.05-.19,.2-.13,.32l1.91,4.01c.69-.38,1.44-.67,2.23-.85L13.63,.71ZM7.98,3.25l5.29,7.46c-.67,.44-1.28,.96-1.8,1.56l-3.17-3.12c-.1-.1-.09-.26,.01-.35l.58-.48-3.15-3.19c-.1-.1-.09-.26,.02-.35l1.87-1.57c.11-.09,.26-.07,.34,.04ZM3.54,7.57c-.11-.08-.27-.04-.34,.08l-1.22,2.12c-.07,.12-.02,.27,.1,.33l4.06,1.92-.38,.65c-.07,.12-.02,.28,.11,.33l4.04,1.85c.29-.75,.68-1.45,1.16-2.08L3.54,7.57ZM.55,13.33c.02-.14,.16-.22,.29-.19l8.85,2.31c-.23,.75-.36,1.54-.38,2.36l-4.43-.36c-.14-.01-.24-.14-.21-.28l.13-.74-4.47-.42c-.14-.01-.23-.14-.21-.28l.42-2.41h0Zm-.33,5.98c-.14,.01-.23,.14-.21,.28l.43,2.41c.02,.14,.16,.22,.29,.19l4.34-1.13,.13,.74c.02,.14,.16,.22,.29,.19l4.28-1.18c-.25-.74-.41-1.53-.45-2.34L.21,19.31Zm1.42,6.34c-.07-.12-.02-.27,.1-.33l8.26-3.92c.31,.74,.73,1.43,1.23,2.05l-3.62,2.58c-.11,.08-.27,.05-.34-.07l-.38-.66-3.69,2.55c-.11,.08-.27,.04-.34-.08l-1.23-2.12Zm10.01-1.72l-6.43,6.51c-.1,.1-.09,.26,.02,.35l1.88,1.57c.11,.09,.26,.07,.34-.04l2.6-3.66,.58,.49c.11,.09,.27,.07,.35-.05l2.52-3.66c-.68-.42-1.31-.93-1.85-1.51Zm-1.27,10.45c-.13-.05-.19-.2-.13-.32l3.81-8.32c.7,.36,1.46,.63,2.25,.78l-1.12,4.3c-.03,.13-.18,.21-.31,.16l-.71-.26-1.19,4.33c-.04,.13-.18,.21-.31,.16l-2.3-.84h0Zm6.56-7.75l-.74,9.12c-.01,.14,.1,.26,.23,.26h2.45c.14,0,.25-.12,.23-.26l-.36-4.47h.75c.14,0,.25-.12,.24-.26l-.42-4.42c-.43,.07-.87,.1-1.32,.1-.36,0-.71-.02-1.06-.07h0ZM25.76,1.94c.06-.13,0-.27-.13-.32l-2.3-.84c-.13-.05-.27,.03-.31,.16l-1.19,4.33-.71-.26c-.13-.05-.27,.03-.31,.16l-1.12,4.3c.8,.16,1.55,.43,2.25,.78L25.76,1.94h0Zm5.02,3.63l-6.43,6.51c-.54-.58-1.16-1.09-1.85-1.51l2.52-3.66c.08-.11,.24-.14,.35-.05l.58,.49,2.6-3.66c.08-.11,.24-.13,.34-.04l1.88,1.57c.11,.09,.11,.25,.02,.35Zm3.48,5.12c.13-.06,.17-.21,.1-.33l-1.23-2.12c-.07-.12-.23-.15-.34-.08l-3.69,2.55-.38-.65c-.07-.12-.23-.16-.34-.07l-3.62,2.58c.5,.62,.91,1.31,1.23,2.05l8.26-3.92Zm1.3,3.32l.42,2.41c.02,.14-.07,.26-.21,.28l-9.11,.85c-.04-.82-.2-1.6-.45-2.34l4.28-1.18c.13-.04,.27,.05,.29,.19l.13,.74,4.34-1.13c.13-.03,.27,.05,.29,.19h0Zm-.41,8.85c.13,.03,.27-.05,.29-.19l.42-2.41c.02-.14-.07-.26-.21-.28l-4.47-.42,.13-.74c.02-.14-.07-.26-.21-.28l-4.43-.36c-.02,.82-.15,1.61-.38,2.36l8.85,2.31h0Zm-2.36,5.5c-.07,.12-.23,.15-.34,.08l-7.53-5.2c.48-.63,.87-1.33,1.16-2.08l4.04,1.85c.13,.06,.18,.21,.11,.33l-.38,.65,4.06,1.92c.12,.06,.17,.21,.1,.33l-1.22,2.12h0Zm-10.07-3.07l5.29,7.46c.08,.11,.24,.13,.34,.04l1.87-1.57c.11-.09,.11-.25,.02-.35l-3.15-3.19,.58-.48c.11-.09,.11-.25,.01-.35l-3.17-3.12c-.53,.6-1.13,1.13-1.8,1.56h0Zm-.05,10.16c-.13,.05-.27-.03-.31-.16l-2.42-8.82c.79-.18,1.54-.47,2.23-.85l1.91,4.01c.06,.13,0,.28-.13,.32l-.71,.26,1.87,4.08c.06,.13,0,.27-.13,.32l-2.3,.84h0Z" fill="#191919" fill-rule="evenodd"></path>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,44 @@
<svg {{ $attributes->merge(['class' => 'icon', 'aria-label' => '']) }} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 95 81">
<path d="M20.918 89.57h294.943v79.632H20.918z" style="fill:none" transform="translate(-20.918 -88.744)"/>
<path d="M1493.5 1056.38V1037h3v24.62l-70.48-41.24 70.48-40.988V1004h-3v-19.392l-61.52 35.782 61.52 35.99Z"
transform="matrix(.43887 -.1176 .1176 .43887 -716.35 -229.278)"/>
<path d="M212.517 110h-12.125L190 92l-10.392 18h-12.125L190 71l22.517 39Z"
transform="matrix(-.1176 -.43887 .43887 -.1176 .489 147.968)"/>
<path d="M212.517 110h-12.125L190 92l-10.392 18h-12.125L190 71l22.517 39Z"
transform="matrix(.43887 .1176 -.1176 .43887 -14.85 -48.254)"/>
<path d="M212.517 110h-12.125L190 92l-10.392 18h-12.125L190 71l22.517 39Z"
transform="matrix(-.32127 .32127 -.32127 -.32127 162.921 36.777)"/>
<path d="M139.622 117 149 142h-18.756l9.378-25Z"
transform="matrix(-.43887 -.1176 .1176 -.43887 90.607 139.907)"/>
<path d="M139.622 117 149 142h-18.756l9.378-25Z"
transform="scale(-.45435 .45435) rotate(45 108.173 -159.724)"/>
<path d="M139.622 117 149 142h-18.756l9.378-25Z"
transform="matrix(-.1176 -.43887 -.43887 .1176 143.747 86.32)"/>
<circle cx="1496" cy="1004" r="7"
transform="matrix(.43887 -.1176 .1176 .43887 -716.897 -229.16)"/>
<circle cx="1496" cy="1004" r="7"
transform="matrix(.43887 -.1176 .1176 .43887 -712.788 -214.678)"/>
<circle cx="1496" cy="1004" r="7"
transform="matrix(.43887 -.1176 .1176 .43887 -710.323 -205.023)"/>
<circle cx="1496" cy="1004" r="7"
transform="matrix(.43887 -.1176 .1176 .43887 -743.74 -214.209)"/>
<circle cx="1496" cy="1004" r="7"
transform="matrix(.43887 -.1176 .1176 .43887 -719.362 -238.816)"/>
<path
d="M1499.26 757.787s-1.89-1.298-2.26-2.587c-.29-1.018-.43-4.538-.46-5.2-.13-2.697 2.67-4.356 2.67-4.356l-9.2.191s3.14-.122 3.45 4.165c.05.661-.23 3.476-.46 5.2-.09 1.247-1.8 2.468-1.8 2.468l8.06.119Z"
transform="matrix(.43887 -.1176 .1029 .384 -676.905 -82.123)"/>
<path d="M1495 760v-16" style="fill:none" transform="matrix(.43887 -.1176 .1029 .384 -670.605 -57.986)"/>
<path
d="M1498.27 757.077s-1.56-.617-1.62-2.277c0-1.142-.01-1.519 0-2.784-.03-.682-.06-1.408 0-2.067.13-3.113 1.85-3.793 1.85-3.793l-7.04-.225s1.91.788 2.19 3.899c.06.659.04 1.698 0 2.379a88.86 88.86 0 0 0 0 2.309c.03 1.816-1.07 2.309-1.07 2.309l5.69.25Z"
transform="matrix(.43887 -.1176 .1029 .384 -670.605 -57.986)"/>
<path d="m1496.17 759.473 59.37-39.459" style="fill:none"
transform="matrix(.43887 -.1176 .1029 .384 -702.927 -66.259)"/>
<path
d="M1500.86 762.056s-1-1.656 2.23-4.6c1.82-1.659 4.24-3.305 6.89-5.201 4.84-3.465 10.7-7.315 16.54-11.206 4.93-3.283 9.86-6.57 14.3-9.369 3.7-2.331 7.03-4.384 9.72-5.88.53-.294 1.06-.471 1.51-.771 2.68-1.772 4.8-.061 4.8-.061l-4.62-8.686s-.24 3.172-2.23 4.715c-.43.336-.85.744-1.33 1.123-2.47 1.933-5.68 4.224-9.28 6.747-4.33 3.031-9.26 6.299-14.2 9.571-5.84 3.876-11.67 7.796-16.7 10.891-2.75 1.694-5.21 3.248-7.36 4.269-3.14 1.488-5.85.019-5.85.019l5.58 8.439Z"
transform="matrix(.43887 -.1176 .1029 .384 -702.927 -66.259)"/>
<path d="m1496.17 759.473 59.37-39.459" style="fill:none"
transform="matrix(.43887 -.1176 -.1029 -.384 -546.247 518.549)"/>
<path
d="M1496.1 754.362s1.1 1.245 5.03-.764c2.12-1.089 4.61-2.575 7.36-4.269 5.03-3.095 10.86-7.015 16.7-10.891 4.94-3.272 9.75-6.606 14.08-9.636 3.6-2.523 10.09-6.743 10.54-7.052 2.94-2.02 2.37-3.554 2.37-3.554l3.1 5.956s-1.51-1.247-3.91.529c-.44.325-6.85 4.668-10.55 6.999-4.44 2.799-9.37 6.086-14.3 9.369-5.84 3.891-11.7 7.741-16.54 11.206-2.65 1.896-5.09 3.516-6.89 5.201-3.62 3.385-1.83 5.827-1.83 5.827l-5.16-8.921Z"
transform="matrix(.43887 -.1176 -.1029 -.384 -546.247 518.549)"/>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -32,6 +32,7 @@ use App\Http\Controllers\Setup\AccountController;
use App\Http\Controllers\Setup\DatabaseController;
use App\Http\Controllers\Setup\MetaController;
use App\Http\Controllers\Setup\RequirementsController;
use App\Http\Controllers\SocialiteController;
use Illuminate\Support\Facades\Route;
use Rap2hpoutre\LaravelLogViewer\LogViewerController;
@ -70,6 +71,9 @@ Route::get('auth/accept-invite', [RegistrationController::class, 'acceptInvitati
Route::post('auth/register', [RegistrationController::class, 'register'])
->name('auth.register');
Route::get('/auth/oauth/{provider}/redirect', [SocialiteController::class, 'redirect'])->name('auth.oauth.redirect');
Route::get('/auth/oauth/{provider}/callback', [SocialiteController::class, 'callback'])->name('auth.oauth.callback');
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::get('links/feed', [FeedController::class, 'links'])->name('links.feed');
Route::get('lists/feed', [FeedController::class, 'lists'])->name('lists.feed');