Expensify / App

Welcome to New Expensify: a complete re-imagination of financial collaboration, centered around chat. Help us build the next generation of Expensify by sharing feedback and contributing to the code.
https://new.expensify.com
MIT License
3.36k stars 2.78k forks source link

[HOLD #26538] [$500] Settings - Using deep link, admin can request money to user workspace chat even though its not allowed #26523

Closed izarutskaya closed 9 months ago

izarutskaya commented 1 year ago

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Action Performed:

  1. Open the app
  2. Open settings->workspaces->any workspace-> members->invite any member
  3. Open the new chat created between workspace and user added in step 2
  4. Click plus and observe that request money is not present as we are admin
  5. In the URL, replace '/r/' with '/request/new/' and observe that it allows to open request money page
  6. Complete the process and observe that app raises a request

Expected Result:

App should display 'Hmm its not here' page for request money by deep link by admin in workspace chat as request money option is not available for admin

Actual Result:

App allows to request money by deep link by admin in workspace chat even though request money option is not available for admin

Workaround:

Unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

Version Number: v1.3.61-3

Reproducible in staging?: Y

Reproducible in production?: Y

If this was caught during regression testing, add the test name, ID and link from TestRail:

Email or phone of affected tester (no customers):

Logs: https://stackoverflow.com/c/expensify/questions/4856

Notes/Photos/Videos: Any additional supporting documentation

https://github.com/Expensify/App/assets/115492554/bd1189fd-151c-429a-b57b-d976626d65d9

https://github.com/Expensify/App/assets/115492554/c19de3ee-768d-4c47-be61-c2971efc939a

Expensify/Expensify Issue URL:

Issue reported by: @Dhanashree-Sawant

Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1692943365255729

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01fea0f36079525f3d
  • Upwork Job ID: 1698569709503803392
  • Last Price Increase: 2023-10-19
Issue OwnerCurrent Issue Owner: @sophiepintoraetz
GItGudRatio commented 1 year ago

Proposal

Please re-state the problem that we are trying to solve in this issue.

Using deep link, admin can request money to user workspace chat even though its not allowed

What is the root cause of that problem?

On the MoneyRequestSelectorPage, we do not have any validation based on the report type if the user should be allowed to create an IOU.

What changes do you think we should make in order to solve the problem?

We need to add a validation to show the "Not found" page if the user is not allowed to perform IOU in a specific chat.

We need to add a new condition here !ReportUtils.canRequestMoney(ReportUtils.getReport(reportID)): https://github.com/Expensify/App/blob/f5fa30b8e831eb4d19fef2a24a61c1b7d5292b3c/src/pages/iou/MoneyRequestSelectorPage.js#L68

What alternative solutions did you explore? (Optional)

To determine if the Request Money menu item should be shown in a chat, we use the function ReportUtils.getMoneyRequestOptions. All the validation is present here that tells if the user should be able to request money. What we need to do is create a function to have all this validation. We could also update the existing canRequestMoney method. The exact implementation can be discussed in the PR.

The places where Request Money should be disabled are:

The places where Split Bill should be disabled are:

namhihi237 commented 1 year ago

Proposal

Please re-state the problem that we are trying to solve in this issue.

App should display 'Hmm its not here' page for request money by deep link by admin in workspace chat as request money option is not available for admin

What is the root cause of that problem?

We have not checked whether the report is allowed to open modal request money when opened by deep link or not at MoneyRequestSelectorPage like in composer here

Therefore, when we open a deeplink, we can open the money request modal in any report.

What changes do you think we should make in order to solve the problem?

We should check the same as in the composer and add condition here

    const report = reportID && ReportUtils.getReport(reportID);
    const isRequestMoney = _.isEmpty(report) || ReportUtils.getMoneyRequestOptions(report, lodashGet(report, "participantAccountIDs", []), props.betas).includes(CONST.IOU.MONEY_REQUEST_TYPE.REQUEST);
<FullPageNotFoundView shouldShow={!IOUUtils.isValidMoneyRequestType(iouType) || !isRequestMoney}>

https://github.com/Expensify/App/blob/5db24452f475e51226be1d12ef5e8d47878d8879/src/pages/iou/MoneyRequestSelectorPage.js#L68

What alternative solutions did you explore? (Optional)

N/A

esh-g commented 1 year ago

Proposal

Please re-state the issue

The request money deep link has no checks to ensure that the action is allowed or not.

What is the root cause of this issue?

The request money page MoneyRequestSelectorPage has no logic to check if the requesting action is allowed for the particular report.

What changes should be made in order to fix this?

We already have a method called ReportUtils.getMoneyRequestOptions() which returns the valid money request options for a particular report that we are using in the + button in the composer to display valid options. https://github.com/Expensify/App/blob/c16995257c738761206ea07645e863ee717ecbc0/src/libs/ReportUtils.js#L2977-L2996

We should use this function in MoneyRequestSelectorPage as well. Since, we are already using FullScreenNotFoundView in the page already: https://github.com/Expensify/App/blob/c16995257c738761206ea07645e863ee717ecbc0/src/pages/iou/MoneyRequestSelectorPage.js#L90

  1. We need to check if the passed iouType is allowed for the current report. Therefore, we should modify the condition to the following:

    const isInvalid = !IOUUtils.isValidMoneyRequestType(iouType) || (props.report && !_.includes(ReportUtils.getMoneyRequestOptions(props.report, reportParticipantIDs, props.betas), iouType));
    ...
    <FullPageNotFoundView shouldShow={isInvalid}> 
  2. We also need to pass the reportParticipantIDs so we can add that to the body of the component as a memo:

    const reportParticipantIDs = useMemo(
    () => _.without(lodashGet(props.report, 'participantAccountIDs', []), props.currentUserPersonalDetails.accountID),
    [props.session.accountID, props.report],
    );
  3. To get the relevant parameters for getMoneyRequestOptions(), we can modify the HOCs and add some properties to the withOnyx HOC as well as add the withCurrentUserPersonalDetails HOC, like this:

    export default withOnyx({
    selectedTab: {
        key: `${ONYXKEYS.SELECTED_TAB}_${CONST.TAB.RECEIPT_TAB_ID}`,
    },
    report: {
        key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`,
    },
    betas: {
        key: ONYXKEYS.BETAS,
    },
    session: {
        key: ONYXKEYS.SESSION
    }
    })(MoneyRequestSelectorPage);
melvin-bot[bot] commented 1 year ago

Triggered auto assignment to @sophiepintoraetz (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

melvin-bot[bot] commented 1 year ago

Bug0 Triage Checklist (Main S/O)

sophiepintoraetz commented 1 year ago

2023-09-04_17-31-33 (1)

melvin-bot[bot] commented 1 year ago

Job added to Upwork: https://www.upwork.com/jobs/~01fea0f36079525f3d

melvin-bot[bot] commented 1 year ago

Current assignee @sophiepintoraetz is eligible for the External assigner, not assigning anyone new.

melvin-bot[bot] commented 1 year ago

Triggered auto assignment to Contributor-plus team member for initial proposal review - @ntdiary (External)

ntdiary commented 1 year ago

@sophiepintoraetz , hmm, curious if there are other normal flows that would cause a user to hit this issue? πŸ˜‚ The conditions for allowing money request seem a bit complex, so I'm not exactly sure if it's necessary to fix right now. Also it looks like the backend allows this request - if we really want to fix this issue, we may need to disable it there as well.

image
esh-g commented 1 year ago

@ntdiary I think a combination of backend and frontend are required. This is how we handled the issue of accessing things like workspace settings for non-admins. Like in this issue: https://github.com/Expensify/App/issues/22013

sophiepintoraetz commented 1 year ago

if there are other normal flows that would cause a user to hit this issue?

I appreciate it's not a normal flow but given the world of finance, these are the sort of back doors you want to shore up, so let's fix it. If it is on the back end as well, I'll assign the internal label.

melvin-bot[bot] commented 1 year ago

Current assignee @ntdiary is eligible for the Internal assigner, not assigning anyone new.

ntdiary commented 1 year ago

@sophiepintoraetz, can you please also add a internal engineer?

We need to prohibit such creating requests on the backend (return error code), just like deleting these requests:

https://github.com/Expensify/App/assets/8579651/9d5342b4-d12a-4f78-8c09-caf36025796a

ntdiary commented 1 year ago

@GItGudRatio, the MoneyRequestSelectorPage component already has a report prop, so I think we can replace ReportUtils.getReport(reportID) with props.report.

GItGudRatio commented 1 year ago

@ntdiary Yeah sure, we can do the optimizations in the PR itself. I believe we need to decide upon the logic only for now, that's why I focused on the flow.

esh-g commented 1 year ago

@ntdiary From the proposals in this issue, please recognise that proposals from @GItGudRatio and @namhihi237 don't cover the case for split bills. If you see my proposal, it uses the iouType prop to validate to it will also be able to protect against unwanted split bill requests.

ntdiary commented 1 year ago

@ntdiary Yeah sure, we can do the optimizations in the PR itself. I believe we need to decide upon the logic only for now, that's why I focused on the flow.

@GItGudRatio, yeah, this is just a small kindly reminder, it would not make me reject your proposal, it's just that if you pay attention to this, it will make me feel you have a good understanding of the flow. : )

ntdiary commented 1 year ago

@ntdiary From the proposals in this issue, please recognise that proposals from @GItGudRatio and @namhihi237 don't cover the case for split bills. If you see my proposal, it uses the iouType prop to validate to it will also be able to protect against unwanted split bill requests.gg

@esh-g, don't worry, I'm still reviewing these proposals, no final decision yet. Also, @GItGudRatio mentioned logic related to split bill in the alternative solutions.

melvin-bot[bot] commented 1 year ago

Triggered auto assignment to @pecanoro (Engineering), see https://stackoverflow.com/c/expensify/questions/4319 for more details.

sophiepintoraetz commented 1 year ago

Hey @pecanoro - similar to this issue here, we believe that this requires a fix on both the back end and front end - so not sure if you want to take care of both or just the back end?

pecanoro commented 1 year ago

Can someone summarize what I need to block on the back-end? Blocking admins from making money requests on workspace chats?

ntdiary commented 1 year ago

Can someone summarize what I need to block on the back-end? Blocking admins from making money requests on workspace chats?

@pecanoro, yeah, for example:

image

This is expense chat between ntdiary and 2471314+1's Workspace (the creator is 2471314+1@gmail.com). We should only allow ntdiary to create money requests, but now, the creator can also successfully create money requests by modifying the url:

image
ntdiary commented 1 year ago

If you see my proposal, it uses the iouType prop to validate to it will also be able to protect against unwanted split bill requests.

@esh-g, this makes sense. I'm just concerned that the data in currentUserPersonalDetails may be quite large, while actually all we need is the accountId for the current user accountID, right? It would be better if we can reduce unnecessary dependencies. πŸ™‚

esh-g commented 1 year ago

@ntdiary In that case, we can subscribe to the ONYXKEYS.SESSION in the withOnyx HOC and access accountID like this: props.session.accountID

Infact, this is how we are getting the accountID in the currentUserPersonalDetails HOC

esh-g commented 1 year ago

@ntdiary I have updated my proposal to use the session.accountID instead of currentUserPersonalDetails. Let me know if you have any further concerns πŸ˜‡

ntdiary commented 1 year ago

@esh-g, considering the cause of this issue is quite straightforward, and you are the only one who clearly proposed handling iouType in the solution, I think we can move forward with your approach. : )

On the other hand, @pecanoro, we need to validate in the RequestMoney API that if the current user is not the owner of the current expense chat, do not allow them to create money request. Do you think this is feasible? (This issue is regarding the scenario where the creator of a workspace illegally created a Money request in the expense chat of one of its members.)

image
pecanoro commented 1 year ago

Asked internally because I am not sure what's the current behavior

melvin-bot[bot] commented 1 year ago

@pecanoro, @ntdiary, @sophiepintoraetz Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

pecanoro commented 1 year ago

Ok, figured this out, I am going to move to weekly so I can take care of this bug during the week but it's not extremely urgent. Once we have the back-end fix, we can implement the front-end ones.

sophiepintoraetz commented 1 year ago

Actually moving to weekly

esh-g commented 1 year ago

Ok, figured this out, I am going to move to weekly so I can take care of this bug during the week but it's not extremely urgent. Once we have the back-end fix, we can implement the front-end ones.

@pecanoro why not do them in parallel? Because I don't this the front end PR will interfere with the backend one in any way...

melvin-bot[bot] commented 1 year ago

@pecanoro @ntdiary @sophiepintoraetz this issue was created 2 weeks ago. Are we close to a solution? Let's make sure we're treating this as a top priority. Don't hesitate to create a thread in #expensify-open-source to align faster in real time. Thanks!

sophiepintoraetz commented 1 year ago

@pecanoro - what's happening here?

esh-g commented 1 year ago

@ntdiary Would like to hear your thoughts as to if we can proceed with frontend and backend simultaneously

ntdiary commented 1 year ago

Ah, I think it's also good to do them in parallel. If the backend finishes after the frontend, then we can use the old frontend version to test the backend. : )

pecanoro commented 1 year ago

Basically if we proceed with both there is a high chance that I will forget to fix it in the back-end since I currently have a high amount of workload. But sure, let's try both at the same time, though I don't think I can handle this until next week.

pecanoro commented 1 year ago

@ntdiary Was there any approved proposal?

ntdiary commented 1 year ago

@pecanoro, yeah, I was originally planning to move forward with @esh-g's proposal, however I was notified a few hours ago that there's another idea (for some similar flows) in slack that may be discussed, so I think we can wait for the outcome of that discussion first, and then we can assign to @esh-g to raise an implementation PR. πŸ™‚

sophiepintoraetz commented 1 year ago

Oh, sounds like we're holding this issue then?

pecanoro commented 1 year ago

@ntdiary I am not sure if that thread ended up agreeing on a path forward. Am I missing something?

ntdiary commented 1 year ago

@pecanoro, This is the discussion thread, it's still in progress. They posted it in the open source channel two days ago. : )

sophiepintoraetz commented 12 months ago

Where did we end up here @ntdiary?

ntdiary commented 12 months ago

Where did we end up here @ntdiary?

@sophiepintoraetz, still discussing in slack, was active a few hours ago. : )

sophiepintoraetz commented 12 months ago

(Sorry, Im out in the depths of Indonesia and wifi is verrrry slow so I try not to load slack if I don't have to!)

techievivek commented 11 months ago

Coming from here: https://github.com/Expensify/App/issues/29367#issuecomment-1759919616 we also want to prevent send money in group chat or other flows except global create and DM 1:1.

pecanoro commented 11 months ago

@ntdiary I think Tim closed the discussion here with a good proposal to move forward, do you think we could apply to this problem as well?

ntdiary commented 11 months ago

@ntdiary I think Tim closed the discussion here with a good proposal to move forward, do you think we could apply to this problem as well?

@pecanoro, I think it's good, and just left a comment in that thread, if there are no other updates within 24 hours, let's move forward with that approach. πŸš€

melvin-bot[bot] commented 11 months ago

Current assignee @ntdiary is eligible for the External assigner, not assigning anyone new.

melvin-bot[bot] commented 11 months ago

πŸ“£ It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? πŸ’Έ