mirror of
https://github.com/System-End/hackatime.git
synced 2026-04-19 21:05:15 +00:00
* Themes pt1 * Themes pt2 * Standard -> Classic, new default is Gruvbox Dark * Make settings shell fatter
211 lines
13 KiB
Text
211 lines
13 KiB
Text
<% content_for :title do %>
|
|
<%= @application.name %> - OAuth Application
|
|
<% end %>
|
|
|
|
<div class="max-w-4xl mx-auto p-6 space-y-6">
|
|
<header class="text-center mb-8">
|
|
<h1 class="text-4xl font-bold text-surface-content mb-2"><%= t('.title', name: @application.name) %></h1>
|
|
<p class="text-secondary text-lg">OAuth application credentials and settings</p>
|
|
</header>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<div class="lg:col-span-2 space-y-6">
|
|
<div class="border border-primary rounded-xl p-6 bg-dark">
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<div class="p-2 bg-primary/10 rounded">
|
|
<svg class="w-6 h-6 text-primary" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
|
|
</svg>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-surface-content">Application Credentials</h2>
|
|
</div>
|
|
|
|
<div class="space-y-5">
|
|
<div>
|
|
<label class="block text-sm font-medium text-secondary mb-2"><%= t('.application_id') %></label>
|
|
<div class="flex items-center gap-2">
|
|
<code id="application_id" class="flex-1 px-3 py-2 bg-darkless border border-darkless rounded text-surface-content font-mono text-sm break-all"><%= @application.uid %></code>
|
|
<button type="button" onclick="c(this, <%= @application.uid.to_json %>)" class="px-3 py-2 bg-darkless hover:bg-secondary/20 text-surface-content rounded transition-colors" title="Copy">
|
|
<svg class="w-5 h-5 ci" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
|
</svg>
|
|
<svg class="w-5 h-5 c hidden text-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-secondary mb-2"><%= t('.secret') %></label>
|
|
<% secret = flash[:application_secret].presence || @application.plaintext_secret %>
|
|
<% if secret.blank? && Doorkeeper.config.application_secret_hashed? %>
|
|
<div class="px-3 py-2 bg-darkless border border-darkless rounded">
|
|
<span class="text-secondary italic text-sm"><%= t('.secret_hashed') %></span>
|
|
</div>
|
|
<p class="mt-2 text-xs text-yellow">
|
|
<svg class="w-4 h-4 inline mr-1" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
|
</svg>
|
|
The secret was only shown once when the application was created.
|
|
</p>
|
|
<% else %>
|
|
<div class="flex items-center gap-2">
|
|
<code id="secret" class="flex-1 px-3 py-2 bg-darkless border border-darkless rounded text-surface-content font-mono text-sm break-all"><%= secret %></code>
|
|
<button type="button" onclick="c(this, <%= secret.to_json %>)" class="px-3 py-2 bg-darkless hover:bg-secondary/20 text-surface-content rounded transition-colors" title="Copy">
|
|
<svg class="w-5 h-5 ci" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
|
</svg>
|
|
<svg class="w-5 h-5 c hidden text-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<% if flash[:application_secret].present? %>
|
|
<p class="mt-2 text-xs text-green">
|
|
<svg class="w-4 h-4 inline mr-1" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
|
|
</svg>
|
|
Here are your details. Keep them safe and secure!
|
|
</p>
|
|
<% end %>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-secondary mb-2"><%= t('.scopes') %></label>
|
|
<% if @application.scopes.present? %>
|
|
<div class="flex flex-wrap gap-2">
|
|
<% @application.scopes.to_a.each do |scope| %>
|
|
<span class="px-2 py-1 bg-primary/20 text-primary border border-primary/30 rounded text-sm font-mono"><%= scope %></span>
|
|
<% end %>
|
|
</div>
|
|
<% else %>
|
|
<span class="text-secondary italic text-sm"><%= t('.not_defined') %></span>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-secondary mb-2"><%= t('.confidential') %></label>
|
|
<% if @application.confidential? %>
|
|
<span class="inline-flex items-center gap-1.5 px-2 py-1 bg-green/20 text-green border border-green/30 rounded text-sm">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
|
|
</svg>
|
|
Yes - Confidential
|
|
</span>
|
|
<% else %>
|
|
<span class="inline-flex items-center gap-1.5 px-2 py-1 bg-yellow/20 text-yellow border border-yellow/30 rounded text-sm">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
|
</svg>
|
|
No - Public Client
|
|
</span>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-secondary mb-2">Verified Status</label>
|
|
<% if @application.verified? %>
|
|
<span class="inline-flex items-center gap-1.5 px-2 py-1 bg-green/20 text-green border border-green/30 rounded text-sm">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
Verified
|
|
</span>
|
|
<% else %>
|
|
<span class="inline-flex items-center gap-1.5 px-2 py-1 bg-yellow/20 text-yellow border border-yellow/30 rounded text-sm">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
|
</svg>
|
|
Unverified
|
|
</span>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border border-primary rounded-xl p-6 bg-dark">
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<div class="p-2 bg-primary/10 rounded">
|
|
<svg class="w-6 h-6 text-primary" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
|
</svg>
|
|
</div>
|
|
<h2 class="text-xl font-semibold text-surface-content"><%= t('.callback_urls') %></h2>
|
|
</div>
|
|
|
|
<% if @application.redirect_uri.present? %>
|
|
<div class="space-y-3">
|
|
<% @application.redirect_uri.split.each do |uri| %>
|
|
<div class="flex items-center gap-3 p-3 bg-darkless border border-darkless rounded">
|
|
<code class="flex-1 text-surface-content font-mono text-sm break-all"><%= uri %></code>
|
|
<%= link_to oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code', scope: @application.scopes),
|
|
class: "shrink-0 px-3 py-1.5 bg-green hover:opacity-90 text-on-primary text-sm font-medium rounded transition-colors",
|
|
target: '_blank' do %>
|
|
Test Auth
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% else %>
|
|
<p class="text-secondary italic"><%= t('.not_defined') %></p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div class="border border-primary rounded-xl p-6 bg-dark">
|
|
<h3 class="text-lg font-semibold text-surface-content mb-4"><%= t('.actions') %></h3>
|
|
<div class="space-y-3">
|
|
<%= link_to edit_oauth_application_path(@application),
|
|
class: "w-full inline-flex items-center justify-center gap-2 px-4 py-2 bg-primary hover:opacity-90 text-on-primary font-medium rounded transition-colors duration-200" do %>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
|
</svg>
|
|
<%= t('doorkeeper.applications.buttons.edit') %>
|
|
<% end %>
|
|
<%= render 'delete_form', application: @application, submit_btn_css: 'danger' %>
|
|
|
|
<% if current_user&.admin_level_superadmin? %>
|
|
<%= button_to toggle_verified_admin_oauth_application_path(@application),
|
|
method: :post,
|
|
class: "w-full inline-flex items-center justify-center gap-2 px-4 py-2 #{@application.verified? ? 'bg-yellow hover:bg-yellow/80' : 'bg-green hover:bg-green/80'} text-on-primary font-medium rounded transition-colors duration-200" do %>
|
|
<% if @application.verified? %>
|
|
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
|
</svg>
|
|
Remove Verification
|
|
<% else %>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
Verify Application
|
|
<% end %>
|
|
<% end %>
|
|
<% end %>
|
|
|
|
<%= button_to rotate_secret_oauth_application_path(@application),
|
|
method: :post,
|
|
data: { turbo_confirm: "Are you sure? This will invalidate your current secrets and break existing integrations" },
|
|
class: "w-full inline-flex items-center justify-center gap-2 px-4 py-2 border border-yellow/40 text-yellow hover:bg-yellow/10 font-medium rounded transition-colors duration-200" do %>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
</svg>
|
|
Rotate Secret
|
|
<% end %>
|
|
|
|
<%= link_to oauth_applications_path,
|
|
class: "w-full inline-flex items-center justify-center gap-2 px-4 py-2 border border-darkless text-surface-content font-medium rounded transition-colors duration-200 hover:bg-darkless" do %>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
|
</svg>
|
|
Back to Applications
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<%= render "shared/clipboard_script" %>
|