Fix browser extension not working (#316)

Co-authored-by: Max Wofford <max@maxwofford.com>
This commit is contained in:
ShyMike 2025-06-17 19:20:54 +01:00 committed by GitHub
parent 927e1903f0
commit 9676fd13f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 5 deletions

View file

@ -234,6 +234,10 @@ class Api::Hackatime::V1::HackatimeController < ApplicationController
heartbeat_array.each do |heartbeat|
source_type = :direct_entry
# Fallback to :plugin if :user_agent is not set
fallback_value = heartbeat.delete(:plugin)
heartbeat[:user_agent] ||= fallback_value
parsed_ua = WakatimeService.parse_user_agent(heartbeat[:user_agent])
# special case: if the entity is "test.txt", this is a test heartbeat
@ -318,7 +322,8 @@ class Api::Hackatime::V1::HackatimeController < ApplicationController
:project_root_count,
:time,
:type,
:user_agent
:user_agent,
:plugin
]
end
@ -328,8 +333,9 @@ class Api::Hackatime::V1::HackatimeController < ApplicationController
{ heartbeats: params.permit(_json: [ *heartbeat_keys ])[:_json] }
elsif request.content_type&.include?("text/plain") && request.raw_post.present?
# Handle text/plain requests by parsing JSON directly
parsed_json = JSON.parse(request.raw_post) rescue []
{ heartbeats: parsed_json }
parsed_json = JSON.parse(request.raw_post, symbolize_names: true) rescue []
filtered_json = parsed_json.map { |hb| hb.slice(*heartbeat_keys) }
{ heartbeats: filtered_json }
else
params.require(:hackatime).permit(
heartbeats: [
@ -345,7 +351,7 @@ class Api::Hackatime::V1::HackatimeController < ApplicationController
params[:_json].first.permit(*heartbeat_keys)
elsif request.content_type&.include?("text/plain") && request.raw_post.present?
# Handle text/plain requests by parsing JSON directly
parsed_json = JSON.parse(request.raw_post) rescue {}
parsed_json = JSON.parse(request.raw_post, symbolize_names: true) rescue {}
parsed_json = [ parsed_json ] unless parsed_json.is_a?(Array)
parsed_json.first&.with_indifferent_access&.slice(*heartbeat_keys) || {}
elsif params[:hackatime].present?

View file

@ -87,7 +87,18 @@ class WakatimeService
else
# Try parsing as browser user agent as fallback
if browser_ua = user_agent.match(/^([^\/]+)\/([^\/\s]+)/)
{ os: browser_ua[1], editor: browser_ua[2], err: nil }
# If "wakatime" is present, assume it's the browser extension
if user_agent.include?("wakatime") then
full_os = user_agent.split(" ")[1]
if full_os.present?
os = full_os.include?("_") ? full_os.split("_")[0] : full_os
{ os: os, editor: browser_ua[1].downcase, err: nil }
else
{ os: "", editor: "", err: "failed to parse user agent string" }
end
else
{ os: browser_ua[1], editor: browser_ua[2], err: nil }
end
else
{ os: "", editor: "", err: "failed to parse user agent string" }
end

View file

@ -63,6 +63,14 @@ class WakatimeServiceTest < Minitest::Test
assert_nil result[:error]
end
def test_parse_user_agent_with_Firefox
user_agent = "Firefox/139.0 linux_x86-64 firefox-wakatime/4.1.0"
result = WakatimeService.parse_user_agent(user_agent)
assert_equal "linux", result[:os]
assert_equal "firefox", result[:editor]
assert_nil result[:error]
end
def test_parse_user_agent_with_invalid_user_agent
user_agent = "invalid-user-agent"
result = WakatimeService.parse_user_agent(user_agent)