- One card per app (grouped by client_id) showing distinct device and category counts; the whole card opens the details modal (with hover and focus highlight) instead of a separate Details button - Details modal: access list styled like the OAuth consent dialog via a shared RsScopeListComponent, plus per-token device, connected date and expiry, each with its own Revoke - "folder" -> "category" in the card, modal, consent dialog and the auth-created notification - Make revoke a real DELETE: it was a GET link that Turbo 8's prefetch-on-hover fired on its own, silently deleting authorizations. Missing or foreign authorizations now return 404 instead of 500. - Move "Launch app" to the app level (GET /services/storage/apps/:client_id/launch); no token id in the URL Part of #254
70 lines
2.0 KiB
Ruby
70 lines
2.0 KiB
Ruby
class Services::RsAuthsController < Services::BaseController
|
|
before_action :authenticate_user!
|
|
before_action :require_service_enabled
|
|
before_action :require_service_available
|
|
before_action :find_rs_auth, only: [:destroy]
|
|
|
|
def index
|
|
@rs_apps = current_user.remote_storage_authorizations
|
|
.includes(:web_app)
|
|
.group_by(&:client_id)
|
|
.values
|
|
.map { |auths| auths.sort_by(&:created_at).reverse }
|
|
.sort_by { |auths| app_name_for(auths.first).downcase }
|
|
end
|
|
|
|
def destroy
|
|
@auth.destroy!
|
|
|
|
respond_to do |format|
|
|
format.html do redirect_to apps_services_storage_url, flash: {
|
|
success: 'App authorization revoked'
|
|
}
|
|
end
|
|
format.json { head :no_content }
|
|
end
|
|
end
|
|
|
|
def launch_app
|
|
auth = current_user.remote_storage_authorizations
|
|
.where(client_id: params[:client_id])
|
|
.order(created_at: :desc)
|
|
.first
|
|
http_status(:not_found) and return unless auth
|
|
|
|
user_address =
|
|
if Rails.env.development?
|
|
"#{current_user.cn}@#{request.host_with_port}"
|
|
else
|
|
current_user.address
|
|
end
|
|
|
|
# Storage-first bearer token issuance (remoteStorage spec §11): the app
|
|
# receives the address and runs the application-first flow itself.
|
|
launch_url = "#{auth.launch_url}#remotestorage=#{user_address}"
|
|
|
|
redirect_to launch_url, allow_other_host: true
|
|
end
|
|
|
|
private
|
|
|
|
def app_name_for(auth)
|
|
auth.web_app&.name.presence || auth.app_name.presence || auth.client_id
|
|
end
|
|
|
|
def require_service_enabled
|
|
unless current_user.service_enabled?(:remotestorage)
|
|
http_status :forbidden
|
|
end
|
|
end
|
|
|
|
def require_service_available
|
|
http_status :not_found unless Setting.remotestorage_enabled?
|
|
end
|
|
|
|
def find_rs_auth
|
|
@auth = current_user.remote_storage_authorizations.find_by(id: params[:id])
|
|
http_status :not_found unless @auth
|
|
end
|
|
end
|