identity-vault/app/controllers/backend/kbar_controller.rb
nora 9998147a4e
epic: overhaul program management experience (#188)
* temp commit

* lemme do it

* nope

* let them do it too

* collab invite model

* better visuals on progman

* waow

* danger will robinson

* show apps on backend & link user

* first pass on app auditability!

* no lastnaming admins

* async frame that shit!

* waugh

* can't add yourself

* fix reinvite

* sidebar badging

* lint...

* gotta be on the app!

* let that get rescued by applcon

* already in revoke_all_authorizations

* woag

* the routes you grew up with no longer exist

* what would the UI for that even be?

* sorch

* much better!

* frickin validations
2026-03-02 22:15:13 -05:00

91 lines
2.8 KiB
Ruby

# frozen_string_literal: true
module Backend
class KbarController < ApplicationController
skip_after_action :verify_authorized
def search
query = params[:q].to_s.strip
scope = params[:scope].to_s.strip
results = []
return render json: results if query.blank?
# Check if it's a public ID pattern
prefix = query.split("!").first.downcase
prefix_info = Shortcodes.public_id_prefixes[prefix]
if query.include?("!") && prefix_info
begin
# Safe to use constantize because prefix_info[:model] comes from
# Shortcodes.public_id_prefixes which contains only whitelisted model names
model_name = prefix_info[:model]
klass = Object.const_get(model_name)
record = klass.find_by_public_id(query)
if record
results << build_result_for(record, prefix_info)
end
rescue
nil
end
elsif scope.present?
results = search_in_scope(scope, query)
end
render json: results
end
private
def search_in_scope(scope, query)
results = []
case scope
when "identities"
policy_scope(Identity).search(query.sub("mailto:", "")).limit(10).each do |identity|
results << {
type: "identity",
id: identity.public_id,
label: identity.full_name,
sublabel: identity.primary_email,
path: "/backend/identities/#{identity.public_id}"
}
end
when "oauth_apps"
if current_user.super_admin? || current_user.program_manager?
Program.where("name ILIKE ? OR uid = ?", "%#{query}%", query).limit(10).each do |app|
results << {
type: "oauth_app",
id: app.id,
label: app.name,
sublabel: app.redirect_uri&.truncate(50),
path: "/developer/apps/#{app.id}"
}
end
end
end
results
end
def build_result_for(record, prefix_info)
type = prefix_info[:model].underscore
base_path = prefix_info[:path]
label, sublabel, path = case record
when Identity
[ record.full_name, record.primary_email, "#{base_path}/#{record.public_id}" ]
when Address
[ record.full_address, record.identity&.full_name, "/backend/identities/#{record.identity&.public_id}" ]
when Verification
[ "Verification #{record.public_id}", record.identity&.full_name, "#{base_path}/#{record.public_id}" ]
else
display = record.try(:name) || record.try(:title) || record.public_id
[ display, nil, "#{base_path}/#{record.public_id}" ]
end
{ type: type, id: record.public_id, label: label, sublabel: sublabel, path: path }
end
end
end