feat: Linear OAuth 2.0 (#10851)

Fixes https://linear.app/chatwoot/issue/CW-3417/oauth-20-authentication
We are planning to publish the Chatwoot app in the Linear [integration
list](https://linear.app/docs/integration-directory). While we currently
use token-based authentication, Linear recommends OAuth2 authentication.
This PR implements OAuth2 support.

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
This commit is contained in:
Muhsin Keloth
2025-02-27 18:15:53 +05:30
committed by GitHub
parent 30996140a3
commit 12134f9391
18 changed files with 432 additions and 29 deletions

View File

@@ -1,4 +1,5 @@
class Integrations::App
include Linear::IntegrationHelper
attr_accessor :params
def initialize(params)
@@ -25,10 +26,18 @@ class Integrations::App
params[:fields]
end
# There is no way to get the account_id from the linear callback
# so we are using the generate_linear_token method to generate a token and encode it in the state parameter
def encode_state
generate_linear_token(Current.account.id)
end
def action
case params[:id]
when 'slack'
"#{params[:action]}&client_id=#{ENV.fetch('SLACK_CLIENT_ID', nil)}&redirect_uri=#{self.class.slack_integration_url}"
when 'linear'
build_linear_action
else
params[:action]
end
@@ -45,6 +54,17 @@ class Integrations::App
end
end
def build_linear_action
[
"#{params[:action]}?response_type=code",
"client_id=#{ENV.fetch('LINEAR_CLIENT_ID', nil)}",
"redirect_uri=#{self.class.linear_integration_url}",
"state=#{encode_state}",
'scope=read,write',
'prompt=consent'
].join('&')
end
def enabled?(account)
case params[:id]
when 'webhook'
@@ -64,6 +84,10 @@ class Integrations::App
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/#{Current.account.id}/settings/integrations/slack"
end
def self.linear_integration_url
"#{ENV.fetch('FRONTEND_URL', nil)}/linear/callback"
end
class << self
def apps
Hashie::Mash.new(APPS_CONFIG)