Getting OAuth Error

I am trying to use mailchimp to login to my app. I forked the repo because I keep getting the following error on my console (server):

W20150317-23:09:04.408(3) (oauth_server.js:78) Unable to parse state from OAuth query: ã‡4yÍ}ùÝÚßî:ão¼éçþõ֝۶Ý}Ƶ
W20150317-23:09:04.425(3) (oauth_server.js:78) Unable to parse state from OAuth query: ã‡4yÍ}ùÝÚßî:ão¼éçþõ֝۶Ý}Ƶ
W20150317-23:09:04.426(3) (oauth_server.js:78) Unable to parse state from OAuth query: ã‡4yÍ}ùÝÚßî:ão¼éçþõ֝۶Ý}Ƶ
W20150317-23:09:04.460(3) (oauth_server.js:398) Error in OAuth Server: failed [400] �VJ-*�/R�R��+K��L�O��L�+Q�����)�
I20150317-23:09:04.625(3)? Exception while invoking method 'login' Error: failed [400] �VJ-*�/R�R��+K��L�O��L�+Q�����)�
I20150317-23:09:04.625(3)?     at Object.Future.wait (/home/tsega/.meteor/packages/meteor-tool/.1.0.41.v3cupe++os.linux.x86_32+web.browser+web.cordova/meteor-tool-os.linux.x86_32/dev_bundle/server-lib/node_modules/fibers/future.js:326:15)
I20150317-23:09:04.625(3)?     at Object.call (packages/meteor/helpers.js:119:1)
I20150317-23:09:04.625(3)?     at Object.HTTP.post (packages/http/httpcall_common.js:56:1)
I20150317-23:09:04.625(3)?     at getTokenResponse (packages/tsega:accounts-mailchimp/lib/mailchimp_server.js:42:1)
I20150317-23:09:04.625(3)?     at Object.ServiceConfiguration.configurations.findOne.service [as handleOauthRequest] (packages/tsega:accounts-mailchimp/lib/mailchimp_server.js:7:1)
I20150317-23:09:04.625(3)?     at OAuth._requestHandlers.(anonymous function) (packages/oauth2/oauth2_server.js:8:1)
I20150317-23:09:04.626(3)?     at middleware (packages/oauth/oauth_server.js:173:1)
I20150317-23:09:04.626(3)?     at packages/oauth/oauth_server.js:146:1
I20150317-23:09:04.626(3)?     - - - - -
I20150317-23:09:04.626(3)?     at makeErrorByStatus (packages/http/httpcall_common.js:12:1)
I20150317-23:09:04.626(3)?     at Request._callback (packages/http/httpcall_server.js:98:1)
I20150317-23:09:04.626(3)?     at Request.self.callback (/home/tsega/.meteor/packages/http/.1.0.10.1ekyffn++os+web.browser+web.cordova/npm/node_modules/request/request.js:372:22)
I20150317-23:09:04.626(3)?     at Request.emit (events.js:98:17)
I20150317-23:09:04.627(3)?     at Request.<anonymous> (/home/tsega/.meteor/packages/http/.1.0.10.1ekyffn++os+web.browser+web.cordova/npm/node_modules/request/request.js:1310:14)
I20150317-23:09:04.627(3)?     at Request.emit (events.js:117:20)
I20150317-23:09:04.627(3)?     at IncomingMessage.<anonymous> (/home/tsega/.meteor/packages/http/.1.0.10.1ekyffn++os+web.browser+web.cordova/npm/node_modules/request/request.js:1258:12)
I20150317-23:09:04.627(3)?     at IncomingMessage.emit (events.js:117:20)
I20150317-23:09:04.627(3)?     at _stream_readable.js:943:16
I20150317-23:09:04.627(3)?     at process._tickCallback (node.js:419:13)

How do I fix this?

did you encode the state in the url?

var config = ServiceConfiguration.configurations.findOne({service: 'mailchimp'});
var loginStyle = OAuth._loginStyle('mailchimp', config, options);
var credentialToken = Random.secret();
var state = OAuth._stateParam(credentialToken, loginStyle);
url += "&state=" + state;

I had a problem similar in my application.

