Skip to content

Commit c668beb

Browse files
committed
refactor: change selectors name, fix translation paths, remove unneccessary comments, pull proper data about users domain security groups
1 parent 7d68350 commit c668beb

8 files changed

Lines changed: 46 additions & 31 deletions

File tree

src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ const OPTIONS_PER_SCREEN: Partial<Record<Screen, PlatformStackNavigationOptions>
119119
[SCREENS.TWO_FACTOR_AUTH.SUCCESS]: {
120120
animationTypeForReplace: 'push',
121121
},
122-
// Opened via forceReplace from the add domain page, so it needs a forward (push) transition instead of the default reversed (pop) one.
123122
[SCREENS.WORKSPACES_DOMAIN_ALREADY_EXISTS]: {
124123
animationTypeForReplace: 'push',
125124
},

src/pages/domain/AddDomainPage.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {getFieldRequiredErrors, isPublicDomain} from '@libs/ValidationUtils';
2020

2121
import ONYXKEYS from '@src/ONYXKEYS';
2222
import ROUTES from '@src/ROUTES';
23-
import {hasDomainAccessSelector} from '@src/selectors/Domain';
23+
import {hasDomainAccess} from '@src/selectors/Domain';
2424
import {accountIDSelector} from '@src/selectors/Session';
2525
import INPUT_IDS from '@src/types/form/CreateDomainForm';
2626

@@ -35,6 +35,7 @@ function AddDomainPage() {
3535
const [currentUserAccountID] = useOnyx(ONYXKEYS.SESSION, {selector: accountIDSelector});
3636
const [form] = useOnyx(ONYXKEYS.FORMS.CREATE_DOMAIN_FORM);
3737
const [allDomains] = useOnyx(ONYXKEYS.COLLECTION.DOMAIN);
38+
const [myDomainSecurityGroups] = useOnyx(ONYXKEYS.MY_DOMAIN_SECURITY_GROUPS);
3839

3940
const validate = useCallback(
4041
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.CREATE_DOMAIN_FORM>) => {
@@ -84,13 +85,13 @@ function AddDomainPage() {
8485
return;
8586
}
8687

87-
if (!!currentUserAccountID && hasDomainAccessSelector(currentUserAccountID)(existingDomain)) {
88+
if (!!currentUserAccountID && hasDomainAccess(currentUserAccountID, myDomainSecurityGroups)(existingDomain)) {
8889
setCreateDomainAlreadyHaveAccessError();
8990
return;
9091
}
9192

9293
Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.navigate(ROUTES.WORKSPACES_DOMAIN_ALREADY_EXISTS.getRoute(domainAccountID), {forceReplace: true}));
93-
}, [form?.domainAccountID, allDomains, currentUserAccountID]);
94+
}, [form?.domainAccountID, allDomains, currentUserAccountID, myDomainSecurityGroups]);
9495

9596
useEffect(() => {
9697
return () => {

src/pages/domain/DomainAlreadyExistsPage.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,11 @@ function DomainAlreadyExistsPage({route}: DomainAlreadyExistsPageProps) {
4545
description={translate('domain.domainAlreadyExists.description')}
4646
descriptionStyle={styles.textSupporting}
4747
shouldShowSecondaryButton
48-
secondaryButtonText={translate('domain.domainAlreadyExists.neverMind')}
48+
secondaryButtonText={translate('domain.common.neverMind')}
4949
onSecondaryButtonPress={goToDomainsList}
5050
shouldShowButton
5151
buttonText={translate('domain.domainAlreadyExists.requestAccess')}
5252
onButtonPress={() => {
53-
// TODO: call the BE "request domain admin access" endpoint for domainAccountID once it exists.
5453
goToDomainsList();
5554
}}
5655
/>

src/pages/domain/DomainsListPage.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type {DomainRowData} from '@components/Tables/DomainListTable';
44
import DomainListTable from '@components/Tables/DomainListTable';
55
import WorkspaceListLayout from '@components/WorkspaceListLayout';
66

7-
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
87
import useDocumentTitle from '@hooks/useDocumentTitle';
98
import {useIsAppLoadPending} from '@hooks/useInFlightRequests';
109
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
@@ -20,7 +19,8 @@ import Navigation from '@libs/Navigation/Navigation';
2019
import CONST from '@src/CONST';
2120
import ONYXKEYS from '@src/ONYXKEYS';
2221
import ROUTES from '@src/ROUTES';
23-
import {hasDomainAccessSelector, isAdminSelector} from '@src/selectors/Domain';
22+
import {hasDomainAccess, isAdminSelector} from '@src/selectors/Domain';
23+
import {accountIDSelector} from '@src/selectors/Session';
2424
import {isEmptyObject} from '@src/types/utils/EmptyObject';
2525

2626
import {Str} from 'expensify-common';
@@ -32,13 +32,14 @@ function DomainsListPage() {
3232
const {isOffline} = useNetwork();
3333
const {translate} = useLocalize();
3434
const icons = useMemoizedLazyExpensifyIcons(['Plus']);
35-
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
3635

3736
useDocumentTitle(translate('common.domains'));
3837

3938
const isAppLoadPending = useIsAppLoadPending();
39+
const [currentUserAccountID] = useOnyx(ONYXKEYS.SESSION, {selector: accountIDSelector});
4040
const [allDomains] = useOnyx(ONYXKEYS.COLLECTION.DOMAIN);
4141
const [allDomainErrors] = useOnyx(ONYXKEYS.COLLECTION.DOMAIN_ERRORS);
42+
const [myDomainSecurityGroups] = useOnyx(ONYXKEYS.MY_DOMAIN_SECURITY_GROUPS);
4243

4344
const navigateToDomain = ({domainAccountID, isAdmin}: {domainAccountID: number; isAdmin: boolean}) => {
4445
if (!isAdmin) {
@@ -57,14 +58,11 @@ function DomainsListPage() {
5758
continue;
5859
}
5960

60-
const currentUserAccountID = currentUserPersonalDetails?.accountID;
61-
const isDomainAdmin = isAdminSelector(currentUserAccountID)(domain);
62-
63-
// we don't want to show domains that the user has no access to, so we skip them in the list
64-
if (!currentUserAccountID || !hasDomainAccessSelector(currentUserAccountID)(domain)) {
61+
if (!currentUserAccountID || !hasDomainAccess(currentUserAccountID, myDomainSecurityGroups)(domain)) {
6562
continue;
6663
}
6764

65+
const isDomainAdmin = isAdminSelector(currentUserAccountID)(domain);
6866
const domainErrors = allDomainErrors?.[`${ONYXKEYS.COLLECTION.DOMAIN_ERRORS}${domain.accountID}`];
6967

7068
domainRows.push({

src/pages/domain/Groups/DefaultGroupToggle.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function DefaultGroupToggle({domainAccountID, groupID, groupName}: DefaultGroupT
4949
title: translate('domain.groups.defaultGroup'),
5050
prompt: translate('domain.groups.defaultGroupPrompt', defaultSecurityGroup.name, groupName),
5151
confirmText: translate('domain.groups.makeDefault'),
52-
cancelText: translate('domain.groups.neverMind'),
52+
cancelText: translate('domain.common.neverMind'),
5353
shouldShowCancelButton: true,
5454
});
5555

src/pages/domain/Groups/DeleteGroupRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ function DeleteGroupRow({domainAccountID, groupID}: DeleteGroupRowProps) {
4848
title: translate('domain.groups.deleteGroupDangerConfirmationModal'),
4949
prompt: translate('domain.groups.deleteGroupDangerConfirmationModalDescription', defaultSecurityGroup?.name ?? ''),
5050
confirmText: translate('domain.groups.deleteGroup'),
51-
cancelText: translate('domain.groups.neverMind'),
51+
cancelText: translate('domain.common.neverMind'),
5252
shouldShowCancelButton: true,
5353
danger: true,
5454
});

src/selectors/Domain.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,19 @@ function isAdminSelector(accountID: number) {
213213
};
214214
}
215215

216-
/**
217-
* Creates a selector that checks if a given account ID has any access to the domain,
218-
* either as an admin or as a member of one of its security groups.
219-
*/
220-
function hasDomainAccessSelector(accountID: number) {
216+
/** Checks if a given account ID has any access to the domain, as an admin, a security group member, or via `myDomainSecurityGroups`. */
217+
function hasDomainAccess(accountID: number, myDomainSecurityGroups: OnyxEntry<Record<string, string>>) {
221218
return (domain: OnyxEntry<Domain>): boolean => {
222219
if (!domain || !accountID) {
223220
return false;
224221
}
225222

226-
return isAdminSelector(accountID)(domain) || memberAccountIDsSelector(domain).includes(accountID);
223+
if (isAdminSelector(accountID)(domain) || memberAccountIDsSelector(domain).includes(accountID)) {
224+
return true;
225+
}
226+
227+
const domainName = domainNameSelector(domain);
228+
return !!domainName && !!myDomainSecurityGroups?.[domainName];
227229
};
228230
}
229231

@@ -269,7 +271,7 @@ export {
269271
vacationDelegateSelector,
270272
accountLockSelector,
271273
isAdminSelector,
272-
hasDomainAccessSelector,
274+
hasDomainAccess,
273275
selectGroupByID,
274276
domainSecurityGroupSettingPendingActionSelector,
275277
domainSecurityGroupSettingErrorsSelector,

tests/unit/DomainSelectorsTest.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
domainSecurityGroupSettingPendingActionSelector,
1515
domainSettingsPrimaryContactSelector,
1616
groupsSelector,
17-
hasDomainAccessSelector,
17+
hasDomainAccess,
1818
isAdminSelector,
1919
isSecurityGroupEntry,
2020
isSecurityGroupPendingDeleteSelector,
@@ -844,19 +844,19 @@ describe('domainSelectors', () => {
844844
});
845845
});
846846

847-
describe('hasDomainAccessSelector', () => {
847+
describe('hasDomainAccess', () => {
848848
it('Should return false if domain is undefined', () => {
849-
expect(hasDomainAccessSelector(userID1)(undefined)).toBe(false);
849+
expect(hasDomainAccess(userID1, undefined)(undefined)).toBe(false);
850850
});
851851

852852
it('Should return false if accountID is 0', () => {
853853
const domain = createDomainFixture({admins: [['123456', userID1]]});
854-
expect(hasDomainAccessSelector(0)(domain)).toBe(false);
854+
expect(hasDomainAccess(0, undefined)(domain)).toBe(false);
855855
});
856856

857857
it('Should return true if the accountID is an admin', () => {
858858
const domain = createDomainFixture({admins: [['123456', userID1]]});
859-
expect(hasDomainAccessSelector(userID1)(domain)).toBe(true);
859+
expect(hasDomainAccess(userID1, undefined)(domain)).toBe(true);
860860
});
861861

862862
it('Should return true if the accountID is a member of a security group', () => {
@@ -870,7 +870,7 @@ describe('domainSelectors', () => {
870870
},
871871
});
872872

873-
expect(hasDomainAccessSelector(userID1)(domain)).toBe(true);
873+
expect(hasDomainAccess(userID1, undefined)(domain)).toBe(true);
874874
});
875875

876876
it('Should return false if the accountID is neither an admin nor a member', () => {
@@ -885,12 +885,28 @@ describe('domainSelectors', () => {
885885
},
886886
});
887887

888-
expect(hasDomainAccessSelector(userID1)(domain)).toBe(false);
888+
expect(hasDomainAccess(userID1, undefined)(domain)).toBe(false);
889889
});
890890

891891
it('Should return false for empty domain object', () => {
892892
const domain = createDomainFixture({empty: true});
893-
expect(hasDomainAccessSelector(userID1)(domain)).toBe(false);
893+
expect(hasDomainAccess(userID1, undefined)(domain)).toBe(false);
894+
});
895+
896+
it("Should return true if the domain name is present in the account's own myDomainSecurityGroups map, even without admin/security-group data on the domain entry", () => {
897+
// Mirrors the payload a non-admin member's own `domain_<id>` entry actually looks like: no
898+
// `expensify_adminPermissions_*` nor `domain_securityGroup_*` data, since only admins receive that.
899+
const domain = createDomainFixture({email: 'member@example.com'});
900+
const myDomainSecurityGroups = {'example.com': 'groupID123'};
901+
902+
expect(hasDomainAccess(userID1, myDomainSecurityGroups)(domain)).toBe(true);
903+
});
904+
905+
it("Should return false if the domain name is not present in the account's own myDomainSecurityGroups map", () => {
906+
const domain = createDomainFixture({email: 'member@example.com'});
907+
const myDomainSecurityGroups = {'other-domain.com': 'groupID123'};
908+
909+
expect(hasDomainAccess(userID1, myDomainSecurityGroups)(domain)).toBe(false);
894910
});
895911
});
896912

0 commit comments

Comments
 (0)