-
Notifications
You must be signed in to change notification settings - Fork 0
Add headless helpers for custom dashboard integrations #9
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
Add headless helpers for custom dashboard integrations #9
Conversation
Introduce three helper modules that make building custom API key UIs
effortless without dictating styling:
- TokenSession: Manages "show token once" pattern for secret keys
- store(session, api_key) - save token after creation
- retrieve_once(session) - get and clear token
- available?(session) - check without clearing
- ExpirationOptions: Handles expiration preset dropdowns
- for_select - returns options for Rails select helper
- parse("30_days") - converts preset to datetime
- default_value - returns "no_expiration"
- ViewHelpers: Data formatting for views (include in ApplicationHelper)
- api_key_status/status_label/status_info
- api_key_environment_label/environment_from_token
- api_key_type_label/publishable?/secret?
These helpers are designed to be framework-agnostic - they return data,
not HTML, so integrators can use Tailwind, Bootstrap, or any styling.
Co-Authored-By: Claude <noreply@anthropic.com>
Introduce FormBuilderExtensions module that reduces view boilerplate
while letting integrators control all styling. Opt-in via initializer:
Rails.application.config.to_prepare do
ActionView::Helpers::FormBuilder.include(ApiKeys::FormBuilderExtensions)
end
Form helpers included:
- api_key_expiration_select(options, html_options)
One-line expiration dropdown with all presets
<%= form.api_key_expiration_select(class: "my-select") %>
- api_key_scopes_checkboxes(scopes, checked:, &block)
Block-based scope rendering - you provide markup, we handle logic
<%= form.api_key_scopes_checkboxes(@scopes) do |scope, checked| %>
<label><%= check_box_tag ..., checked %><%= scope %></label>
<% end %>
- api_key_token_data
Returns structured hash for building custom token display UIs
{ masked:, full:, viewable:, type:, environment: }
Design principle: helpers yield data and handle logic, integrators
provide all HTML/CSS. Works with any design system.
Co-Authored-By: Claude <noreply@anthropic.com>
Model scopes on ApiKey: - .publishable - keys with key_type: "publishable" - .secret - keys that are NOT publishable (includes legacy) Owner instance methods (HasApiKeys): - available_api_key_scopes - get scopes for forms - can_create_api_key?(key_type:) - check limits before UI - create_api_key! now accepts expires_at_preset: param Auto-cleaning: - scopes= setter auto-removes blank values (form checkbox fix) - create_api_key! also cleans scopes array Wire up in lib/api_keys.rb: - Require all helper modules - Create top-level aliases for cleaner API: - ApiKeys::TokenSession (vs ApiKeys::Helpers::TokenSession) - ApiKeys::ExpirationOptions - ApiKeys::ViewHelpers Co-Authored-By: Claude <noreply@anthropic.com>
Extract reusable partials from key row for cleaner code: - _token_display.html.erb - masked/viewable token with show button - _key_badges.html.erb - type, environment, expiration badges - _key_status.html.erb - active/expired/revoked status badge - _key_actions.html.erb - edit/revoke action buttons - _empty_state.html.erb - empty state messaging Update existing partials: - _key_row.html.erb - now uses extracted partials - _keys_table.html.erb - simplified table structure - _publishable_keys.html.erb - improved section layout - _secret_keys.html.erb - improved section layout Add minimal JS for show/copy token functionality: - Event delegation for .btn-show-token and .btn-copy-token - Vanilla JS, no framework dependencies - Progressive enhancement (works without JS) Co-Authored-By: Claude <noreply@anthropic.com>
Document all helpers and best practices learned from production integration into a real SaaS application. New sections: - Building Custom Integrations (overview + what you'll need) - Quick Setup (4-step guide with code) - Complete Controller Example (90-line production-ready code) - Model Scopes (.publishable, .secret, .active, etc.) - Owner Instance Methods (available_api_key_scopes, can_create_api_key?, etc.) - API Key Instance Methods (full method reference) - Token Session Helper (store, retrieve_once, available?) - Expiration Options Helper (for_select, parse, default_value) - Form Builder Extensions (with ERB examples) - View Helpers (status, type, environment helpers) - View Examples (index, form, success page code) - Best Practices (7 production-learned patterns) The guide provides copy-paste-ready code for building custom UIs while using the gem's model layer and business logic. Co-Authored-By: Claude <noreply@anthropic.com>
Pull Request Review: Headless Helpers for Custom Dashboard IntegrationsOverviewThis PR introduces a comprehensive set of helpers and utilities for building custom API key management UIs. The implementation is well-structured and follows Rails conventions effectively. ✅ Strengths1. Excellent Code Organization
2. Strong Documentation
3. Framework-Agnostic Design
4. Production-Ready Patterns
🔍 Code Quality IssuesCritical: Input Validation in within_key_type_limit While .where() calls use parameterized queries (safe), key_type and environment values come from user input without explicit validation at this point. The validation happens earlier in validate_key_type! and validate_environment!, but only when creating keys through create_api_key!. Risk: If someone creates a key directly via ApiKey.create! or bypasses the helper, unvalidated input could reach this validation. Recommendation: Add validation safeguards in the validation method itself to ensure key_type is in the list of known types. High: Missing Input Validation in View Helpers The api_key_environment_from_token method accepts user-provided tokens without length validation. While read-only, excessively long tokens could cause performance issues. Recommendation: Add basic input validation with a reasonable max length (e.g., 500 characters). Medium: Race Condition in can_create_api_key? This check happens without locking, so concurrent requests could bypass the limit. The actual within_key_type_limit validation uses locking, but the UI-facing can_create_api_key? doesn't. Impact: Low - worst case is showing a Create button that will fail validation. Not a security issue, just UX. Recommendation: Document this behavior with a comment explaining it's a best-effort check for UI purposes only. 🎯 Best Practices & Suggestions1. Expiration Options Edge Case 2. Form Builder Extension Safety 🧪 Test CoverageThe PR mentions all existing tests pass (145 runs, 0 failures) - great! However, I recommend adding tests for:
🔒 Security ConsiderationsOverall Security Posture: Good ✅
Recommendations:
📊 Performance ConsiderationsPositive:
Concerns:
📝 DocumentationExcellent additions:
Minor suggestions:
✨ ConclusionThis is a high-quality PR that significantly improves the gem's flexibility while maintaining security and following Rails conventions. The helper design is excellent and clearly informed by real production usage. Summary:
Recommended Actions Before Merge:
Overall Rating: 8.5/10 - Solid implementation with room for minor security improvements. Great work on this feature! 🚀 |
Cover TokenSession, ExpirationOptions, and ViewHelpers to bring branch coverage above the 60% CI threshold. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Address automated review feedback: - Add max length check (500 chars) in api_key_environment_from_token - Add max days limit (3650 / ~10 years) in ExpirationOptions.parse - Document can_create_api_key? as best-effort check for UI purposes - Add thorough boundary condition tests for all edge cases Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pull Request Review: Add headless helpers for custom dashboard integrationsOverviewThis is a well-designed PR that adds comprehensive helper modules for custom API key management UIs. The code is clean, well-tested, and follows Rails conventions. The README additions are extensive and provide excellent documentation. Test Coverage: All 145 tests pass ✅ 🟢 Strengths
🟡 Issues FoundHigh Priority1. Race Condition in Key Limit Validation
|
Summary
Adds helper modules and model conveniences for building custom API key management UIs outside the built-in engine dashboard. This enables apps like LicenseSeat to create tailored experiences while leveraging the gem's core functionality.
.publishable,.secret,.active,.inactivecan_create_api_key?,available_api_key_scopesWhat's included
lib/api_keys/helpers/)lib/api_keys/form_builder_extensions.rb)Setup for custom integrations
Test plan
🤖 Generated with Claude Code