diff --git a/app/models/api_key.rb b/app/models/api_key.rb index 7eda901..fd8142a 100644 --- a/app/models/api_key.rb +++ b/app/models/api_key.rb @@ -1,4 +1,6 @@ class ApiKey < ApplicationRecord + include NtfyDispatchable + # Normalize permissions to always be a Hash attribute :permissions, :jsonb, default: {} @@ -56,6 +58,12 @@ class ApiKey < ApplicationRecord # Revoke API key def revoke! update!(active: false) + + self.class.dispatch_ntfy("api_key_revoked", + title: "API key revoked", + message: "API key '#{name}' (#{key_prefix}...) was revoked", + priority: 3, + tags: ["key", "no_entry"]) end # Deactivate expired keys diff --git a/test/models/api_key_test.rb b/test/models/api_key_test.rb new file mode 100644 index 0000000..7adf114 --- /dev/null +++ b/test/models/api_key_test.rb @@ -0,0 +1,31 @@ +require "test_helper" + +class ApiKeyTest < ActiveSupport::TestCase + include ActiveJob::TestHelper + + setup do + ActiveJob::Base.queue_adapter = :test + @admin = AdminUser.create!( + name: "Key Admin", email: "key@example.com", + password: "password123", + ntfy_topic: "key-topic", ntfy_token: "tk_key", + ntfy_enabled: true, ntfy_server_url: "https://ntfy.example.com" + ) + stub_request(:post, "https://ntfy.example.com/key-topic").to_return(status: 200) + end + + test "revoke! dispatches api_key_revoked notification" do + api_key = ApiKey.create!( + name: "Test Key", + key_digest: "e" * 64, + key_prefix: "api_live_ab", + permissions: {}, active: true + ) + + assert_enqueued_jobs 1 do + api_key.revoke! + end + + assert_not api_key.reload.active + end +end