feat: google login
CI / 🧪 Tests Laravel (push) Failing after 9s
CI / 🐳 Build & Push Images (push) Has been skipped

This commit is contained in:
2026-08-17 10:06:35 +02:00
parent c0688044e8
commit ddc80956a0
22 changed files with 1886 additions and 6 deletions
+102
View File
@@ -1,15 +1,41 @@
<?php
use App\Enums\SocialProvider;
use App\Models\MealPosts;
use App\Models\SocialAccount;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Client\Request as ClientRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Laravel\Sanctum\Sanctum;
uses(RefreshDatabase::class);
function configureDeletionAppleOAuthClient(): void
{
$key = openssl_pkey_new([
'curve_name' => 'prime256v1',
'private_key_type' => OPENSSL_KEYTYPE_EC,
]);
if ($key === false || ! openssl_pkey_export($key, $privateKey)) {
throw new RuntimeException('Unable to generate an Apple OAuth test key.');
}
config()->set([
'services.apple.client_id' => 'com.meal.daily',
'services.apple.issuer' => 'https://appleid.apple.com',
'services.apple.key_id' => 'APPLEKEY1',
'services.apple.private_key' => $privateKey,
'services.apple.private_key_base64' => null,
'services.apple.revoke_url' => 'https://appleid.apple.com/auth/revoke',
'services.apple.team_id' => 'TEAMID1234',
]);
}
it('deletes the authenticated account and related data', function () {
config()->set('filesystems.default', 's3');
@@ -81,3 +107,79 @@ it('requires authentication to delete an account', function () {
$this->deleteJson('/api/auth/me')
->assertUnauthorized();
});
it('revokes the Apple refresh token before deleting the account', function () {
configureDeletionAppleOAuthClient();
Http::preventStrayRequests();
Http::fake([
'https://appleid.apple.com/auth/revoke' => Http::response(status: 200),
]);
$user = User::factory()->create();
$socialAccount = SocialAccount::factory()->for($user)->create([
'provider' => SocialProvider::Apple,
'provider_refresh_token' => 'apple-refresh-token',
]);
Sanctum::actingAs($user);
$this->deleteJson('/api/auth/me')
->assertOk()
->assertJsonPath('code', 'ACCOUNT_DELETED');
Http::assertSent(function (ClientRequest $request): bool {
$data = $request->data();
return $request->url() === 'https://appleid.apple.com/auth/revoke'
&& $request->isForm()
&& ($data['client_id'] ?? null) === 'com.meal.daily'
&& ($data['token'] ?? null) === 'apple-refresh-token'
&& ($data['token_type_hint'] ?? null) === 'refresh_token'
&& is_string($data['client_secret'] ?? null);
});
$this->assertModelMissing($user);
$this->assertModelMissing($socialAccount);
});
it('keeps the account when Apple token revocation fails', function () {
configureDeletionAppleOAuthClient();
Http::preventStrayRequests();
Http::fake([
'https://appleid.apple.com/auth/revoke' => Http::response([
'error' => 'invalid_client',
], 400),
]);
$user = User::factory()->create();
$socialAccount = SocialAccount::factory()->for($user)->create([
'provider' => SocialProvider::Apple,
'provider_refresh_token' => 'apple-refresh-token',
]);
Sanctum::actingAs($user);
$this->deleteJson('/api/auth/me')
->assertServiceUnavailable()
->assertJsonPath('code', 'SOCIAL_REVOCATION_FAILED');
$this->assertModelExists($user);
$this->assertModelExists($socialAccount);
expect($socialAccount->fresh()->provider_refresh_token)->toBe('apple-refresh-token');
});
it('keeps an Apple account that has no refresh token', function () {
$user = User::factory()->create();
$socialAccount = SocialAccount::factory()->for($user)->create([
'provider' => SocialProvider::Apple,
'provider_refresh_token' => null,
]);
Sanctum::actingAs($user);
$this->deleteJson('/api/auth/me')
->assertConflict()
->assertJsonPath('code', 'SOCIAL_REVOCATION_TOKEN_MISSING');
$this->assertModelExists($user);
$this->assertModelExists($socialAccount);
});