question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom listenerMiddleware Problem

See original GitHub issue

Hi All,

I’m working on an additional security layer feature for hubot involving two factor authentication with Verisign VIP and am just battling to get my head around how hubot and middleware work.

My middleware code seems to work as expected when chatting directly to hubot (private message) but it’s not working correctly when it receives messages from users in a room.

Here is my middleware code:

module.exports = (robot) ->

  robot.listenerMiddleware (context, next, done) ->

    allowed_commands = [ "help", "ping" ]
    # Grab just the command issued, eg "ping" and not "hubot ping"
    command = context.response.message.text.slice(10)

    # Allow if any of our excluded commands are issued otherwise deny
    if command in allowed_commands
      next(done)
    else
      context.response.send "That command is not allowed"
      done()

My aim with the code above is:

  • if “hubot help” or “hubot ping” is issued, run it as normal…
  • if anything else is issued to hubot, deny and stop

Testing from a private chat message with hubot:

dave> hubot blah
hubot> That command is not allowed
dave> hubot ping
hubot> pong!

That worked just the way I expected it too: allow certain commands and deny the rest.

Now a test from a chat room to hubot:

dave> hubot blah
hubot> That command is not allowed

Great, just as expected but now when I try issue an allowed command I get the following:

dave> hubot ping
hubot> That command is not allowed
hubot> That command is not allowed

This is my problem. I’m not sure why it’s not allowing that command or why it’s sending a double response back. I’m using Hubot 2.18.0 and the hubot-hipchat adapter 2.12.0

Unfortunately my coffeescript and coding skills are not great. If anyone could shed some light on this problem or possibly point me in the right direction I’d really appreciate it!

Thanks! Dave

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
justdavercommented, May 5, 2016

Managed to solve this one. There were 2 issues.

When I issued something like this to hubot:

dave> hubot blah

In a room, context.response.message.text is:

hubot blah

While in a private message to hubot, context.response.message.text is:

Hubot:  blah

So to grab just the command issued to hubot, I had to check if it was issued from a room first and if so then apply a different slice…

    # Strip the first characters so we're left with just the command issued...
    if context.response.message.user.room?
      # hubot blah
      command = context.response.message.text.slice(6)
    else
      # Hubot:  blah
      command = context.response.message.text.slice(8)

Now it works the same for a room or a private message.

The next issue was where it was returning “That command is not allowed” twice in a room. This was solved by dropping the last done().

For anyone interested, here’s the full middleware code I’m using to intercept messages and first check if a user has verified with 2 factor authentication before the command runs. There are many pieces which work together here but this is just the middleware I’m using:

  # Catch all attempted commands and first check that the user is verified before allowing them
  # to run any commands. If not verified, tell them how it's done...

  robot.listenerMiddleware (context, next, done) ->

    name = context.response.message.user.name
    user = robot.brain.userForName(name)

    # Exclude some commands as all users need to be able to use verification funtions
    excluded_commands = [ "status", "users", "help", "ping" ]

    # Verify needs some regex magic...
    regex_verify = /// ^                # begin of line
      verify                            # the word "verify"
      .                                 # followed by a single space
      [0-9.]{6}                         # then exactly 6 digits, can also use [0-9][0-9][0-9][0-9][0-9]
      ///i                              # end

    # Strip the first characters so we're left with just the command issued...
    if context.response.message.user.room?
      # hubot blah
      command = context.response.message.text.slice(6)
    else
      # Hubot:  blah
      command = context.response.message.text.slice(8)

    # Allow if any core commands are issued
    if command in excluded_commands or command.match regex_verify
      next (done)
    else
      # Allow if user is currently verified
      if user.vip_status == "verified"
        next (done)
      else
        # Deny if user is not verified
        if user.vip_status == "never" or user.vip_status == "failed" or user.vip_status == "expired"
          context.response.send "Bot access denied. You need to verify first using two-factor authentication before I can trust you."
          context.response.send "To verify, type: #{robot.name} verify <your 6 digit OTP number>"

Thanks! Dave

1reaction
justdavercommented, May 5, 2016

@michaelansel I would really love to see how you guys are handling this with 2 factor authentication! 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Add an action listener callback middleware · Issue #237 - GitHub
I've started a PR that implements the idea of action listeners (custom middleware) using the builder pattern: #432.
Read more >
createListenerMiddleware - Redux Toolkit - JS.ORG
The "listener middleware instance" returned from createListenerMiddleware is an object similar to the "slice" objects generated by createSlice .
Read more >
Redux Toolkit's new listener middleware vs. Redux-Saga
The reason for creating the new listener middleware is to fill that void. In this article, I will compare the new listener middleware...
Read more >
Redux.js - Build a listener middleware who listens for thunk ...
Two suggestions: 1) add a console.log() statement in your listener callback to see if it's running, and 2) remove the this.props part because ......
Read more >
Designing the Redux Toolkit Listener Middleware
So, you've always been able to add sagas, observables, or custom middleware to the store, or turn off thunks entirely.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found