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

isInRole, fix #56 #390

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

isInRole, fix #56 #390

wants to merge 6 commits into from

Conversation

StorytellerCZ
Copy link
Member

Adds isInRole function (and its async equivalent) as per #56

TODO: tests

@StorytellerCZ StorytellerCZ linked an issue Feb 3, 2024 that may be closed by this pull request
@StorytellerCZ StorytellerCZ marked this pull request as ready for review July 22, 2024 16:14
@StorytellerCZ
Copy link
Member Author

Just need to add the tests and then we are good to go.

Copy link
Member

@jankapunkt jankapunkt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally approve, since it technically works. My comments a mostly nitpicking.
One thing, though: the majority of the functions could be extracted into a single fn (DRY):

const getIsInRole = (role, scope, fn) => {
  const userId = Meteor.userId()
  const comma = (role || '').indexOf(',')
  let roles

  if (!userId) return false
  if (!Match.test(role, String)) return false

  if (comma !== -1) {
    roles = role.split(',').reduce(function (memo, r) {
      if (!r) {
        return memo
      }
      memo.push(r)
      return memo
    }, [])
  } else {
    roles = [role]
  }

return Match.test(scope, String)
  ? fn(userId, roles, scope)
  : fn(userId, roles)
}
 

// ...

isInRole: function (role, scope) {
  return getIsInRole(role, scope, this.userIsInRole)
}

isInRoleAsync: function (role, scope) {
  return getIsInRole(role, scope, this.userIsInRoleAsync)
}

Just a potential saving of lines and potential bugs etc.

what do you think? Am I overengineering?

return memo
}
memo.push(r)
return memo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be simplified:

if (r) {
  memo.push(r)
}
return memo

return this.userIsInRole(userId, roles, scope)
}

return this.userIsInRole(userId, roles)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a conditional return:

return Match.test(scope, String)
  ? this.userIsInRole(userId, roles, scope)
  : this.userIsInRole(userId, roles)

return await this.userIsInRoleAsync(userId, roles, scope)
}

return await this.userIsInRoleAsync(userId, roles)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically you don't need to await before returning and also don't need to make the function async, because it will return a promise anyway.

If you resolve the promise before returning, there will be one more microtask execution than if returning the promise directly:

isInRoleAsync: function (role, scope) {
  // ...

  return this.userIsInRoleAsync(userId, roles) // always returns Promise
}

does not affect anything by itself but might be measurable when requests / operations do in the millions haha

@StorytellerCZ
Copy link
Member Author

Yes, I agree with all the simplifications and improvements. The original code is pretty old.

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

Successfully merging this pull request may close these issues.

Add isInRole to JS API as well
2 participants