Thanks for the quick reply @corvid, but I’m not so sure where I would put that piece of code, here is the mailchimp_server.js code in its entirety. I’m guessing your code goes in the getTokenResponse() method.

var Oauth = Package.oauth.Oauth;

var urlUtil = Npm.require('url');

Oauth.registerService('mailchimp', 2, null, function(query) {

    var response    = getTokenResponse(query);
    var accessToken = response.access_token;
    var metaData = getMetaData(accessToken);
    var accountData = getAccountData(accessToken, metaData);

    var serviceData = {
      id: accountData.user_id,
      accessToken: accessToken,
      username: accountData.username,
      accountName: metaData.accountname,
      role: metaData.role,
      apiEndpoint: metaData.api_endpoint
    };

    return {
      serviceData: serviceData,
      options: {
        profile: {
          accountName: metaData.accountname,
          firstName: accountData.contact.fname,
          lastName: accountData.contact.lname,
          email: accountData.contact.email,
        }
      }
    };
});

// returns an object containing:
// - accessToken
// - expiresIn: lifetime of token in seconds
var getTokenResponse = function (query) {
    var config = ServiceConfiguration.configurations.findOne({service: 'mailchimp'});
    if (!config)
        throw new ServiceConfiguration.ConfigError("Service not configured");

    var result = HTTP.post(
        "https://login.mailchimp.com/oauth2/token", {params: {
            code: query.code,
            client_id: config.clientId,
            client_secret: OAuth.openSecret(config.secret),
            redirect_uri: OAuth._redirectUri('mailchimp', config),
            grant_type: 'authorization_code'
        }});

    if (result.error) // if the http response was an error
        throw result.error;
    if (typeof result.content === "string")
        result.content = JSON.parse(result.content);
    if (result.content.error) // if the http response was a json object with an error attribute
        throw result.content;
    return result.content;
};

var getMetaData = function(accessToken) {
  var result = HTTP.get("https://login.mailchimp.com/oauth2/metadata",
                        {headers:
                          {"Authorization" : "OAuth "+accessToken}});
  if (result.error) // if the http response was an error
        throw result.error;
  if (typeof result.content === "string")
      result.content = JSON.parse(result.content);
  if (result.content.error) // if the http response was a json object with an error attribute
      throw result.content;
  return result.content;
}

var getAccountData = function(accessToken, metaData) {

  var result = HTTP.post(
        decodeURI(metaData.api_endpoint) + "/2.0/helper/account-details.json", {params: {
            "apikey": accessToken
        }});

  if (result.error) // if the http response was an error
      throw result.error;
  if (typeof result.content === "string")
      result.content = JSON.parse(result.content);
  if (result.content.error) // if the http response was a json object with an error attribute
      throw result.content;
  return result.content;
}

Mailchimp.retrieveCredential = function(credentialToken) {
  console.log("retrieveCredential");
  return Oauth.retrieveCredential(credentialToken);
};

nah, meant on the client side

Yeah, I actually figured that I should put that code on the client side. Now I have a different error:

W20150318-00:13:36.638(3) (oauth_server.js:204) Error generating end of login response
Error: Unrecognized login style: sanKdppuG_6T5LQ7Bad1vZFHmjxgpr-TLILZF_6ukCL
    at Object.OAuth._loginStyleFromQuery (packages/oauth/oauth_server.js:94:1)
    at middleware (packages/oauth/oauth_server.js:200:1)
    at packages/oauth/oauth_server.js:146:1
W20150318-00:15:35.286(3) (oauth_server.js:204) Error generating end of login response
Error: Unrecognized login style: sanKdppuG_6T5LQ7Bad1vZFHmjxgpr-TLILZF_6ukCL
    at Object.OAuth._loginStyleFromQuery (packages/oauth/oauth_server.js:94:1)
    at middleware (packages/oauth/oauth_server.js:200:1)
    at packages/oauth/oauth_server.js:146:1

