Access tokens are strictly personal

This commit is contained in:
David Heinemeier Hansson
2025-12-02 13:05:31 +01:00
committed by Stanko K.R.
parent caa4cd491e
commit 88902485e1
9 changed files with 36 additions and 53 deletions
@@ -0,0 +1,24 @@
class My::AccessTokensController < ApplicationController
def index
@access_tokens = Current.identity.access_tokens.order(created_at: :desc)
end
def new
@access_token = Current.identity.access_tokens.new
end
def create
@access_token = Current.identity.access_tokens.create!(access_token_params)
redirect_to my_access_tokens_path
end
def destroy
Current.identity.access_tokens.find(params[:id]).destroy!
redirect_to my_access_tokens_path
end
private
def access_token_params
params.expect(access_token: [ :description, :permission ])
end
end
@@ -1,35 +0,0 @@
class Users::AccessTokensController < ApplicationController
before_action :set_user
before_action :set_access_token, except: %i[ index new create ]
def index
set_page_and_extract_portion_from @user.identity.access_tokens.order(created_at: :desc)
end
def new
@access_token = @user.identity.access_tokens.new
end
def create
@access_token = @user.identity.access_tokens.create!(access_token_params)
redirect_to user_access_tokens_path(@user)
end
def destroy
@access_token.destroy!
redirect_to user_access_tokens_path(@user)
end
private
def set_user
@user = Current.account.users.active.find(params[:user_id])
end
def set_access_token
@access_token = @user.identity.access_tokens.find(params[:id])
end
def access_token_params
params.expect(access_token: [ :description, :permission ])
end
end
-4
View File
@@ -5,8 +5,4 @@ module UsersHelper
else user.role.titleize
end
end
def access_token_permission_options
Identity::AccessToken.permissions.keys.map { [ it.humanize, it ] }
end
end
@@ -3,7 +3,7 @@
<td><%= access_token.permission.humanize %></td>
<td><%= local_datetime_tag access_token.created_at, style: :datetime %></td>
<td>
<%= button_to user_access_token_path(@user, access_token), method: :delete,
<%= button_to my_access_token_path(access_token), method: :delete,
class: "btn txt-negative btn--circle txt-x-small borderless fill-transparent",
data: { turbo_confirm: "Are you sure you want to permanently revoke this access token?" } do %>
<%= icon_tag "trash" %>
@@ -2,14 +2,14 @@
<% content_for :header do %>
<div class="header__actions header__actions--start">
<%= back_link_to "My profile", user_path(@user), "keydown.left@document->hotkey#click keydown.esc@document->hotkey#click" %>
<%= back_link_to "My profile", user_path(Current.user), "keydown.left@document->hotkey#click keydown.esc@document->hotkey#click" %>
</div>
<h1 class="header__title"><%= @page_title %></h1>
<% end %>
<section class="panel panel--wide shadow center webhooks">
<% if @page.used? %>
<% if @access_tokens.any? %>
<p class="margin-none-block-start">Tokens you have generated that can be used to access the Fizzy API.</p>
<table class="access_tokens_table margin-block-end-double max-width txt-small">
<thead>
@@ -21,16 +21,14 @@
</tr>
</thead>
<tbody>
<%= with_automatic_pagination :access_tokens, @page do %>
<%= render partial: "users/access_tokens/access_token", collection: @page.records %>
<% end %>
<%= render partial: "my/access_tokens/access_token", collection: @access_tokens %>
</tbody>
</table>
<% else %>
<p class="margin-none-block-start">Personal access tokens can be used like a password to access the Fizzy developer API. You can have as many tokens as you need and revoke access to each one at any time.</p>
<% end %>
<%= link_to new_user_access_token_path(@user), class: "btn btn--link" do %>
<%= link_to new_my_access_token_path, class: "btn btn--link" do %>
<%= icon_tag "add" %>
<span>Generate a new access token</span>
<% end %>
@@ -2,14 +2,14 @@
<% content_for :header do %>
<div class="header__actions header__actions--start">
<%= back_link_to "tokens", user_access_tokens_path(@user), "keydown.left@document->hotkey#click keydown.esc@document->hotkey#click" %>
<%= back_link_to "tokens", my_access_tokens_path, "keydown.left@document->hotkey#click keydown.esc@document->hotkey#click" %>
</div>
<h1 class="header__title"><%= @page_title %></h1>
<% end %>
<article class="panel panel--wide shadow center txt-align-start" style="view-transition-name: <%= dom_id(@access_token) %>">
<%= form_with model: @access_token, url: user_access_tokens_path(@user), scope: :access_token, data: { controller: "form" }, html: { class: "flex flex-column gap" } do |form| %>
<%= form_with model: @access_token, url: my_access_tokens_path, scope: :access_token, data: { controller: "form" }, html: { class: "flex flex-column gap" } do |form| %>
<div class="flex flex-column gap-half">
<strong><%= form.label :description, "Access token description" %></strong>
<%= form.text_field :description, required: true, autofocus: true, class: "input", placeholder: "e.g. Github", data: { action: "keydown.esc@document->form#cancel" } %>
@@ -17,13 +17,13 @@
<div class="flex flex-column gap-half">
<strong><%= form.label :permission %></strong>
<%= form.select :permission, options_for_select(access_token_permission_options), {}, class: "input input--select" %>
<%= form.select :permission, options_for_select({ "Read" => "read", "Read + Write" => "write"}), {}, class: "input input--select" %>
</div>
<%= form.button type: :submit, class: "btn btn--link center txt-medium" do %>
<span>Generate access token</span>
<% end %>
<%= link_to "Cancel and go back", user_access_tokens_path(@user), data: { form_target: "cancel" }, hidden: true %>
<%= link_to "Cancel and go back", my_access_tokens_path, data: { form_target: "cancel" }, hidden: true %>
<% end %>
</article>
+1 -1
View File
@@ -4,6 +4,6 @@
</header>
<div class="flex align-center gap txt-normal">
<%= link_to "Personal access tokens", user_access_tokens_path(user), class: "btn" %>
<%= link_to "Personal access tokens", my_access_tokens_path, class: "btn" %>
</div>
</div>
+1 -1
View File
@@ -43,7 +43,7 @@
<% if Current.user == @user %>
<section class="panel shadow" style="--panel-size: 45ch;">
<%= render "users/transfer", user: @user %>
<%= render "users/developer", user: @user %>
<%= render "users/developer" %>
<div class="center margin-block-start-double">
<%= button_to session_url(script_name: nil), method: :delete, class: "btn btn--plain txt-link txt-small", data: { turbo: false } do %>
+1 -1
View File
@@ -15,7 +15,6 @@ Rails.application.routes.draw do
resource :events
resources :push_subscriptions
resources :access_tokens
resources :email_addresses, param: :token do
resource :confirmation, module: :email_addresses
@@ -163,6 +162,7 @@ Rails.application.routes.draw do
resource :landing
namespace :my do
resources :access_tokens
resources :pins
resource :timezone
resource :menu