slackapi / deno-slack-sdk

SDK for building Run on Slack apps using Deno
https://api.slack.com/automation
151 stars 27 forks source link

[BUG] External authentication with LinkedIn doesn't work #312

Closed liorp closed 2 months ago

liorp commented 2 months ago

The deno-slack versions

"deno-slack-sdk/": "https://deno.land/x/deno_slack_sdk@2.9.0/",
"deno-slack-api/": "https://deno.land/x/deno_slack_api@2.3.2/"

Deno runtime version

deno 1.42.1 (release, aarch64-apple-darwin)
v8 12.3.219.9
typescript 5.4.3

OS info

ProductName:            macOS
ProductVersion:         14.4.1
BuildVersion:           23E224
Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:41 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T8103

Describe the bug

When implementing DefineOAuth2Provider with LinkedIn, the authorization fails with

    oauth2_exchange_error
                scope_mismatch_error: provider and token scopes do not match

Steps to reproduce

  1. My OAuth 2 provider is defined as follows:
    
    import { DefineOAuth2Provider, Schema } from "deno-slack-sdk/mod.ts";

const LinkedInProvider = DefineOAuth2Provider({ provider_key: "linkedin", provider_type: Schema.providers.oauth2.CUSTOM, options: { provider_name: "LinkedIn", authorization_url: "https://www.linkedin.com/oauth/v2/authorization", token_url: "https://www.linkedin.com/oauth/v2/accessToken", client_id: CLIENT_ID, scope: [ "email", "openid", "profile", "w_member_social", ], authorization_url_extras: { prompt: "consent", access_type: "offline", }, identity_config: { url: "https://api.linkedin.com/v2/userinfo", account_identifier: "$.sub", http_method_type: "GET", }, use_pkce: false, }, });

export default LinkedInProvider;


I've configured a message trigger that sends a button in a chat. This button then triggers a workflow that has an input of

linkedin_access_token_id: { credential_source: "END_USER", },


2. The LinkedIn popup appears as expected, but when approving the request the console reports the following error
oauth2_exchange_error
            scope_mismatch_error: provider and token scopes do not match


**Expected result**

The authentication should succeed.
<!-- Tell what you expected to happen -->

**Actual result**

The authentication fails.
<!-- Tell what actually happened with logs, screenshots -->

**Requirements**

Please read the [Contributing guidelines](https://github.com/slackapi/deno-slack-sdk/blob/main/.github/contributing.md) and [Code of Conduct](https://slackhq.github.io/code-of-conduct) before creating this issue or pull request. By submitting, you are agreeing to those rules.
filmaj commented 2 months ago

Can you share your workflow and trigger definitions, please?

liorp commented 2 months ago

The workflow

import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
import { LinkedInPostFunctionDefinition } from "../functions/_linkedin_post.ts";

const PostWorkflow = DefineWorkflow({
  callback_id: "_post",
  title: " a Post",
  description: " a Post",
  input_parameters: {
    properties: {
      message: {
        type: Schema.types.string,
        description: "The message",
      },
      user_id: {
        type: Schema.slack.types.user_id,
        description: "The user id",
      },
    },
    required: ["message", "user_id"],
  },
});

const Step = PostWorkflow.addStep(
  LinkedInPostFunctionDefinition,
  {
    linkedin_access_token_id: {
      credential_source: "END_USER",
    },
    message: PostWorkflow.inputs.message,
    user_id: PostWorkflow.inputs.user_id,
  },
);

PostWorkflow.addStep(Schema.slack.functions.SendDm, {
  user_id: PostWorkflow.inputs.user_id,
  message:
    `Finished with ${Step.outputs.data}, error: ${Step.outputs.error}`,
});

export default PostWorkflow;

The trigger

import { Trigger } from "deno-slack-api/types.ts";
import { TriggerContextData, TriggerTypes } from "deno-slack-api/mod.ts";
import PostWorkflow from "../workflows/_post_link.ts";

const trigger: Trigger<typeof PostWorkflow.definition> = {
  type: TriggerTypes.Shortcut,
  name: "Linkedin post",
  description: "Responds to a linkedin post",
  workflow: `#/workflows/${PostWorkflow.definition.callback_id}`,
  inputs: {
    message: {
      customizable: true,
    },
    user_id: {
      value: TriggerContextData.Shortcut.user_id,
    },
  },
};

export default trigger;
filmaj commented 2 months ago

I can confirm this issue. I will engage the backend 3P Auth team at Slack to see what the issue is.

filmaj commented 2 months ago

We have identified the problem. The response from LinkedIn's token-exchange API is not exactly to the OAuth RFC spec (the scopes field should be space delimited, whereas LinkedIn's response is comma-delimited). Thus the error around scope mismatch.

We are working on a fix! Will keep you posted as to progress there.

filmaj commented 2 months ago

Hey @liorp , the fix was merged a couple hours ago and is deployed to production. I verified on my end that this now works 🎉

Going to close this, but if it's not working for you, feel free to re-open this issue or file a new one.