Customized more doorkeeper views, only logged in users can create oauth apps
This commit is contained in:
parent
aab9f57e36
commit
1aa477ac2f
16 changed files with 234 additions and 102 deletions
|
@ -8,7 +8,7 @@ $text-color: #333030;
|
||||||
$lighter-text-color: #8b8687;
|
$lighter-text-color: #8b8687;
|
||||||
|
|
||||||
@import url(https://fonts.googleapis.com/css?family=Roboto:400,500,400italic);
|
@import url(https://fonts.googleapis.com/css?family=Roboto:400,500,400italic);
|
||||||
@import url(https://fonts.googleapis.com/css?family=Roboto+Mono);
|
@import url(https://fonts.googleapis.com/css?family=Roboto+Mono:400,500);
|
||||||
@import "font-awesome";
|
@import "font-awesome";
|
||||||
|
|
||||||
/* http://meyerweb.com/eric/tools/css/reset/
|
/* http://meyerweb.com/eric/tools/css/reset/
|
||||||
|
|
|
@ -30,6 +30,11 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #fff;
|
||||||
|
background: darken(#282c37, 1%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
|
@ -86,14 +91,12 @@
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||||
border-bottom: 1px solid #d9e1e8;
|
|
||||||
color: #282c37;
|
color: #282c37;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.alternate {
|
&.alternate {
|
||||||
background: lighten(#282c37, 10%);
|
background: lighten(#282c37, 10%);
|
||||||
border-bottom: 1px solid lighten(#282c37, 10%);
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +107,7 @@
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
margin-left: 7px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +123,71 @@
|
||||||
border-radius: 0 4px 4px 0;
|
border-radius: 0 4px 4px 0;
|
||||||
|
|
||||||
.dashboard__content__content {
|
.dashboard__content__content {
|
||||||
//padding: 20px;
|
padding: 20px;
|
||||||
|
color: #282c37;
|
||||||
|
line-height: 18px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
samp {
|
||||||
|
font-family: 'Roboto Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: circle;
|
||||||
|
padding-left: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid lighten(#282c37, 55%);
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 5px 0;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #2b90d9;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
border: 0;
|
||||||
|
background: #2b90d9;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: lighten(#2b90d9, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard__top-bar {
|
.dashboard__top-bar {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
.api-descriptions {
|
||||||
|
.address {
|
||||||
|
samp {
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
&.method {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,13 +4,5 @@ class HomeController < ApplicationController
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
|
|
||||||
def index
|
def index
|
||||||
feed = Feed.new(:home, current_user.account)
|
|
||||||
@statuses = feed.get(20, (params[:offset] || 0).to_i)
|
|
||||||
end
|
|
||||||
|
|
||||||
def mentions
|
|
||||||
feed = Feed.new(:mentions, current_user.account)
|
|
||||||
@statuses = feed.get(20, (params[:offset] || 0).to_i)
|
|
||||||
render action: :index
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,4 +11,8 @@ module ApplicationHelper
|
||||||
def local_id?(id)
|
def local_id?(id)
|
||||||
id.start_with?("tag:#{Rails.configuration.x.local_domain}")
|
id.start_with?("tag:#{Rails.configuration.x.local_domain}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def active_nav_class(path)
|
||||||
|
current_page?(path) ? 'active' : ''
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,11 +18,11 @@ class PrecomputeFeedService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def home(account)
|
def home(account)
|
||||||
Status.where(account: [account] + account.following).with_includes.with_counts
|
Status.where(account: [account] + account.following).with_includes.with_counters
|
||||||
end
|
end
|
||||||
|
|
||||||
def mentions(account)
|
def mentions(account)
|
||||||
Status.where(id: Mention.where(account: account).pluck(:status_id)).with_includes.with_counts
|
Status.where(id: Mention.where(account: account).pluck(:status_id)).with_includes.with_counters
|
||||||
end
|
end
|
||||||
|
|
||||||
def key(type, id)
|
def key(type, id)
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<div class="page-header">
|
|
||||||
<h1><%= t('.title') %></h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p><%= link_to t('.new'), new_oauth_application_path, class: 'btn btn-success' %></p>
|
|
||||||
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th><%= t('.name') %></th>
|
|
||||||
<th><%= t('.callback_url') %></th>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% @applications.each do |application| %>
|
|
||||||
<tr id="application_<%= application.id %>">
|
|
||||||
<td><%= link_to application.name, oauth_application_path(application) %></td>
|
|
||||||
<td><%= application.redirect_uri %></td>
|
|
||||||
<td><%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(application), class: 'btn btn-link' %></td>
|
|
||||||
<td><%= render 'delete_form', application: application %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
19
app/views/doorkeeper/applications/index.html.haml
Normal file
19
app/views/doorkeeper/applications/index.html.haml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
Applications
|
||||||
|
|
||||||
|
%p= link_to t('.new'), new_oauth_application_path, class: 'btn btn-success'
|
||||||
|
|
||||||
|
%table.table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th= t('.name')
|
||||||
|
%th= t('.callback_url')
|
||||||
|
%th
|
||||||
|
%th
|
||||||
|
%tbody
|
||||||
|
- @applications.each do |application|
|
||||||
|
%tr
|
||||||
|
%td= link_to application.name, oauth_application_path(application)
|
||||||
|
%td= application.redirect_uri
|
||||||
|
%td= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(application), class: 'btn btn-link'
|
||||||
|
%td= render 'delete_form', application: application
|
|
@ -1,5 +0,0 @@
|
||||||
<%- submit_btn_css ||= 'btn btn-link' %>
|
|
||||||
<%= form_tag oauth_authorized_application_path(application) do %>
|
|
||||||
<input type="hidden" name="_method" value="delete">
|
|
||||||
<%= submit_tag t('doorkeeper.authorized_applications.buttons.revoke'), onclick: "return confirm('#{ t('doorkeeper.authorized_applications.confirmations.revoke') }')", class: submit_btn_css %>
|
|
||||||
<% end %>
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
= form_tag oauth_authorized_application_path(application) do
|
||||||
|
%input{type: "hidden", name: "_method", value: "delete"}
|
||||||
|
= submit_tag 'Revoke', class: 'btn'
|
|
@ -1,25 +0,0 @@
|
||||||
<header class="page-header">
|
|
||||||
<h1><%= t('doorkeeper.authorized_applications.index.title') %></h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main role="main">
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th><%= t('doorkeeper.authorized_applications.index.application') %></th>
|
|
||||||
<th><%= t('doorkeeper.authorized_applications.index.created_at') %></th>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% @applications.each do |application| %>
|
|
||||||
<tr>
|
|
||||||
<td><%= application.name %></td>
|
|
||||||
<td><%= application.created_at.strftime(t('doorkeeper.authorized_applications.index.date_format')) %></td>
|
|
||||||
<td><%= render 'delete_form', application: application %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</main>
|
|
16
app/views/doorkeeper/authorized_applications/index.html.haml
Normal file
16
app/views/doorkeeper/authorized_applications/index.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
Authorized apps
|
||||||
|
|
||||||
|
%p
|
||||||
|
You can register a new OAuth2 app
|
||||||
|
= link_to 'here', oauth_applications_path
|
||||||
|
|
||||||
|
%table.table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th= t('doorkeeper.authorized_applications.index.application')
|
||||||
|
%th
|
||||||
|
- @applications.each do |application|
|
||||||
|
%tr
|
||||||
|
%td= application.name
|
||||||
|
%td= render 'delete_form', application: application
|
|
@ -1,3 +1,97 @@
|
||||||
.activity-stream.activity-stream-embedded
|
%h3 OAuth2
|
||||||
- @statuses.each do |status|
|
%p All API methods require a valid access token.
|
||||||
= render partial: 'stream_entries/status', locals: { status: status, include_threads: false, is_successor: false, is_predecessor: false }
|
|
||||||
|
%h3 Statuses
|
||||||
|
%ul.api-descriptions
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method GET
|
||||||
|
%samp /api/statuses/home
|
||||||
|
.description
|
||||||
|
Returns user's home timeline
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method GET
|
||||||
|
%samp /api/statuses/mentions
|
||||||
|
.description
|
||||||
|
Returns user's mentions timeline
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method POST
|
||||||
|
%samp /api/statuses
|
||||||
|
.options
|
||||||
|
Options:
|
||||||
|
= succeed ',' do
|
||||||
|
%samp status
|
||||||
|
%samp in_reply_to_id
|
||||||
|
.description
|
||||||
|
Creates a new status, optionally as a response to another, from user's account. Returns the new status.
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method GET
|
||||||
|
%samp /api/statuses/:id
|
||||||
|
.description
|
||||||
|
Returns a single status
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method POST
|
||||||
|
%samp /api/statuses/:id/reblog
|
||||||
|
.description
|
||||||
|
Reblogs a status from user's account. Returns the target status.
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method POST
|
||||||
|
%samp /api/statuses/:id/favourite
|
||||||
|
.description
|
||||||
|
Favourites a status from user's account. Returns the target status.
|
||||||
|
|
||||||
|
%h3 Accounts
|
||||||
|
%ul.api-descriptions
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method GET
|
||||||
|
%samp /api/accounts/:id
|
||||||
|
.description
|
||||||
|
Returns a single account
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method GET
|
||||||
|
%samp /api/accounts/:id/statuses
|
||||||
|
.description
|
||||||
|
Returns an account's statuses
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method GET
|
||||||
|
%samp /api/accounts/:id/followers
|
||||||
|
.description
|
||||||
|
Returns accounts following an account
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method GET
|
||||||
|
%samp /api/accounts/:id/following
|
||||||
|
.description
|
||||||
|
Returns the accounts the target account follows
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method POST
|
||||||
|
%samp /api/accounts/:id/follow
|
||||||
|
.description
|
||||||
|
Follows target account from the user's account. Returns the target account.
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method POST
|
||||||
|
%samp /api/accounts/:id/unfollow
|
||||||
|
.description
|
||||||
|
Unfollows target account from the user's account. Returns the target account.
|
||||||
|
|
||||||
|
%h3 Follows
|
||||||
|
%ul.api-descriptions
|
||||||
|
%li
|
||||||
|
.address
|
||||||
|
%samp.method POST
|
||||||
|
%samp /api/follows
|
||||||
|
.options
|
||||||
|
Options:
|
||||||
|
%samp uri
|
||||||
|
.description
|
||||||
|
Follows a user, regardless of where they are, from user's account. URI assumed to be of username@domain form. Returns the target account.
|
||||||
|
|
|
@ -6,38 +6,23 @@
|
||||||
.dashboard__current-user
|
.dashboard__current-user
|
||||||
= link_to account_path(current_user.account) do
|
= link_to account_path(current_user.account) do
|
||||||
= image_tag current_user.account.avatar.url(:medium), class: 'dashboard__current-user__avatar'
|
= image_tag current_user.account.avatar.url(:medium), class: 'dashboard__current-user__avatar'
|
||||||
%strong.dashboard__current-user__display-name= current_user.account.display_name
|
%strong.dashboard__current-user__display-name= current_user.account.display_name.blank? ? current_user.account.username : current_user.account.display_name
|
||||||
%span.dashboard__current-user__username= "@#{current_user.account.username}"
|
%span.dashboard__current-user__username= "@#{current_user.account.username}"
|
||||||
%ul
|
%ul
|
||||||
%li.active
|
%li{ class: active_nav_class(root_path) }
|
||||||
= link_to root_path do
|
= link_to root_path do
|
||||||
= fa_icon 'home'
|
= fa_icon 'home'
|
||||||
Home
|
Home
|
||||||
%li
|
%li{ class: active_nav_class(oauth_authorized_applications_path) }
|
||||||
= link_to mentions_path do
|
|
||||||
= fa_icon 'at'
|
|
||||||
Mentions
|
|
||||||
%li
|
|
||||||
= link_to root_path do
|
|
||||||
= fa_icon 'group'
|
|
||||||
Subscriptions
|
|
||||||
%li
|
|
||||||
= link_to oauth_authorized_applications_path do
|
= link_to oauth_authorized_applications_path do
|
||||||
= fa_icon 'shield'
|
= fa_icon 'shield'
|
||||||
Authorized apps
|
Authorized apps
|
||||||
%li
|
|
||||||
= link_to root_path do
|
|
||||||
= fa_icon 'user'
|
|
||||||
Edit profile
|
|
||||||
%li
|
|
||||||
= link_to edit_registration_path(current_user) do
|
|
||||||
= fa_icon 'wrench'
|
|
||||||
Change password
|
|
||||||
.dashboard__content
|
.dashboard__content
|
||||||
.dashboard__top-bar
|
.dashboard__top-bar
|
||||||
Home
|
= content_for?(:page_title) ? yield(:page_title) : 'Mastodon'
|
||||||
%ul
|
%ul
|
||||||
%li= link_to fa_icon('sign-out'), destroy_user_session_path, method: :delete
|
%li= link_to fa_icon('gear'), edit_registration_path(current_user), title: 'Change password'
|
||||||
|
%li= link_to fa_icon('sign-out'), destroy_user_session_path, method: :delete, title: 'Sign out'
|
||||||
.dashboard__content__content= yield
|
.dashboard__content__content= yield
|
||||||
.footer
|
.footer
|
||||||
.domain= Rails.configuration.x.local_domain
|
.domain= Rails.configuration.x.local_domain
|
||||||
|
|
|
@ -14,18 +14,16 @@ Doorkeeper.configure do
|
||||||
end
|
end
|
||||||
|
|
||||||
# If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
|
# If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
|
||||||
# admin_authenticator do
|
admin_authenticator do
|
||||||
# # Put your admin authentication logic here.
|
current_user || redirect_to(new_user_session_url)
|
||||||
# # Example implementation:
|
end
|
||||||
# Admin.find_by_id(session[:admin_id]) || redirect_to(new_admin_session_url)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# Authorization Code expiration time (default 10 minutes).
|
# Authorization Code expiration time (default 10 minutes).
|
||||||
# authorization_code_expires_in 10.minutes
|
# authorization_code_expires_in 10.minutes
|
||||||
|
|
||||||
# Access token expiration time (default 2 hours).
|
# Access token expiration time (default 2 hours).
|
||||||
# If you want to disable expiration, set this to nil.
|
# If you want to disable expiration, set this to nil.
|
||||||
# access_token_expires_in 2.hours
|
# access_token_expires_in nil
|
||||||
|
|
||||||
# Assign a custom TTL for implicit grants.
|
# Assign a custom TTL for implicit grants.
|
||||||
# custom_access_token_expires_in do |oauth_client|
|
# custom_access_token_expires_in do |oauth_client|
|
||||||
|
|
|
@ -49,7 +49,5 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/mentions', to: 'home#mentions', as: :mentions
|
|
||||||
|
|
||||||
root 'home#index'
|
root 'home#index'
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue