Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function up(): void
Schema::create('interactions', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignUuid('character_id')->constrained('characters');
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->string('type');
$table->string('provider');
$table->string('value_tier');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ public function up(): void
{
if (!Schema::hasColumn('messages', 'tenant_id')) {
Schema::table('messages', function (Blueprint $table): void {
$table->foreignId('tenant_id')->nullable()->after('id')->constrained('tenants');
$table->foreignUuid('tenant_id')->nullable()->after('id')->constrained('tenants');
});
}

if (!Schema::hasColumn('voice_messages', 'tenant_id')) {
Schema::table('voice_messages', function (Blueprint $table): void {
$table->foreignId('tenant_id')->nullable()->after('id')->constrained('tenants');
$table->foreignUuid('tenant_id')->nullable()->after('id')->constrained('tenants');
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public function up(): void
{
Schema::create('moderation_events', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->foreignUuid('external_identity_id')->nullable()->constrained('external_identities');
$table->foreignUuid('moderator_identity_id')->nullable()->constrained('external_identities');
$table->string('type');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public function up(): void
{
Schema::create('activity_reactions', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->uuidMorphs('reactable');

$table->string('emoji_key', 128);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public function up(): void
{
Schema::create('message_mentions', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->foreignUuid('message_id')->constrained('messages')->cascadeOnDelete();
$table->foreignUuid('mentioned_identity_id')->nullable()->constrained('external_identities');
$table->string('mentioned_provider_account_id');
Expand All @@ -36,7 +36,7 @@ public function up(): void

Schema::create('message_threads', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->foreignUuid('message_id')->constrained('messages')->cascadeOnDelete();
$table->string('provider_thread_id');
$table->string('name')->nullable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function up(): void
{
Schema::create('message_attachments', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->foreignUuid('message_id')->constrained('messages')->cascadeOnDelete();
$table->string('provider_attachment_id')->nullable();
$table->text('url');
Expand All @@ -29,7 +29,7 @@ public function up(): void

Schema::create('message_embeds', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->foreignUuid('message_id')->constrained('messages')->cascadeOnDelete();
$table->text('url')->nullable();
$table->text('title')->nullable();
Expand All @@ -48,7 +48,7 @@ public function up(): void

Schema::create('membership_events', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignId('tenant_id')->constrained('tenants');
$table->foreignUuid('tenant_id')->constrained('tenants');
$table->foreignUuid('external_identity_id')->constrained('external_identities');
$table->string('kind');
$table->timestamp('occurred_at');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

declare(strict_types=1);

use He4rt\Identity\Tenant\Models\Tenant;
use He4rt\Identity\User\Models\User;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Expand All @@ -14,8 +12,8 @@ public function up(): void
{
Schema::create('activity_timeline', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignIdFor(User::class, 'user_id');
$table->foreignIdFor(Tenant::class, 'tenant_id');
$table->foreignUuid('user_id');
$table->foreignUuid('tenant_id');
$table->uuidMorphs('postable');
$table->foreignUuid('root_id')->nullable();
$table->foreignUuid('parent_id')->nullable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

declare(strict_types=1);

use He4rt\Identity\User\Models\User;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Expand All @@ -12,10 +11,10 @@
public function up(): void
{
Schema::create('tenants', function (Blueprint $table): void {
$table->id();
$table->uuid('id')->primary();
$table->string('name');
$table->string('slug');
$table->foreignIdFor(User::class, 'owner_id')->constrained('users');
$table->foreignUuid('owner_id')->constrained('users');
$table->boolean('active');
$table->timestamps();
$table->softDeletes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function up(): void

foreach ($tables as $table => $indexableColumns) {
Schema::table($table, function (Blueprint $table) use ($indexableColumns): void {
$table->foreignId('tenant_id')
$table->foreignUuid('tenant_id')
->after('id')
->constrained('tenants')
->nullOnDelete();
Expand All @@ -36,12 +36,7 @@ public function up(): void
}
});
}

}

public function down(): void
{
// Don't listen to the haters
// Schema::dropIfExists('tenant');
}
public function down(): void {}
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public function up(): void
{
Schema::create('tenant_users', function (Blueprint $table): void {
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
$table->foreignUuid('tenant_id')->constrained('tenants')->cascadeOnDelete();
$table->foreignUuid('user_id')->constrained('users')->cascadeOnDelete();
$table->timestamps();
});
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public function execute(User|Tenant $owner, Tenant $tenant, OAuthUserDTO $oauthU
'username' => $oauthUser->username,
]),
'connected_at' => now(),
'disconnected_at' => null,
'connected_by' => auth()->id(),
]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ public static function tenantNotFound(string $identifier): self
{
return new self(sprintf('Tenant "%s" not found.', $identifier));
}

public static function tokenExchangeFailed(string $provider, string $error): self
{
return new self(sprintf('Token exchange failed for "%s": %s', $provider, $error));
}
}
28 changes: 26 additions & 2 deletions app-modules/identity/src/Auth/Http/Controllers/OAuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
use He4rt\Identity\Auth\Actions\HandleOAuthCallbackAction;
use He4rt\Identity\Auth\DTOs\OAuthStateDTO;
use He4rt\Identity\Auth\Enums\OAuthIntent;
use He4rt\Identity\Auth\Exceptions\OAuthFlowException;
use He4rt\Identity\ExternalIdentity\Enums\IdentityProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use RuntimeException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

final class OAuthController extends Controller
Expand All @@ -22,7 +25,13 @@ public function getRedirect(string $tenant, string $panel, string $provider): Re

throw_if($identityProvider === null, NotFoundHttpException::class);

$client = $identityProvider->getClient();
try {
$client = $identityProvider->getClient();
} catch (RuntimeException $runtimeException) {
Log::warning('OAuth client not configured', ['provider' => $provider, 'error' => $runtimeException->getMessage()]);

return redirect()->to('/');
}

throw_unless($client instanceof OAuthClientContract, NotFoundHttpException::class);

Expand All @@ -45,7 +54,22 @@ public function getAuthenticate(string $provider, HandleOAuthCallbackAction $act

$state = OAuthStateDTO::fromEncryptedString(request()->input('state'));

$result = $action->execute($state, $identityProvider, request()->input('code'));
$code = request()->input('code');
$oauthDenied = $code === null || request()->has('error');

if ($oauthDenied) {
$fallbackUrl = $state->returnUrl ?? '/';

return redirect()->to($fallbackUrl);
}
Comment thread
danielhe4rt marked this conversation as resolved.

try {
$result = $action->execute($state, $identityProvider, $code);
} catch (OAuthFlowException $oAuthFlowException) {
Log::warning('OAuth flow failed', ['provider' => $provider, 'error' => $oAuthFlowException->getMessage()]);

return redirect()->to($state->returnUrl ?? '/');
}
Comment thread
danielhe4rt marked this conversation as resolved.

if ($result->hasMergeConflict()) {
session()->put('oauth_merge_pending', $result->mergeConflict->toSession());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function up(): void
{
Schema::create('discord_guilds', function (Blueprint $table): void {
$table->id();
$table->foreignId('tenant_id')->nullable()->constrained('tenants')->nullOnDelete();
$table->foreignUuid('tenant_id')->nullable()->constrained('tenants')->nullOnDelete();
$table->string('discord_guild_id')->unique();
$table->string('name');
$table->string('icon')->nullable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use He4rt\Identity\Auth\DTOs\OAuthAccessDTO;
use He4rt\Identity\Auth\DTOs\OAuthStateDTO;
use He4rt\Identity\Auth\DTOs\OAuthUserDTO;
use He4rt\Identity\Auth\Exceptions\OAuthFlowException;
use He4rt\IntegrationDiscord\Transport\DiscordOAuthConnector;
use He4rt\IntegrationDiscord\Transport\Requests\OAuth\ExchangeCodeForToken;
use He4rt\IntegrationDiscord\Transport\Requests\OAuth\GetCurrentUser;
Expand Down Expand Up @@ -38,7 +39,14 @@ public function auth(string $code): OAuthAccessDTO
redirectUri: $this->callbackUrl(),
));

return DiscordOAuthAccessDTO::make($response->json());
$payload = $response->json();
$tokenExchangeFailed = !isset($payload['access_token']);

if ($tokenExchangeFailed) {
throw OAuthFlowException::tokenExchangeFailed('discord', $payload['error'] ?? 'unknown');
}

return DiscordOAuthAccessDTO::make($payload);
}

public function getAuthenticatedUser(OAuthAccessDTO $credentials): OAuthUserDTO
Expand Down
Loading