reveal API key with user password

This commit is contained in:
Alex Turchyn
2025-09-05 09:29:20 +03:00
committed by Pete Matsyburka
parent c04bb2d7cf
commit f40f1d25de
7 changed files with 93 additions and 4 deletions
@@ -0,0 +1,21 @@
# frozen_string_literal: true
class RevealAccessTokenController < ApplicationController
def show
authorize!(:manage, current_user.access_token)
end
def create
authorize!(:manage, current_user.access_token)
if current_user.valid_password?(params[:password])
render turbo_stream: turbo_stream.replace(:access_token_container,
partial: 'reveal_access_token/access_token',
locals: { token: current_user.access_token.token })
else
render turbo_stream: turbo_stream.replace(:modal, template: 'reveal_access_token/show',
locals: { error_message: I18n.t('wrong_password') }),
status: :unprocessable_content
end
end
end
+15 -4
View File
@@ -11,10 +11,21 @@
<div class="flex flex-col md:flex-row gap-4">
<div class="flex w-full space-x-4">
<% token = current_user.access_token.token %>
<masked-input class="block w-full" data-token="<%= token %>">
<input id="api_key" type="text" value="<%= token.sub(token[5..], '*' * token[5..].size) %>" class="input font-mono input-bordered w-full" autocomplete="off" readonly>
</masked-input>
<%= render 'shared/clipboard_copy', icon: 'copy', text: token, class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: t('copy'), copied_title: t('copied') %>
<% obscured_token = current_user.access_token.token.sub(token[5..], '*' * token[5..].size) %>
<% if current_account.testing? %>
<masked-input class="block w-full" data-token="<%= token %>">
<input id="api_key" type="text" value="<%= obscured_token %>" class="input font-mono input-bordered w-full" autocomplete="off" readonly>
</masked-input>
<%= render 'shared/clipboard_copy', icon: 'copy', text: token, class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: t('copy'), copied_title: t('copied') %>
<% else %>
<a id="access_token_container" href="<%= settings_reveal_access_token_path %>" data-turbo-frame="modal" class="flex w-full space-x-4">
<input id="api_key" type="text" value="<%= obscured_token %>" class="input font-mono input-bordered w-full" autocomplete="off" readonly>
<div class="base-button">
<%= svg_icon('copy', class: 'w-6 h-6 text-white') %>
<span class="hidden md:inline"><%= t('copy') %></span>
</div>
</a>
<% end %>
</div>
<%= button_to button_title(title: t('rotate'), disabled_with: t('rotate'), icon: svg_icon('reload', class: 'w-6 h-6')), settings_api_index_path, class: 'white-button w-full', data: { turbo_confirm: t('remove_existing_api_token_and_generated_a_new_one_are_you_sure_') } %>
</div>
@@ -0,0 +1,2 @@
<input id="api_key" type="text" value="<%= token %>" class="input font-mono input-bordered w-full" autocomplete="off" readonly>
<%= render 'shared/clipboard_copy', icon: 'copy', text: token, class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: t('copy'), copied_title: t('copied') %>
@@ -0,0 +1,14 @@
<%= render 'shared/turbo_modal', title: t('reveal_api_key') do %>
<%= form_tag settings_reveal_access_token_path, enctype: 'multipart/form-data', data: { turbo_frame: :_top } do %>
<div class="form-control">
<%= label_tag :password, t('enter_your_password_to_reveal_the_api_key'), class: 'label' %>
<%= password_field_tag :password, nil, class: 'base-input', autocomplete: 'current-password', required: true, autofocus: true, placeholder: t('password') %>
<% if local_assigns[:error_message].present? %>
<span class="label-text-alt text-red-400 mt-1"><%= local_assigns[:error_message] %></span>
<% end %>
</div>
<div class="form-control mt-4">
<%= submit_tag t('submit'), class: 'base-button' %>
</div>
<% end %>
<% end %>