Skip to content

Commit

Permalink
fix: Group Members fixes (#1445)
Browse files Browse the repository at this point in the history
Fixed usage of permission policies
Updated tests
Setup logic to automaitcally do the only action sheet option if available
  • Loading branch information
alexrisch authored Jan 2, 2025
1 parent 0bd5d13 commit 1f3ce1f
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 64 deletions.
4 changes: 4 additions & 0 deletions components/StateHandlers/ActionSheetStateHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export default function ActionSheetStateHandler() {
options: ActionSheetOptions,
callback: (i?: number | undefined) => void | Promise<void>
) => {
if (options.options.length === 1) {
callback(0);
return;
}
useAppStore.getState().setActionSheetShown(true);
_showActionSheetWithOptions(options, (i?: number | undefined) => {
useAppStore.getState().setActionSheetShown(false);
Expand Down
16 changes: 12 additions & 4 deletions containers/GroupScreenMembersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { actionSheetColors, textSecondaryColor } from "@styles/colors";
import {
getAccountIsAdmin,
getAccountIsSuperAdmin,
getAddressIsAdmin,
getAddressIsSuperAdmin,
} from "@utils/groupUtils/adminUtils";
import { getGroupMemberActions } from "@utils/groupUtils/getGroupMemberActions";
Expand Down Expand Up @@ -77,6 +78,11 @@ export const GroupScreenMembersTable: FC<GroupScreenMembersTableProps> = memo(
[currentAccount, members]
);

const currentAccountIsAdmin = useMemo(
() => getAddressIsAdmin(members, currentAccount),
[currentAccount, members]
);

const tableViewItems = useMemo(() => {
const items: TableViewItemType[] = [];

Expand All @@ -103,13 +109,14 @@ export const GroupScreenMembersTable: FC<GroupScreenMembersTableProps> = memo(
revokeSuperAdminIndex,
removeIndex,
destructiveButtonIndex,
} = getGroupMemberActions(
groupPermissionPolicy,
} = getGroupMemberActions({
groupPermissionLevel: groupPermissionPolicy,
isCurrentUser,
isSuperAdmin,
isAdmin,
currentAccountIsSuperAdmin
);
currentAccountIsSuperAdmin,
currentAccountIsAdmin,
});
showActionSheetWithOptions(
{
options,
Expand Down Expand Up @@ -201,6 +208,7 @@ export const GroupScreenMembersTable: FC<GroupScreenMembersTableProps> = memo(
colorScheme,
currentAccount,
currentAccountIsSuperAdmin,
currentAccountIsAdmin,
groupPermissionPolicy,
mappedData,
members,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function ChatGroupMemberLeft({ inboxId }: IChatGroupMemberLeftProps) {
<ChatGroupUpdateText weight="bold">{readableName} </ChatGroupUpdateText>
</Pressable>
<ChatGroupUpdateText>
{translate("group_member_joined")}
{translate("group_member_left")}
</ChatGroupUpdateText>
</HStack>
);
Expand Down
92 changes: 49 additions & 43 deletions utils/groupUtils/getGroupMemberActions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,85 +3,91 @@ import { getGroupMemberActions } from "./getGroupMemberActions";

describe("getGroupMemberActions", () => {
test("should return correct actions when user can promote to admin", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Promote to admin");
});

test("should return correct actions when user can promote to super admin", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Promote to super admin");
});

test("should return correct actions when user can revoke admin", () => {
const result = getGroupMemberActions(
{
addAdminPolicy: "allow",
const result = getGroupMemberActions({
groupPermissionLevel: {
removeAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
true, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: true,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Revoke admin");
});

test("should return correct actions when user can revoke super admin", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
true, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: true,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Revoke super admin");
});

test("should return correct actions when user can remove from group", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
removeMemberPolicy: "allow",
} as PermissionPolicySet,
false, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: false,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).toContain("Remove from group");
});

test("should not include admin actions for the current user", () => {
const result = getGroupMemberActions(
{
const result = getGroupMemberActions({
groupPermissionLevel: {
addAdminPolicy: "allow",
} as PermissionPolicySet,
true, // isCurrentUser
false, // isSuperAdmin
false, // isAdmin
true // currentAccountIsSuperAdmin
);
isCurrentUser: true,
isSuperAdmin: false,
isAdmin: false,
currentAccountIsSuperAdmin: true,
currentAccountIsAdmin: true,
});

expect(result.options).not.toContain("Promote to admin");
expect(result.options).not.toContain("Promote to super admin");
Expand Down
54 changes: 41 additions & 13 deletions utils/groupUtils/getGroupMemberActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,57 @@ import { translate } from "@i18n";
import { PermissionPolicySet } from "@xmtp/react-native-sdk/build/lib/types/PermissionPolicySet";
import { userCanDoGroupActions } from "./userCanDoGroupActions";

export const getGroupMemberActions = (
groupPermissionLevel: PermissionPolicySet | undefined,
isCurrentUser: boolean,
isSuperAdmin: boolean,
isAdmin: boolean,
currentAccountIsSuperAdmin: boolean
) => {
type GetGroupMemberActionsProps = {
groupPermissionLevel: PermissionPolicySet | undefined;
isCurrentUser: boolean;
isSuperAdmin: boolean;
isAdmin: boolean;
currentAccountIsSuperAdmin: boolean;
currentAccountIsAdmin: boolean;
};

export const getGroupMemberActions = ({
groupPermissionLevel,
isCurrentUser,
isSuperAdmin,
isAdmin,
currentAccountIsSuperAdmin,
currentAccountIsAdmin,
}: GetGroupMemberActionsProps) => {
const canRemove =
!isCurrentUser &&
userCanDoGroupActions(
groupPermissionLevel,
"removeMemberPolicy",
isSuperAdmin,
isAdmin
currentAccountIsSuperAdmin,
currentAccountIsAdmin
);
const canPromoteToSuperAdmin =
currentAccountIsSuperAdmin && !isSuperAdmin && !isCurrentUser;
!isSuperAdmin && !isCurrentUser && currentAccountIsSuperAdmin;
const canPromoteToAdmin =
!isCurrentUser && currentAccountIsSuperAdmin && !isAdmin && !isSuperAdmin;
!isCurrentUser &&
!isAdmin &&
!isSuperAdmin &&
userCanDoGroupActions(
groupPermissionLevel,
"addAdminPolicy",
currentAccountIsSuperAdmin,
currentAccountIsAdmin
);

const canRevokeAdmin =
!isCurrentUser && currentAccountIsSuperAdmin && isAdmin && !isSuperAdmin;
!isCurrentUser &&
isAdmin &&
!isSuperAdmin &&
userCanDoGroupActions(
groupPermissionLevel,
"removeAdminPolicy",
currentAccountIsSuperAdmin,
currentAccountIsAdmin
);
const canRevokeSuperAdmin =
!isCurrentUser && currentAccountIsSuperAdmin && isSuperAdmin;
const options = ["Profile page"];
const options = [translate("group_screen_member_actions.profile_page")];
let cancelButtonIndex = 1;
let promoteAdminIndex: number | undefined = undefined;
if (canPromoteToAdmin) {
Expand Down Expand Up @@ -54,6 +81,7 @@ export const getGroupMemberActions = (
cancelButtonIndex++;
}
let removeIndex: number | undefined = undefined;

if (canRemove) {
removeIndex = options.length;
options.push(translate("group_screen_member_actions.remove_member"));
Expand Down
6 changes: 3 additions & 3 deletions utils/groupUtils/userCanDoGroupActions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PermissionPolicySet } from "@xmtp/react-native-sdk/build/lib/types/PermissionPolicySet";

type MemberRole = "admin" | "super_admin" | "member";
type MemberRole = "admin" | "superAdmin" | "member";

type GetMemberRoleParams = {
isSuperAdmin: boolean;
Expand All @@ -11,7 +11,7 @@ const getMemberRole = ({
isSuperAdmin,
isAdmin,
}: GetMemberRoleParams): MemberRole => {
if (isSuperAdmin) return "super_admin";
if (isSuperAdmin) return "superAdmin";
if (isAdmin) return "admin";
return "member";
};
Expand All @@ -29,7 +29,7 @@ export const userCanDoGroupActions = (
if (policy === "deny") return false;
if (
policy === "admin" &&
(memberRole === "admin" || memberRole === "super_admin")
(memberRole === "admin" || memberRole === "superAdmin")
)
return true;
if (policy === memberRole) return true;
Expand Down

0 comments on commit 1f3ce1f

Please sign in to comment.