Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scoping data fetching (relations) #277

Open
mihaa1 opened this issue Oct 24, 2023 · 6 comments
Open

Scoping data fetching (relations) #277

mihaa1 opened this issue Oct 24, 2023 · 6 comments

Comments

@mihaa1
Copy link

mihaa1 commented Oct 24, 2023

Hello,
My setup uses authorizer to manage user auth while app user data is saved in the main db (the 1 remult sees - postgres), in the users table (created from User model).

For each request - I authenticate the request using a token - at this point - we are still in express-mw land. I then attach the user to the request obj so that getUser() can extract it (as specified in the tutorials).

I'm trying to get the user inside getUser() for all additional data like this:

getUser: async (req) => {
    const userData = await remult.repo(User)
      .find({ where: { email: req.user?.email } });
    if (userData) {
      return Promise.resolve({
        id: userData[0].id || '',
        email: userData[0].email || '',
        roles: [userData[0].role],
      });
    }
    return Promise.resolve(undefined);
}

But this causes some issues, specifically when combining with backendPrefilter() on entities. I'm guessing because of the async/await.
Example of backendFilter:

backendPrefilter: () => {
    return { organizationId: remult.user?.organizationId || '' };
  },

What/where would be the best place to extract to user data?

@mihaa1 mihaa1 closed this as completed Oct 24, 2023
@mihaa1 mihaa1 reopened this Oct 24, 2023
@mihaa1
Copy link
Author

mihaa1 commented Oct 24, 2023

Update:
The problem is I'm accessing the model from getUser(), triggering backendFilter before I have everything backendFilter expects.
Now I'm left with the original question - where should I pull user data from my db so it is visible to all entities/controllers?
Assuming also I want the role so getUser() will block api access relying on it (such as role: 'admin')

@noam-honig
Copy link
Collaborator

Hi @mihaa1 ,

First of all - you can check the user roles anywhere using remult.isAllowed('admin') etc...
Here's an example from an app I'm writing:

https://github.com/noam-honig/trempim/blob/master/src/app/events/tasks.ts#L145-L165

As for storing data you have several options.

  1. If you want that data to be shared with the frontend as well - you can extend the UserInfo object to include more information (phone etc...)
    https://github.com/noam-honig/trempim/blob/1e5f395bda16ed10cc9591f6788f982f8f08148b/src/app/common/UITools.ts#L54-L56

  2. You can store on the server anything that you want, using remult.context and then you can access it anywhere in the server:
    https://github.com/noam-honig/trempim/blob/1e5f395bda16ed10cc9591f6788f982f8f08148b/src/server/server-session.ts#L8-L29

  3. backendPrefilter is an async method, so you can fetch data there:

backendPrefilter: () =>{
const ids = (await repo(Something).find()).map(x=>x.id)
return {id:ids}
}

@mihaa1
Copy link
Author

mihaa1 commented Oct 28, 2023

@noam-honig thanks. I'll have to check the context approach.
In the meantime - I added a raw sql query to get the user on each request in getUser()

const sql = await SqlDatabase.getDb();
    const command = sql.createCommand();
    const res = await command.execute(
      `
  			SELECT * FROM users
  			WHERE email='${req.user?.email}'
  		`
    );

This way I get the user's data (role, other stuff for scoping data), and don't trigger the User model entity methods.

@noam-honig
Copy link
Collaborator

noam-honig commented Oct 28, 2023 via email

@mihaa1
Copy link
Author

mihaa1 commented Oct 28, 2023

@noam-honig if ur asking why I'm not using the context option - I still don't know how to yet (I need to move fast here on some development :)

@noam-honig
Copy link
Collaborator

You code is at risk of sql injection, with an invalid email.

Also - I'm not sure what you're getting in the result .

I think this can be solved by extending the UserInfo interface, at best - or by using repo to select the user as a less favorible option.

If you want, reach out to me tomorrow on discord and if I can, we can look at it together and I'll be happy to help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants