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

[BUG] Oauth2 with linear.app is broken #259

Open
NickeZ opened this issue Dec 19, 2023 · 13 comments
Open

[BUG] Oauth2 with linear.app is broken #259

NickeZ opened this issue Dec 19, 2023 · 13 comments
Labels
backend Slack backend issue bug Something isn't working

Comments

@NickeZ
Copy link

NickeZ commented Dec 19, 2023

The deno-slack versions

$ cat import_map.json | grep deno-slack
    "deno-slack-sdk/": "https://deno.land/x/deno_slack_sdk@2.4.1/",
    "deno-slack-api/": "https://deno.land/x/deno_slack_api@2.1.2/",

Deno runtime version

$ deno --version
deno 1.38.5 (release, aarch64-apple-darwin)
v8 12.0.267.1
typescript 5.2.2

OS info

$ sw_vers && uname -v
ProductName:            macOS
ProductVersion:         14.0
BuildVersion:           23A344
Darwin Kernel Version 23.0.0: Fri Sep 15 14:42:57 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T8112

Describe the bug

I'm trying to add linear.app oauth2 api to a slack app as an "external-auth". Whenever I try to authentiecate I get an error message "unable_to_parse_state", see attached image. I did double check that the state parameter has the same content before the redirect as after. Slack support told me to reach out here.

Screenshot 2023-11-25 at 10 53 17

Steps to reproduce

  1. Create a new slack app using the CLI.
  2. Create an oauth2 app over at linear.app.
  3. Add the oauth2 app as an external auth provider in slack. (https://api.slack.com/automation/external-auth)
  4. Try authenticating

Expected result

I expect the authentication to work

Actual result

Error message about parsing state

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

@NickeZ NickeZ changed the title [BUG] <title> [BUG] Oauth2 with linear.app is broken Dec 19, 2023
@WilliamBergamin
Copy link
Contributor

Hi @NickeZ thanks for writing in 💯

Does this consistently happen?

I might be out of my depth here but this error may indicate that the OAuth protocol may not be properly implemented (I have not tested this out yet)

In short based on the OAuth2 protocol if the Authorization Request sent by Slack includes a state parameter then the Authorization Response returned by the linear.app api is required to contain this state parameter as well. The error message leads me to believe that this state parameter may be invalid in the response.

Regardless this feels like a server side issue, I've inquired internally about this

@WilliamBergamin WilliamBergamin added server-side issue with Slack HTTP API needs info not enough information to reproduce or continue labels Dec 19, 2023
@NickeZ
Copy link
Author

NickeZ commented Dec 23, 2023

Hi @NickeZ thanks for writing in 💯

Does this consistently happen?

Yes, it has happened consistently over a couple of weeks while chatting with slack support.

I might be out of my depth here but this error may indicate that the OAuth protocol may not be properly implemented (I have not tested this out yet)

This might be the case. I did try setting up a simple oauth2 integration using a rust app. Using that I had no problem authenticating.

In short based on the OAuth2 protocol if the Authorization Request sent by Slack includes a state parameter then the Authorization Response returned by the linear.app api is required to contain this state parameter as well. The error message leads me to believe that this state parameter may be invalid in the response.

The state parameter is correctly sent back and forth. I double checked the URLs and it doesn't change. The value of the state parameter set by slack is quite long. Maybe that contributes to some problem? Maybe the value is truncated by some proxy at slack?

Regardless this feels like a server side issue, I've inquired internally about this

I think the error message is quite vague and I have a hard time understanding exactly where the integration fails.

@WilliamBergamin
Copy link
Contributor

Hi @NickeZ

Where there OAuth flows with other providers on this workspace that where successful?

Any chance you could join the Slack Community workspace in order to exchange your specific environment information and track down these logs?

@WilliamBergamin
Copy link
Contributor

Hi @NickeZ would you be able to share what the provider configuration looks like?
And share what the raw manifest looks like by pasting the output of the slack manifest command? 🙏

@NickeZ
Copy link
Author

NickeZ commented Jan 6, 2024

Hi,

provider config:

mport { DefineOAuth2Provider, Manifest, Schema } from "deno-slack-sdk/mod.ts";

import { CreateLinearIssueFunction } from "./functions/create_linear_issue.ts";

const LinearProvider = DefineOAuth2Provider({
  provider_key: "linear",
  provider_type: Schema.providers.oauth2.CUSTOM,
  options: {
    provider_name: "Linear",
    authorization_url: "https://linear.app/oauth/authorize",
    token_url: "https://api.linear.app/oauth/token",
    client_id: "084...",
    scope: [
      "read",
      "issues:create",
    ],
    authorization_url_extras: {
      prompt: "consent",
    },
    identity_config: {
      url: "https://api.linear.app/graphql",
      account_identifier: "$.data.viewer.email",
      http_method_type: "POST",
      headers: { "Content-type": "application/json" },
      body: { "query": "{ viewer { email } }" },
    },
    use_pkce: false,
  },
});

/**
 * The app manifest contains the app's configuration. This
 * file defines attributes like app name and description.
 * https://api.slack.com/future/manifest
 */
export default Manifest({
  name: "linear-slack-integration",
  description: "Create issues in linear",
  icon: "assets/default_new_app_icon.png",
  functions: [CreateLinearIssueFunction],
  workflows: [],
  outgoingDomains: ["api.linear.app", "linear.app"],
  botScopes: ["commands", "chat:write", "chat:write.public"],
  externalAuthProviders: [LinearProvider],
});

slack manifest:

{
  "_metadata": {
    "major_version": 2
  },
  "display_information": {
    "name": "linear-slack-integration",
    "description": "Create issues in linear"
  },
  "features": {
    "app_home": {
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": true
    },
    "bot_user": {
      "display_name": "linear-slack-integration"
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "commands",
        "chat:write",
        "chat:write.public"
      ]
    },
    "token_management_enabled": false
  },
  "settings": {
    "org_deploy_enabled": true,
    "incoming_webhooks": {},
    "function_runtime": "slack",
    "siws_links": {}
  },
  "functions": {
    "create_linear_issue": {
      "title": "Create Linear Issue",
      "description": "",
      "input_parameters": {
        "properties": {
          "team_identifier": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "user": {
            "type": "string"
          },
          "linearAccessTokenId": {
            "type": "slack#/types/credential/oauth2",
            "oauth2_provider_key": "linear"
          }
        },
        "required": [
          "team_identifier",
          "title",
          "description",
          "user"
        ]
      },
      "output_parameters": {
        "properties": {
          "result": {
            "type": "string"
          },
          "issue_url": {
            "type": "string"
          }
        },
        "required": [
          "result"
        ]
      }
    }
  },
  "outgoing_domains": [
    "api.linear.app",
    "linear.app"
  ],
  "external_auth_providers": {
    "oauth2": {
      "linear": {
        "provider_type": "CUSTOM",
        "options": {
          "provider_name": "Linear",
          "authorization_url": "https://linear.app/oauth/authorize",
          "token_url": "https://api.linear.app/oauth/token",
          "client_id": "08....",
          "scope": [
            "read",
            "issues:create"
          ],
          "authorization_url_extras": {
            "prompt": "consent"
          },
          "identity_config": {
            "url": "https://api.linear.app/graphql",
            "account_identifier": "$.data.viewer.email",
            "http_method_type": "POST",
            "headers": {
              "Content-type": "application/json"
            },
            "body": {
              "query": "{ viewer { email } }"
            }
          },
          "use_pkce": false
        }
      }
    }
  }
}

@WilliamBergamin
Copy link
Contributor

@NickeZ we've published a connector that successfully executes the hand-shack

The linear provider config looks something like this

{
  "provider_type": "CUSTOM",
  "options": {
    "client_id": "xxxx",
    "scope": [
      "read",
      "write",
      "issues:create",
      "comments:create"
    ],
    "provider_name": "Linear",
    "authorization_url": "https://linear.app/oauth/authorize",
    "token_url": "https://api.linear.app/oauth/token",
    "identity_config": {
      "url": "https://api.linear.app/graphql",
      "body": {
        "query": "{ viewer { id email } }"
      },
      "http_method_type": "POST",
      "headers": {
        "Content-Type": "application/json"
      },
      "account_identifier": "$.data.viewer.email"
    }
  }
}

Similar to your implementation, but it seems like authorization_url_extras is not required, could you try removing it from your provider

@WilliamBergamin WilliamBergamin removed the server-side issue with Slack HTTP API label Jan 8, 2024
@filmaj filmaj added bug Something isn't working backend Slack backend issue and removed needs info not enough information to reproduce or continue labels Jan 8, 2024
@NickeZ
Copy link
Author

NickeZ commented Apr 15, 2024

Hello!

I'm back on this task again. I updated all slack dependencies and now I get a bit further. When I do slack run I see the following in the console: Auth start succeeded by user 'XXXX' on team 'XXXX' for app 'XXXXX' and provider 'linear'. So it looks better. But the final redirect doesn't seem to happen. I'm stuck on https://oauth2.slack.com/external/auth/callback?code=455a8024ff5c31780e2bfd6451cbbe896980fa9c7e624eac66a89f2403f573c9&state=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZWFtX2lkIjoiVDAyOFlRNkRCIiwidXNlcl9pZCI6IlUwMlE3MVc2REM3IiwicHJvdmlkZXJfaWQiOjYyODkyMTY3NzY0MTcsImV4cCI6MTcxMzE3NDY3NCwic291cmNlIjoic2xhY2tfY2xpZW50Iiwid29ya2Zsb3dfaWQiOiJXZjA2N1M1VVRHTTYiLCJmdW5jdGlvbl9pZCI6IkZuMDY4NzEyNFlDVSJ9.CtjNl6Ghcyn_Pqrx8EyAmN01-npyzwEasWS_LgrVOB8 in the web browser. The page is just a white blank screen. The same happens if I initiate from the slack macos app or the slack web app. I suspect I should be redirected back to the slack app? I tested with Safari on macos.

@NickeZ
Copy link
Author

NickeZ commented Apr 15, 2024

The slack connector that you have published works fine. But I need the customizability of running my own connector.

@NickeZ
Copy link
Author

NickeZ commented Apr 15, 2024

Tested various browsers:

  • firefox, still the "cannot parse state" as in the first comment.
  • safello, white screen
  • chrome, 500 from slack.com see below
Screenshot 2024-04-15 at 14 16 19

@NickeZ
Copy link
Author

NickeZ commented Apr 15, 2024

I figured out the "state" problem. It is because I use firefox containers. It opened the first link as a "containerless" tab. But then when I pressed "Continue to linear" it opened a "Work" container. But the other issue still remains. I get a blank screen / 500.

@WilliamBergamin
Copy link
Contributor

Hi @NickeZ thanks for getting back to us,

Could you ensure that options.identity_config.body.query is "{ viewer { id email } }" and could you share the updated output of slack manifest?

@NickeZ
Copy link
Author

NickeZ commented Apr 15, 2024

Yes, options.identity_config.body.query has the right value.
I tried adding some more domains to the list of outgoing domains. But no success..

$ slack manifest
{
  "_metadata": {
    "major_version": 2
  },
  "display_information": {
    "name": "linear-slack-integration",
    "description": "Create issues in linear"
  },
  "features": {
    "app_home": {
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": true
    },
    "bot_user": {
      "display_name": "linear-slack-integration"
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "commands",
        "chat:write",
        "chat:write.public"
      ]
    },
    "token_management_enabled": false
  },
  "settings": {
    "org_deploy_enabled": true,
    "incoming_webhooks": {},
    "function_runtime": "slack",
    "siws_links": {}
  },
  "functions": {
    "create_linear_issue": {
      "title": "Create Linear Issue",
      "description": "",
      "input_parameters": {
        "properties": {
          "team_identifier": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "user": {
            "type": "string"
          },
          "linearAccessTokenId": {
            "type": "slack#/types/credential/oauth2",
            "oauth2_provider_key": "linear"
          }
        },
        "required": [
          "team_identifier",
          "title",
          "description",
          "user"
        ]
      },
      "output_parameters": {
        "properties": {
          "result": {
            "type": "string"
          },
          "issue_url": {
            "type": "string"
          }
        },
        "required": [
          "result"
        ]
      }
    }
  },
  "outgoing_domains": [
    "api.linear.app",
    "client-api.linear.app",
    "s.linear.app",
    "linear.app"
  ],
  "external_auth_providers": {
    "oauth2": {
      "linear": {
        "provider_type": "CUSTOM",
        "options": {
          "provider_name": "Linear",
          "authorization_url": "https://linear.app/oauth/authorize",
          "token_url": "https://api.linear.app/oauth/token",
          "client_id": "08...",
          "scope": [
            "write",
            "read",
            "issues:create",
            "comments:create"
          ],
          "identity_config": {
            "url": "https://api.linear.app/graphql",
            "account_identifier": "$.data.viewer.email",
            "http_method_type": "POST",
            "headers": {
              "Content-type": "application/json"
            },
            "body": {
              "query": "{ viewer { id email } }"
            }
          }
        }
      }
    }
  }
}

@WilliamBergamin
Copy link
Contributor

@NickeZ thanks for sharing 💯 from what I can tell your configuration is nearly identical to the one used by the linear connector, since this configuration works for the connector I would recommend reaching out to linear in order to ensure everything is setup properly on their end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Slack backend issue bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants