feat: owner read-only view-as from team users table
Allow org owners to inspect any member's data scope via dual JWT; server blocks mutations and team page stays reachable for return. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -102,6 +102,12 @@ const loadedAvatars = new Set<string>();
|
||||
const canInvite = computed(() => canManageUsers(auth.user?.role));
|
||||
const canEditOrg = computed(() => canManageSettings(auth.user?.role));
|
||||
const canEditRoles = computed(() => canManageUsers(auth.user?.role));
|
||||
/** مالک واقعی میتواند از جدول کاربران وارد مشاهده شود / برگردد */
|
||||
const canViewAsUsers = computed(
|
||||
() =>
|
||||
auth.user?.role === 'owner' || Boolean(auth.user?.viewAs?.canOpenTeamSettings),
|
||||
);
|
||||
const viewAsBusy = ref(false);
|
||||
|
||||
const selectedRole = computed(
|
||||
() => roles.value.find((r) => r.id === selectedRoleId.value) ?? null,
|
||||
@@ -232,8 +238,38 @@ function pickRole(id: string) {
|
||||
menuUserId.value = null;
|
||||
}
|
||||
|
||||
function onUserActivate(user: OrgUserDto) {
|
||||
if (user.orgRoleId) pickRole(user.orgRoleId);
|
||||
async function onUserActivate(user: OrgUserDto) {
|
||||
if (!canViewAsUsers.value) {
|
||||
if (user.orgRoleId) pickRole(user.orgRoleId);
|
||||
return;
|
||||
}
|
||||
const impersonatorId = auth.user?.viewAs?.impersonatorId;
|
||||
if (impersonatorId && user.id === impersonatorId) {
|
||||
await switchViewAs(user.id);
|
||||
return;
|
||||
}
|
||||
if (user.id === auth.user?.id) {
|
||||
if (user.orgRoleId) pickRole(user.orgRoleId);
|
||||
return;
|
||||
}
|
||||
await switchViewAs(user.id);
|
||||
}
|
||||
|
||||
async function switchViewAs(targetUserId: string) {
|
||||
if (viewAsBusy.value) return;
|
||||
viewAsBusy.value = true;
|
||||
error.value = '';
|
||||
ok.value = '';
|
||||
try {
|
||||
await auth.viewAs(targetUserId);
|
||||
ok.value = auth.user?.viewAs
|
||||
? `در حال مشاهده بهجای ${auth.user.fullName}`
|
||||
: 'به حساب خودتان برگشتید.';
|
||||
} catch (e) {
|
||||
error.value = apiError(e, 'تغییر حالت مشاهده ناموفق بود.');
|
||||
} finally {
|
||||
viewAsBusy.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function formatLastLogin(iso: string | null | undefined) {
|
||||
|
||||
Reference in New Issue
Block a user