Files
ladill-meet/app/Services/Meet/SecurityPolicyService.php
T
isaaccladandCursor 799c302e2a
Deploy Ladill Meet / deploy (push) Successful in 50s
Improve conferences, guest entry, Afia, and cross-app scheduling.
Route guests through silent SSO to the Meet product page, fix Afia context
query, add conference green-room UX and copy, and extend service API for
Care/CRM/Invoice calendar integration.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 20:12:57 +00:00

80 lines
2.4 KiB
PHP

<?php
namespace App\Services\Meet;
use App\Models\Organization;
use App\Models\Room;
use App\Models\User;
use Illuminate\Support\Str;
class SecurityPolicyService
{
public function canJoin(Room $room, ?User $user, ?string $email, ?string $ip = null): array
{
$org = $room->organization;
$policy = $this->mergedPolicy($org, $room);
$kind = $room->isConference() ? 'conference' : 'meeting';
if ($policy['org_only'] && ! $user) {
return [false, "This {$kind} requires a Ladill account."];
}
if ($policy['authenticated_only'] && ! $user) {
return [false, "Please sign in to join this {$kind}."];
}
if (! empty($policy['allowed_domains']) && $email) {
$domain = Str($email)->after('@')->lower()->toString();
$allowed = collect($policy['allowed_domains'])->map(fn ($d) => strtolower(trim($d)))->filter();
if ($allowed->isNotEmpty() && ! $allowed->contains($domain)) {
return [false, "Your email domain is not allowed to join this {$kind}."];
}
}
if ($room->passcode && ! session()->get("meet.passcode.{$room->uuid}")) {
return [false, 'passcode_required'];
}
if ($room->activeSession()?->is_locked && ! $this->isHost($room, $user)) {
return [false, "This {$kind} is locked."];
}
if ($policy['recording_host_only'] && ! $this->isHost($room, $user)) {
// enforced at recording start
}
return [true, null];
}
public function isHost(Room $room, ?User $user): bool
{
return $user && $user->ownerRef() === $room->host_user_ref;
}
/**
* @param array<string, mixed> $policy
*/
public function updateOrganizationPolicy(Organization $org, array $policy): Organization
{
$org->update([
'security_policy' => array_merge($org->security_policy ?? [], $policy),
]);
AuditLogger::record($org->owner_ref, 'organization.security_updated', $org->id, auth()->user()?->ownerRef());
return $org->fresh();
}
/**
* @return array<string, mixed>
*/
protected function mergedPolicy(?Organization $org, Room $room): array
{
return array_merge(
config('meet.security_defaults'),
$org?->security_policy ?? [],
$room->settings['security'] ?? [],
);
}
}