feat: make user owner
fix: ownership check
This commit is contained in:
parent
ea0a9763bf
commit
f931ebece8
@ -16,6 +16,11 @@ public function makeAdmin()
|
||||
$this->dispatch('reloadWindow');
|
||||
}
|
||||
|
||||
public function makeOwner()
|
||||
{
|
||||
$this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'owner']);
|
||||
$this->dispatch('reloadWindow');
|
||||
}
|
||||
public function makeReadonly()
|
||||
{
|
||||
$this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'member']);
|
||||
@ -26,7 +31,7 @@ public function remove()
|
||||
{
|
||||
$this->member->teams()->detach(currentTeam());
|
||||
Cache::forget("team:{$this->member->id}");
|
||||
Cache::remember('team:' . $this->member->id, 3600, function() {
|
||||
Cache::remember('team:' . $this->member->id, 3600, function () {
|
||||
return $this->member->teams()->first();
|
||||
});
|
||||
$this->dispatch('reloadWindow');
|
||||
|
@ -67,7 +67,7 @@ public function createToken(string $name, array $abilities = ['*'], DateTimeInte
|
||||
'team_id' => session('currentTeam')->id
|
||||
]);
|
||||
|
||||
return new NewAccessToken($token, $token->getKey().'|'.$plainTextToken);
|
||||
return new NewAccessToken($token, $token->getKey() . '|' . $plainTextToken);
|
||||
}
|
||||
public function teams()
|
||||
{
|
||||
@ -103,9 +103,13 @@ public function sendPasswordResetNotification($token): void
|
||||
|
||||
public function isAdmin()
|
||||
{
|
||||
return data_get($this->pivot, 'role') === 'admin' || data_get($this->pivot, 'role') === 'owner';
|
||||
return $this->role() === 'admin' || $this->role() === 'owner';
|
||||
}
|
||||
|
||||
public function isOwner()
|
||||
{
|
||||
return $this->role() === 'owner';
|
||||
}
|
||||
public function isAdminFromSession()
|
||||
{
|
||||
if (auth()->user()->id === 0) {
|
||||
@ -155,6 +159,6 @@ public function otherTeams()
|
||||
|
||||
public function role()
|
||||
{
|
||||
return session('currentTeam')->pivot->role;
|
||||
return auth()->user()->teams->where('id', currentTeam()->id)->first()->pivot->role;
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,55 @@
|
||||
<div>
|
||||
@if ($invitations->count() > 0)
|
||||
<h4 class="pb-2">Pending Invitations</h4>
|
||||
<div class="overflow-x-auto">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Via</th>
|
||||
<th>Role</th>
|
||||
<th>Invitation Link</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody x-data>
|
||||
@foreach ($invitations as $invite)
|
||||
<tr>
|
||||
<td>{{ $invite->email }}</td>
|
||||
<td>{{ $invite->via }}</td>
|
||||
<td>{{ $invite->role }}</td>
|
||||
<td class="flex gap-2" x-data="checkProtocol">
|
||||
<template x-if="isHttps">
|
||||
<x-forms.button x-on:click="copyToClipboard('{{ $invite->link }}')">Copy Invitation
|
||||
Link</x-forms.button>
|
||||
</template>
|
||||
<x-forms.input id="null" type="password" value="{{ $invite->link }}" />
|
||||
</td>
|
||||
<td>
|
||||
<x-forms.button wire:click.prevent='deleteInvitation({{ $invite->id }})'>Revoke
|
||||
Invitation
|
||||
</x-forms.button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<h2 class="pb-2">Pending Invitations</h2>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="inline-block min-w-full">
|
||||
<div class="overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-coolgray-400">
|
||||
<thead>
|
||||
<tr class="text-neutral-500">
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Email
|
||||
</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">
|
||||
Via</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Role</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Invitation Link
|
||||
</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-coolgray-400">
|
||||
@foreach ($invitations as $invite)
|
||||
<tr class="text-white bg-coolblack hover:bg-coolgray-100/40">
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">{{ $invite->email }}</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">{{ $invite->via }}</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">{{ $invite->role }}</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap" x-data="checkProtocol">
|
||||
<template x-if="isHttps">
|
||||
<x-forms.button
|
||||
x-on:click="copyToClipboard('{{ $invite->link }}')">Copy
|
||||
Invitation
|
||||
Link</x-forms.button>
|
||||
</template>
|
||||
<x-forms.input id="null" type="password"
|
||||
value="{{ $invite->link }}" />
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
<x-forms.button
|
||||
wire:click.prevent='deleteInvitation({{ $invite->id }})'>Revoke
|
||||
Invitation
|
||||
</x-forms.button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<form wire:submit='viaLink' class="flex items-center gap-2">
|
||||
<x-forms.input id="email" type="email" name="email" placeholder="Email" />
|
||||
<x-forms.select id="role" name="role">
|
||||
<option value="owner">Owner</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="member">Member</option>
|
||||
</x-forms.select>
|
||||
|
@ -1,25 +1,47 @@
|
||||
<tr>
|
||||
<td>
|
||||
{{ $member->name }}</th>
|
||||
<td>{{ $member->email }}</td>
|
||||
<td>
|
||||
{{ data_get($member, 'pivot.role') }}</td>
|
||||
<td>
|
||||
{{-- TODO: This is not good --}}
|
||||
<tr @class([
|
||||
'text-white bg-coolblack hover:bg-coolgray-100',
|
||||
'bg-coolgray-100' => $member->id == auth()->user()->id,
|
||||
])>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ $member->name }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ $member->email }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
{{ data_get($member, 'pivot.role') }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm whitespace-nowrap">
|
||||
@if (auth()->user()->isAdminFromSession())
|
||||
@if ($member->id !== auth()->user()->id)
|
||||
@if (data_get($member, 'pivot.role') !== 'owner')
|
||||
@if (data_get($member, 'pivot.role') !== 'admin')
|
||||
<x-forms.button wire:click="makeAdmin">Convert to Admin</x-forms.button>
|
||||
@else
|
||||
<x-forms.button wire:click="makeReadonly">Convert to Member</x-forms.button>
|
||||
@if (auth()->user()->isOwner())
|
||||
@if (data_get($member, 'pivot.role') === 'owner')
|
||||
<x-forms.button wire:click="makeAdmin">To Admin</x-forms.button>
|
||||
<x-forms.button wire:click="makeReadonly">To Member</x-forms.button>
|
||||
<x-forms.button isError wire:click="remove">Remove</x-forms.button>
|
||||
@endif
|
||||
@if (data_get($member, 'pivot.role') === 'admin')
|
||||
<x-forms.button wire:click="makeOwner">To Owner</x-forms.button>
|
||||
<x-forms.button wire:click="makeReadonly">To Member</x-forms.button>
|
||||
<x-forms.button isError wire:click="remove">Remove</x-forms.button>
|
||||
@endif
|
||||
@if (data_get($member, 'pivot.role') === 'member')
|
||||
<x-forms.button wire:click="makeOwner">To Owner</x-forms.button>
|
||||
<x-forms.button wire:click="makeAdmin">To Admin</x-forms.button>
|
||||
<x-forms.button isError wire:click="remove">Remove</x-forms.button>
|
||||
@endif
|
||||
@elseif (auth()->user()->isAdmin())
|
||||
@if (data_get($member, 'pivot.role') === 'admin')
|
||||
<x-forms.button wire:click="makeReadonly">To Member</x-forms.button>
|
||||
<x-forms.button isError wire:click="remove">Remove</x-forms.button>
|
||||
@endif
|
||||
@if (data_get($member, 'pivot.role') === 'member')
|
||||
<x-forms.button wire:click="makeAdmin">To Admin</x-forms.button>
|
||||
<x-forms.button isError wire:click="remove">Remove</x-forms.button>
|
||||
@endif
|
||||
<x-forms.button wire:click="remove">Remove</x-forms.button>
|
||||
@else
|
||||
<x-forms.button disabled>Remove</x-forms.button>
|
||||
@endif
|
||||
@else
|
||||
<x-forms.button disabled>Remove</x-forms.button>
|
||||
<div class="text-neutral-500">(This is you)</div>
|
||||
@endif
|
||||
@endif
|
||||
</td>
|
||||
|
@ -1,29 +1,39 @@
|
||||
<div>
|
||||
<x-team.navbar />
|
||||
<h2>Members</h2>
|
||||
<div class="pt-4 overflow-hidden">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (currentTeam()->members->sortBy('name') as $member)
|
||||
<livewire:team.member :member="$member" :wire:key="$member->id" />
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="inline-block min-w-full">
|
||||
<div class="overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-coolgray-400">
|
||||
<thead>
|
||||
<tr class="text-neutral-500">
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Name
|
||||
</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Email</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Role</th>
|
||||
<th class="px-5 py-3 text-xs font-medium text-left uppercase">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-coolgray-400">
|
||||
@foreach (currentTeam()->members as $member)
|
||||
<livewire:team.member :member="$member" :wire:key="$member->id" />
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (auth()->user()->isAdminFromSession())
|
||||
<div class="py-4">
|
||||
@if (is_transactional_emails_active())
|
||||
<h3 class="pb-4">Invite a new member</h3>
|
||||
<h2 class="pb-4">Invite New Member</h2>
|
||||
@else
|
||||
<h3>Invite a new member</h3>
|
||||
<h2>Invite New Member</h2>
|
||||
@if (isInstanceAdmin())
|
||||
<div class="pb-4 text-xs text-warning">You need to configure (as root team) <a href="/settings#smtp"
|
||||
class="underline text-warning">Transactional
|
||||
|
Loading…
Reference in New Issue
Block a user