feat: implement tenant OAuth flow and guest achievements

This commit is contained in:
2025-09-25 08:32:37 +02:00
parent ef6203c603
commit b22d91ed32
84 changed files with 5984 additions and 1399 deletions

View File

@@ -108,7 +108,7 @@ class PhotoController extends Controller
'width' => null, // To be filled by image processing
'height' => null,
'status' => 'pending', // Requires moderation
'uploader_id' => $request->user()->id ?? null,
'uploader_id' => null,
'ip_address' => $request->ip(),
'user_agent' => $request->userAgent(),
]);
@@ -170,8 +170,8 @@ class PhotoController extends Controller
]);
// Only tenant admins can moderate
if (isset($validated['status']) && $request->user()->role !== 'admin') {
return response()->json(['error' => 'Insufficient permissions for moderation'], 403);
if (isset($validated['status']) && ! $this->tokenHasScope($request, 'tenant:write')) {
return response()->json(['error' => 'Insufficient scopes'], 403);
}
$photo->update($validated);
@@ -243,7 +243,7 @@ class PhotoController extends Controller
'status' => 'approved',
'moderation_notes' => $request->moderation_notes,
'moderated_at' => now(),
'moderated_by' => $request->user()->id,
'moderated_by' => null,
]);
// Load approved photos for response
@@ -288,7 +288,7 @@ class PhotoController extends Controller
'status' => 'rejected',
'moderation_notes' => $request->moderation_notes,
'moderated_at' => now(),
'moderated_by' => $request->user()->id,
'moderated_by' => null,
]);
// Optionally delete rejected photos from storage
@@ -369,6 +369,17 @@ class PhotoController extends Controller
]);
}
private function tokenHasScope(Request $request, string $scope): bool
{
$scopes = $request->user()->scopes ?? ($request->attributes->get('decoded_token')['scopes'] ?? []);
if (! is_array($scopes)) {
$scopes = array_values(array_filter(explode(' ', (string) $scopes)));
}
return in_array($scope, $scopes, true);
}
/**
* Generate presigned S3 URL for direct upload (alternative to local storage)
*/
@@ -467,4 +478,10 @@ class PhotoController extends Controller
'status' => 'pending',
], 201);
}
}
}