It looks like mailchimp does not recognize the generate state. How do I fix this one? Here is the client code:

    Mailchimp.requestCredential = function (options, callback) {
    
        if (!callback && typeof options === 'function') {
            callback = options;
            options = {};
        }
    
        var config = ServiceConfiguration.configurations.findOne({service: 'mailchimp'});
        if (!config) {
            callback && callback(new ServiceConfiguration.ConfigError("Service not configured"));
            return;
        }
    
        var loginStyle = OAuth._loginStyle('mailchimp', config, options);
        var credentialToken = Random.secret();
        var state = OAuth._stateParam(credentialToken, loginStyle);
    
        var loginUrl =
            'https://login.mailchimp.com/oauth2/authorize' +
                '?response_type=code' +
                '&client_id=' + config.clientId +
                '&redirect_uri=' + Meteor.absoluteUrl('_oauth/mailchimp?close',{replaceLocalhost:true}) +
                '&state=' + state;
    
    
        Oauth.initiateLogin(state, loginUrl, callback);
    
    };

I’m still trying to fix this issue, here is the error I get on the console now after making changes to the package following the code from core service packages (github, google) and even community service package linkedIn:

W20150321-16:39:53.227(3) (oauth_server.js:398) Error in OAuth Server: failed [400] �VJ-*�/R�R��+K��L�O/J�+Q�����j
I20150321-16:39:53.315(3)? Exception while invoking method 'login' Error: failed [400] �VJ-*�/R�R��+K��L�O/J�+Q�����j
I20150321-16:39:53.316(3)?     at Object.Future.wait (/home/tsega/.meteor/packages/meteor-tool/.1.0.44.l20o1y++os.linux.x86_32+web.browser+web.cordova/mt-os.linux.x86_32/dev_bundle/server-lib/node_modules/fibers/future.js:398:15)
I20150321-16:39:53.316(3)?     at Object.<anonymous> (packages/meteor/helpers.js:119:1)
I20150321-16:39:53.316(3)?     at Object.HTTP.call (packages/meteorhacks:kadira/lib/hijack/http.js:10:1)
I20150321-16:39:53.316(3)?     at Object.HTTP.post (packages/http/httpcall_common.js:56:1)
I20150321-16:39:53.316(3)?     at getTokenResponse (packages/tsega:mailchimp/mailchimp_server.js:44:1)
I20150321-16:39:53.316(3)?     at Object.ServiceConfiguration.configurations.findOne.service [as handleOauthRequest] (packages/tsega:mailchimp/mailchimp_server.js:9:1)
I20150321-16:39:53.317(3)?     at OAuth._requestHandlers.(anonymous function) (packages/oauth2/oauth2_server.js:8:1)
I20150321-16:39:53.317(3)?     at middleware (packages/oauth/oauth_server.js:173:1)
I20150321-16:39:53.317(3)?     at packages/oauth/oauth_server.js:146:1
I20150321-16:39:53.317(3)?     - - - - -
I20150321-16:39:53.317(3)?     at makeErrorByStatus (packages/http/httpcall_common.js:12:1)
I20150321-16:39:53.317(3)?     at Request._callback (packages/http/httpcall_server.js:109:1)
I20150321-16:39:53.317(3)?     at Request.self.callback (/home/tsega/.meteor/packages/http/.1.1.0.o0e7at++os+web.browser+web.cordova/npm/node_modules/request/request.js:344:22)
I20150321-16:39:53.317(3)?     at Request.emit (events.js:98:17)
I20150321-16:39:53.318(3)?     at Request.<anonymous> (/home/tsega/.meteor/packages/http/.1.1.0.o0e7at++os+web.browser+web.cordova/npm/node_modules/request/request.js:1239:14)
I20150321-16:39:53.318(3)?     at Request.emit (events.js:117:20)
I20150321-16:39:53.318(3)?     at IncomingMessage.<anonymous> (/home/tsega/.meteor/packages/http/.1.1.0.o0e7at++os+web.browser+web.cordova/npm/node_modules/request/request.js:1187:12)
I20150321-16:39:53.318(3)?     at IncomingMessage.emit (events.js:117:20)
I20150321-16:39:53.318(3)?     at _stream_readable.js:944:16
I20150321-16:39:53.318(3)?     at process._tickCallback (node.js:442:13)

It seems like your passing the parameters to OAuth._stateParam in the wrong order. The loginStyle must be the first parameter. See here