refactor oauth2 for async; define clearer chain of responsibility