Merge branch 'develop' of https://code.gab.com/gab/social/gab-social into develop
This commit is contained in:
commit
8d3d7efe34
|
@ -10,7 +10,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
before_action :set_body_classes, only: [:new, :create, :edit, :update]
|
before_action :set_body_classes, only: [:new, :create, :edit, :update]
|
||||||
before_action :set_cache_headers, only: [:edit, :update]
|
before_action :set_cache_headers, only: [:edit, :update]
|
||||||
prepend_before_action :check_if_password_email_identical, only: [:create]
|
prepend_before_action :check_if_password_email_identical, only: [:create]
|
||||||
|
if ENV.fetch('GAB_CAPTCHA_CLIENT_KEY', '').empty? || ENV.fetch('GAB_CAPTCHA_CLIENT_KEY', '').nil?
|
||||||
|
# captcha disabled if key not defined
|
||||||
|
else
|
||||||
prepend_before_action :check_captcha, only: [:create]
|
prepend_before_action :check_captcha, only: [:create]
|
||||||
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
set_challenge_buster
|
set_challenge_buster
|
||||||
|
|
|
@ -4,123 +4,4 @@
|
||||||
# <https://tools.ietf.org/html/draft-cavage-http-signatures-06>
|
# <https://tools.ietf.org/html/draft-cavage-http-signatures-06>
|
||||||
module SignatureVerification
|
module SignatureVerification
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def signed_request?
|
|
||||||
request.headers['Signature'].present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def signature_verification_failure_reason
|
|
||||||
return @signature_verification_failure_reason if defined?(@signature_verification_failure_reason)
|
|
||||||
end
|
|
||||||
|
|
||||||
def signed_request_account
|
|
||||||
return @signed_request_account if defined?(@signed_request_account)
|
|
||||||
|
|
||||||
unless signed_request?
|
|
||||||
@signature_verification_failure_reason = 'Request not signed'
|
|
||||||
@signed_request_account = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if request.headers['Date'].present? && !matches_time_window?
|
|
||||||
@signature_verification_failure_reason = 'Signed request date outside acceptable time window'
|
|
||||||
@signed_request_account = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
raw_signature = request.headers['Signature']
|
|
||||||
signature_params = {}
|
|
||||||
|
|
||||||
raw_signature.split(',').each do |part|
|
|
||||||
parsed_parts = part.match(/([a-z]+)="([^"]+)"/i)
|
|
||||||
next if parsed_parts.nil? || parsed_parts.size != 3
|
|
||||||
signature_params[parsed_parts[1]] = parsed_parts[2]
|
|
||||||
end
|
|
||||||
|
|
||||||
if incompatible_signature?(signature_params)
|
|
||||||
@signature_verification_failure_reason = 'Incompatible request signature'
|
|
||||||
@signed_request_account = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
account = nil
|
|
||||||
|
|
||||||
if account.nil?
|
|
||||||
@signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
|
|
||||||
@signed_request_account = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
signature = Base64.decode64(signature_params['signature'])
|
|
||||||
compare_signed_string = build_signed_string(signature_params['headers'])
|
|
||||||
|
|
||||||
return account unless verify_signature(account, signature, compare_signed_string).nil?
|
|
||||||
|
|
||||||
account = nil
|
|
||||||
|
|
||||||
if account.nil?
|
|
||||||
@signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
|
|
||||||
@signed_request_account = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
return account unless verify_signature(account, signature, compare_signed_string).nil?
|
|
||||||
|
|
||||||
# : todo :
|
|
||||||
@signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
|
||||||
@signed_request_account = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def request_body
|
|
||||||
@request_body ||= request.raw_post
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def verify_signature(account, signature, compare_signed_string)
|
|
||||||
if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
|
|
||||||
@signed_request_account = account
|
|
||||||
@signed_request_account
|
|
||||||
end
|
|
||||||
rescue OpenSSL::PKey::RSAError
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_signed_string(signed_headers)
|
|
||||||
signed_headers = 'date' if signed_headers.blank?
|
|
||||||
|
|
||||||
signed_headers.downcase.split(' ').map do |signed_header|
|
|
||||||
if signed_header == Request::REQUEST_TARGET
|
|
||||||
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
|
||||||
elsif signed_header == 'digest'
|
|
||||||
"digest: #{body_digest}"
|
|
||||||
else
|
|
||||||
"#{signed_header}: #{request.headers[to_header_name(signed_header)]}"
|
|
||||||
end
|
|
||||||
end.join("\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
def matches_time_window?
|
|
||||||
begin
|
|
||||||
time_sent = Time.httpdate(request.headers['Date'])
|
|
||||||
rescue ArgumentError
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
(Time.now.utc - time_sent).abs <= 12.hours
|
|
||||||
end
|
|
||||||
|
|
||||||
def body_digest
|
|
||||||
"SHA-256=#{Digest::SHA256.base64digest(request_body)}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_header_name(name)
|
|
||||||
name.split(/-/).map(&:capitalize).join('-')
|
|
||||||
end
|
|
||||||
|
|
||||||
def incompatible_signature?(signature_params)
|
|
||||||
signature_params['keyId'].blank? ||
|
|
||||||
signature_params['signature'].blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,11 +12,12 @@ class CharacterCounter extends React.PureComponent {
|
||||||
render() {
|
render() {
|
||||||
const { text, max } = this.props
|
const { text, max } = this.props
|
||||||
|
|
||||||
const actualRadius = 16
|
const actualRadius = 10
|
||||||
const radius = 12
|
const radius = 8
|
||||||
const circumference = 2 * Math.PI * radius
|
const circumference = 2 * Math.PI * radius
|
||||||
const diff = Math.min(length(text), max) / max
|
const diff = Math.min(length(text), max) / max
|
||||||
const dashoffset = circumference * (1 - diff)
|
const dashoffset = circumference * (1 - diff)
|
||||||
|
const circleClass = length(text) > max ? _s.strokeError : _s.strokeBrand
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.d, _s.mr10, _s.jcCenter, _s.aiCenter].join(' ')}>
|
<div className={[_s.d, _s.mr10, _s.jcCenter, _s.aiCenter].join(' ')}>
|
||||||
|
@ -31,8 +32,8 @@ class CharacterCounter extends React.PureComponent {
|
||||||
cy={actualRadius}
|
cy={actualRadius}
|
||||||
r={radius}
|
r={radius}
|
||||||
fill='none'
|
fill='none'
|
||||||
stroke='#e6e6e6'
|
|
||||||
strokeWidth='2'
|
strokeWidth='2'
|
||||||
|
className={_s.strokeSecondary}
|
||||||
/>
|
/>
|
||||||
<circle
|
<circle
|
||||||
style={{
|
style={{
|
||||||
|
@ -43,9 +44,9 @@ class CharacterCounter extends React.PureComponent {
|
||||||
cx={actualRadius}
|
cx={actualRadius}
|
||||||
cy={actualRadius}
|
cy={actualRadius}
|
||||||
r={radius}
|
r={radius}
|
||||||
strokeWidth='2'
|
strokeWidth='2.25'
|
||||||
strokeLinecap='round'
|
strokeLinecap='round'
|
||||||
stroke='#21cf7a'
|
className={circleClass}
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import {
|
import {
|
||||||
CX,
|
CX,
|
||||||
MODAL_COMPOSE,
|
MODAL_COMPOSE,
|
||||||
|
MAX_POST_CHARACTER_COUNT,
|
||||||
POPOVER_COMPOSE_POST_DESTINATION,
|
POPOVER_COMPOSE_POST_DESTINATION,
|
||||||
} from '../../../constants'
|
} from '../../../constants'
|
||||||
import { openModal } from '../../../actions/modal'
|
import { openModal } from '../../../actions/modal'
|
||||||
|
@ -14,6 +15,7 @@ import Avatar from '../../../components/avatar'
|
||||||
import Button from '../../../components/button'
|
import Button from '../../../components/button'
|
||||||
import Icon from '../../../components/icon'
|
import Icon from '../../../components/icon'
|
||||||
import Text from '../../../components/text'
|
import Text from '../../../components/text'
|
||||||
|
import CharacterCounter from '../../../components/character_counter'
|
||||||
|
|
||||||
class ComposeDestinationHeader extends ImmutablePureComponent {
|
class ComposeDestinationHeader extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ class ComposeDestinationHeader extends ImmutablePureComponent {
|
||||||
composeGroup,
|
composeGroup,
|
||||||
composeGroupId,
|
composeGroupId,
|
||||||
formLocation,
|
formLocation,
|
||||||
|
text,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const isIntroduction = formLocation === 'introduction'
|
const isIntroduction = formLocation === 'introduction'
|
||||||
|
@ -85,6 +88,10 @@ class ComposeDestinationHeader extends ImmutablePureComponent {
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
{
|
||||||
|
!!text &&
|
||||||
|
<CharacterCounter max={MAX_POST_CHARACTER_COUNT} text={text} />
|
||||||
|
}
|
||||||
{
|
{
|
||||||
!isModal && !isIntroduction &&
|
!isModal && !isIntroduction &&
|
||||||
<Button
|
<Button
|
||||||
|
@ -94,6 +101,7 @@ class ComposeDestinationHeader extends ImmutablePureComponent {
|
||||||
color='tertiary'
|
color='tertiary'
|
||||||
icon='fullscreen'
|
icon='fullscreen'
|
||||||
onClick={this.handleOnExpand}
|
onClick={this.handleOnExpand}
|
||||||
|
className={_s.ml10}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -106,6 +114,7 @@ const mapStateToProps = (state) => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
composeGroupId,
|
composeGroupId,
|
||||||
|
text: state.getIn(['compose', 'text']),
|
||||||
isReply: !!state.getIn(['compose', 'in_reply_to']),
|
isReply: !!state.getIn(['compose', 'in_reply_to']),
|
||||||
isEdit: state.getIn(['compose', 'id']) !== null,
|
isEdit: state.getIn(['compose', 'id']) !== null,
|
||||||
composeGroup: state.getIn(['groups', composeGroupId]),
|
composeGroup: state.getIn(['groups', composeGroupId]),
|
||||||
|
|
|
@ -54,7 +54,6 @@ class Followers extends ImmutablePureComponent {
|
||||||
scrollKey='followers'
|
scrollKey='followers'
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
showLoading={isLoading}
|
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
placeholderComponent={AccountPlaceholder}
|
placeholderComponent={AccountPlaceholder}
|
||||||
placeholderCount={4}
|
placeholderCount={4}
|
||||||
|
|
|
@ -54,7 +54,6 @@ class Following extends ImmutablePureComponent {
|
||||||
scrollKey='following'
|
scrollKey='following'
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
showLoading={isLoading}
|
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
placeholderComponent={AccountPlaceholder}
|
placeholderComponent={AccountPlaceholder}
|
||||||
placeholderCount={4}
|
placeholderCount={4}
|
||||||
|
|
|
@ -1110,6 +1110,10 @@ pre {
|
||||||
fill: var(--color_primary);
|
fill: var(--color_primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fillSecondary {
|
||||||
|
fill: var(--text_color_secondary);
|
||||||
|
}
|
||||||
|
|
||||||
.fillWhite {
|
.fillWhite {
|
||||||
fill: var(--color_white);
|
fill: var(--color_white);
|
||||||
}
|
}
|
||||||
|
@ -1133,6 +1137,10 @@ pre {
|
||||||
color: var(--navigation_brand);
|
color: var(--navigation_brand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.strokeBrand { stroke: var(--color_brand); }
|
||||||
|
.strokeSecondary { stroke: var(--solid_color_secondary); }
|
||||||
|
.strokeError { stroke: var(--color_red); }
|
||||||
|
|
||||||
.navigationUnderlineActive:after {
|
.navigationUnderlineActive:after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
# username :string default(""), not null
|
# username :string default(""), not null
|
||||||
# domain :string
|
# domain :string
|
||||||
# secret :string default(""), not null
|
# secret :string default(""), not null
|
||||||
# private_key :text
|
|
||||||
# public_key :text default(""), not null
|
|
||||||
# remote_url :string default(""), not null
|
# remote_url :string default(""), not null
|
||||||
# salmon_url :string default(""), not null
|
# salmon_url :string default(""), not null
|
||||||
# hub_url :string default(""), not null
|
# hub_url :string default(""), not null
|
||||||
|
@ -54,6 +52,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class Account < ApplicationRecord
|
class Account < ApplicationRecord
|
||||||
|
self.ignored_columns = ["private_key"]
|
||||||
|
self.ignored_columns = ["public_key"]
|
||||||
USERNAME_RE = /[a-z0-9_]+([a-z0-9_\.-]+[a-z0-9_]+)?/i
|
USERNAME_RE = /[a-z0-9_]+([a-z0-9_\.-]+[a-z0-9_]+)?/i
|
||||||
MENTION_RE = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
|
MENTION_RE = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
|
||||||
MIN_FOLLOWERS_DISCOVERY = 10
|
MIN_FOLLOWERS_DISCOVERY = 10
|
||||||
|
@ -200,10 +200,6 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def keypair
|
|
||||||
@keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
|
|
||||||
end
|
|
||||||
|
|
||||||
def tags_as_strings=(tag_names)
|
def tags_as_strings=(tag_names)
|
||||||
tag_names.map! { |name| name.mb_chars.downcase.to_s }
|
tag_names.map! { |name| name.mb_chars.downcase.to_s }
|
||||||
tag_names.uniq!
|
tag_names.uniq!
|
||||||
|
@ -279,21 +275,6 @@ class Account < ApplicationRecord
|
||||||
self.fields = tmp
|
self.fields = tmp
|
||||||
end
|
end
|
||||||
|
|
||||||
def magic_key
|
|
||||||
modulus, exponent = [keypair.public_key.n, keypair.public_key.e].map do |component|
|
|
||||||
result = []
|
|
||||||
|
|
||||||
until component.zero?
|
|
||||||
result << [component % 256].pack('C')
|
|
||||||
component >>= 8
|
|
||||||
end
|
|
||||||
|
|
||||||
result.reverse.join
|
|
||||||
end
|
|
||||||
|
|
||||||
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_with_optional_media!
|
def save_with_optional_media!
|
||||||
save!
|
save!
|
||||||
rescue ActiveRecord::RecordInvalid
|
rescue ActiveRecord::RecordInvalid
|
||||||
|
@ -444,7 +425,6 @@ class Account < ApplicationRecord
|
||||||
@emojis ||= CustomEmoji.from_text(emojifiable_text)
|
@emojis ||= CustomEmoji.from_text(emojifiable_text)
|
||||||
end
|
end
|
||||||
|
|
||||||
before_create :generate_keys
|
|
||||||
before_validation :prepare_contents, if: :local?
|
before_validation :prepare_contents, if: :local?
|
||||||
before_validation :prepare_username, on: :create
|
before_validation :prepare_username, on: :create
|
||||||
before_destroy :clean_feed_manager
|
before_destroy :clean_feed_manager
|
||||||
|
@ -460,14 +440,6 @@ class Account < ApplicationRecord
|
||||||
username&.squish!
|
username&.squish!
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_keys
|
|
||||||
return unless local? && !Rails.env.test?
|
|
||||||
|
|
||||||
keypair = OpenSSL::PKey::RSA.new(2048)
|
|
||||||
self.private_key = keypair.to_pem
|
|
||||||
self.public_key = keypair.public_key.to_pem
|
|
||||||
end
|
|
||||||
|
|
||||||
def normalize_domain
|
def normalize_domain
|
||||||
return if local?
|
return if local?
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# member_count :integer default(0)
|
# member_count :integer default(0)
|
||||||
# slug :text
|
# slug :text
|
||||||
# is_private :boolean default(FALSE)
|
# is_private :boolean default(FALSE)
|
||||||
# is_visible :boolean default(FALSE)
|
# is_visible :boolean default(TRUE)
|
||||||
# tags :string default([]), is an Array
|
# tags :string default([]), is an Array
|
||||||
# password :string
|
# password :string
|
||||||
# group_category_id :integer
|
# group_category_id :integer
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
# list_id :bigint(8) not null
|
# list_id :bigint(8) not null
|
||||||
# account_id :bigint(8) not null
|
# account_id :bigint(8) not null
|
||||||
# follow_id :bigint(8) default(1)
|
# follow_id :bigint(8)
|
||||||
#
|
#
|
||||||
|
|
||||||
class ListAccount < ApplicationRecord
|
class ListAccount < ApplicationRecord
|
||||||
|
|
|
@ -101,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "username", default: "", null: false
|
t.string "username", default: "", null: false
|
||||||
t.string "domain"
|
t.string "domain"
|
||||||
t.string "secret", default: "", null: false
|
t.string "secret", default: "", null: false
|
||||||
t.text "private_key"
|
|
||||||
t.text "public_key", default: "", null: false
|
|
||||||
t.string "remote_url", default: "", null: false
|
t.string "remote_url", default: "", null: false
|
||||||
t.string "salmon_url", default: "", null: false
|
t.string "salmon_url", default: "", null: false
|
||||||
t.string "hub_url", default: "", null: false
|
t.string "hub_url", default: "", null: false
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class RemovePrivateKeyFromAccounts < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
safety_assured { remove_column :accounts, :private_key, :text }
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class RemovePublicKeyFromAccounts < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
safety_assured { remove_column :accounts, :public_key, :text }
|
||||||
|
end
|
||||||
|
end
|
38
db/schema.rb
38
db/schema.rb
|
@ -10,9 +10,12 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
ActiveRecord::Schema.define(version: 2021_02_16_022902) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
|
enable_extension "mongo_fdw"
|
||||||
|
enable_extension "pg_stat_statements"
|
||||||
|
enable_extension "pgstattuple"
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
create_table "account_conversations", force: :cascade do |t|
|
create_table "account_conversations", force: :cascade do |t|
|
||||||
|
@ -24,7 +27,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.integer "lock_version", default: 0, null: false
|
t.integer "lock_version", default: 0, null: false
|
||||||
t.boolean "unread", default: false, null: false
|
t.boolean "unread", default: false, null: false
|
||||||
t.index ["account_id", "conversation_id", "participant_account_ids"], name: "index_unique_conversations", unique: true
|
t.index ["account_id", "conversation_id", "participant_account_ids"], name: "index_unique_conversations", unique: true
|
||||||
t.index ["account_id"], name: "index_account_conversations_on_account_id"
|
|
||||||
t.index ["conversation_id"], name: "index_account_conversations_on_conversation_id"
|
t.index ["conversation_id"], name: "index_account_conversations_on_conversation_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "username", default: "", null: false
|
t.string "username", default: "", null: false
|
||||||
t.string "domain"
|
t.string "domain"
|
||||||
t.string "secret", default: "", null: false
|
t.string "secret", default: "", null: false
|
||||||
t.text "private_key"
|
|
||||||
t.text "public_key", default: "", null: false
|
|
||||||
t.string "remote_url", default: "", null: false
|
t.string "remote_url", default: "", null: false
|
||||||
t.string "salmon_url", default: "", null: false
|
t.string "salmon_url", default: "", null: false
|
||||||
t.string "hub_url", default: "", null: false
|
t.string "hub_url", default: "", null: false
|
||||||
|
@ -112,11 +112,11 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "url"
|
t.string "url"
|
||||||
t.string "avatar_file_name"
|
t.string "avatar_file_name"
|
||||||
t.string "avatar_content_type"
|
t.string "avatar_content_type"
|
||||||
t.bigint "avatar_file_size"
|
t.integer "avatar_file_size"
|
||||||
t.datetime "avatar_updated_at"
|
t.datetime "avatar_updated_at"
|
||||||
t.string "header_file_name"
|
t.string "header_file_name"
|
||||||
t.string "header_content_type"
|
t.string "header_content_type"
|
||||||
t.bigint "header_file_size"
|
t.integer "header_file_size"
|
||||||
t.datetime "header_updated_at"
|
t.datetime "header_updated_at"
|
||||||
t.string "avatar_remote_url"
|
t.string "avatar_remote_url"
|
||||||
t.datetime "subscription_expires_at"
|
t.datetime "subscription_expires_at"
|
||||||
|
@ -135,10 +135,10 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "actor_type"
|
t.string "actor_type"
|
||||||
t.boolean "discoverable"
|
t.boolean "discoverable"
|
||||||
t.string "also_known_as", array: true
|
t.string "also_known_as", array: true
|
||||||
t.boolean "is_pro", default: false, null: false
|
|
||||||
t.datetime "pro_expires_at"
|
|
||||||
t.datetime "silenced_at"
|
t.datetime "silenced_at"
|
||||||
t.datetime "suspended_at"
|
t.datetime "suspended_at"
|
||||||
|
t.boolean "is_pro", default: false, null: false
|
||||||
|
t.datetime "pro_expires_at"
|
||||||
t.boolean "is_verified", default: false, null: false
|
t.boolean "is_verified", default: false, null: false
|
||||||
t.boolean "is_donor", default: false, null: false
|
t.boolean "is_donor", default: false, null: false
|
||||||
t.boolean "is_investor", default: false, null: false
|
t.boolean "is_investor", default: false, null: false
|
||||||
|
@ -179,7 +179,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.bigint "user_id"
|
t.bigint "user_id"
|
||||||
t.string "dump_file_name"
|
t.string "dump_file_name"
|
||||||
t.string "dump_content_type"
|
t.string "dump_content_type"
|
||||||
t.bigint "dump_file_size"
|
t.integer "dump_file_size"
|
||||||
t.datetime "dump_updated_at"
|
t.datetime "dump_updated_at"
|
||||||
t.boolean "processed", default: false, null: false
|
t.boolean "processed", default: false, null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
|
@ -257,7 +257,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "domain"
|
t.string "domain"
|
||||||
t.string "image_file_name"
|
t.string "image_file_name"
|
||||||
t.string "image_content_type"
|
t.string "image_content_type"
|
||||||
t.bigint "image_file_size"
|
t.integer "image_file_size"
|
||||||
t.datetime "image_updated_at"
|
t.datetime "image_updated_at"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
@ -325,9 +325,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["account_id", "group_id"], name: "index_group_accounts_on_account_id_and_group_id", unique: true
|
t.index ["account_id", "group_id"], name: "index_group_accounts_on_account_id_and_group_id", unique: true
|
||||||
t.index ["account_id"], name: "index_group_accounts_on_account_id"
|
|
||||||
t.index ["group_id", "account_id"], name: "index_group_accounts_on_group_id_and_account_id"
|
t.index ["group_id", "account_id"], name: "index_group_accounts_on_group_id_and_account_id"
|
||||||
t.index ["group_id"], name: "index_group_accounts_on_group_id"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "group_categories", force: :cascade do |t|
|
create_table "group_categories", force: :cascade do |t|
|
||||||
|
@ -342,7 +340,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["account_id", "group_id"], name: "index_group_join_requests_on_account_id_and_group_id", unique: true
|
t.index ["account_id", "group_id"], name: "index_group_join_requests_on_account_id_and_group_id", unique: true
|
||||||
t.index ["account_id"], name: "index_group_join_requests_on_account_id"
|
|
||||||
t.index ["group_id"], name: "index_group_join_requests_on_group_id"
|
t.index ["group_id"], name: "index_group_join_requests_on_group_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -351,7 +348,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.bigint "group_id", null: false
|
t.bigint "group_id", null: false
|
||||||
t.index ["group_id"], name: "index_group_pinned_statuses_on_group_id"
|
t.index ["group_id"], name: "index_group_pinned_statuses_on_group_id"
|
||||||
t.index ["status_id", "group_id"], name: "index_group_pinned_statuses_on_status_id_and_group_id", unique: true
|
t.index ["status_id", "group_id"], name: "index_group_pinned_statuses_on_status_id_and_group_id", unique: true
|
||||||
t.index ["status_id"], name: "index_group_pinned_statuses_on_status_id"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "group_removed_accounts", force: :cascade do |t|
|
create_table "group_removed_accounts", force: :cascade do |t|
|
||||||
|
@ -360,9 +356,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["account_id", "group_id"], name: "index_group_removed_accounts_on_account_id_and_group_id", unique: true
|
t.index ["account_id", "group_id"], name: "index_group_removed_accounts_on_account_id_and_group_id", unique: true
|
||||||
t.index ["account_id"], name: "index_group_removed_accounts_on_account_id"
|
|
||||||
t.index ["group_id", "account_id"], name: "index_group_removed_accounts_on_group_id_and_account_id"
|
t.index ["group_id", "account_id"], name: "index_group_removed_accounts_on_group_id_and_account_id"
|
||||||
t.index ["group_id"], name: "index_group_removed_accounts_on_group_id"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "groups", force: :cascade do |t|
|
create_table "groups", force: :cascade do |t|
|
||||||
|
@ -371,7 +365,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "description", null: false
|
t.string "description", null: false
|
||||||
t.string "cover_image_file_name"
|
t.string "cover_image_file_name"
|
||||||
t.string "cover_image_content_type"
|
t.string "cover_image_content_type"
|
||||||
t.bigint "cover_image_file_size"
|
t.integer "cover_image_file_size"
|
||||||
t.datetime "cover_image_updated_at"
|
t.datetime "cover_image_updated_at"
|
||||||
t.boolean "is_nsfw", default: false, null: false
|
t.boolean "is_nsfw", default: false, null: false
|
||||||
t.boolean "is_featured", default: false, null: false
|
t.boolean "is_featured", default: false, null: false
|
||||||
|
@ -438,7 +432,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.bigint "status_id"
|
t.bigint "status_id"
|
||||||
t.string "file_file_name"
|
t.string "file_file_name"
|
||||||
t.string "file_content_type"
|
t.string "file_content_type"
|
||||||
t.bigint "file_file_size"
|
t.integer "file_file_size"
|
||||||
t.datetime "file_updated_at"
|
t.datetime "file_updated_at"
|
||||||
t.string "remote_url", default: "", null: false
|
t.string "remote_url", default: "", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
|
@ -570,6 +564,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.integer "lock_version", default: 0, null: false
|
t.integer "lock_version", default: 0, null: false
|
||||||
t.index ["account_id"], name: "index_polls_on_account_id"
|
t.index ["account_id"], name: "index_polls_on_account_id"
|
||||||
|
t.index ["created_at"], name: "index_polls_on_created_at"
|
||||||
t.index ["id", "lock_version"], name: "index_polls_on_id_and_lock_version"
|
t.index ["id", "lock_version"], name: "index_polls_on_id_and_lock_version"
|
||||||
t.index ["status_id"], name: "index_polls_on_status_id"
|
t.index ["status_id"], name: "index_polls_on_status_id"
|
||||||
end
|
end
|
||||||
|
@ -580,7 +575,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "description", default: "", null: false
|
t.string "description", default: "", null: false
|
||||||
t.string "image_file_name"
|
t.string "image_file_name"
|
||||||
t.string "image_content_type"
|
t.string "image_content_type"
|
||||||
t.bigint "image_file_size"
|
t.integer "image_file_size"
|
||||||
t.datetime "image_updated_at"
|
t.datetime "image_updated_at"
|
||||||
t.integer "type", default: 0, null: false
|
t.integer "type", default: 0, null: false
|
||||||
t.text "html", default: "", null: false
|
t.text "html", default: "", null: false
|
||||||
|
@ -676,14 +671,13 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.bigint "shortcut_id", null: false
|
t.bigint "shortcut_id", null: false
|
||||||
t.string "shortcut_type", default: "", null: false
|
t.string "shortcut_type", default: "", null: false
|
||||||
t.index ["account_id", "shortcut_id", "shortcut_type"], name: "index_shortcuts_on_account_id_and_shortcut_id_and_shortcut_type", unique: true
|
t.index ["account_id", "shortcut_id", "shortcut_type"], name: "index_shortcuts_on_account_id_and_shortcut_id_and_shortcut_type", unique: true
|
||||||
t.index ["account_id"], name: "index_shortcuts_on_account_id"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "site_uploads", force: :cascade do |t|
|
create_table "site_uploads", force: :cascade do |t|
|
||||||
t.string "var", default: "", null: false
|
t.string "var", default: "", null: false
|
||||||
t.string "file_file_name"
|
t.string "file_file_name"
|
||||||
t.string "file_content_type"
|
t.string "file_content_type"
|
||||||
t.bigint "file_file_size"
|
t.integer "file_file_size"
|
||||||
t.datetime "file_updated_at"
|
t.datetime "file_updated_at"
|
||||||
t.json "meta"
|
t.json "meta"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
|
@ -705,7 +699,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.bigint "status_id", null: false
|
t.bigint "status_id", null: false
|
||||||
t.bigint "status_bookmark_collection_id"
|
t.bigint "status_bookmark_collection_id"
|
||||||
t.index ["account_id", "status_id"], name: "index_status_bookmarks_on_account_id_and_status_id", unique: true
|
t.index ["account_id", "status_id"], name: "index_status_bookmarks_on_account_id_and_status_id", unique: true
|
||||||
t.index ["account_id"], name: "index_status_bookmarks_on_account_id"
|
|
||||||
t.index ["status_bookmark_collection_id"], name: "index_status_bookmarks_on_status_bookmark_collection_id"
|
t.index ["status_bookmark_collection_id"], name: "index_status_bookmarks_on_status_bookmark_collection_id"
|
||||||
t.index ["status_id"], name: "index_status_bookmarks_on_status_id"
|
t.index ["status_id"], name: "index_status_bookmarks_on_status_id"
|
||||||
end
|
end
|
||||||
|
@ -766,6 +759,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.text "markdown"
|
t.text "markdown"
|
||||||
t.datetime "expires_at"
|
t.datetime "expires_at"
|
||||||
t.boolean "has_quote"
|
t.boolean "has_quote"
|
||||||
|
t.index ["account_id", "id", "visibility", "created_at"], name: "index_statuses_20201206", order: { id: :desc }
|
||||||
t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20180106", order: { id: :desc }
|
t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20180106", order: { id: :desc }
|
||||||
t.index ["created_at"], name: "index_statuses_on_created_at"
|
t.index ["created_at"], name: "index_statuses_on_created_at"
|
||||||
t.index ["group_id"], name: "index_statuses_on_group_id"
|
t.index ["group_id"], name: "index_statuses_on_group_id"
|
||||||
|
|
|
@ -101,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "username", default: "", null: false
|
t.string "username", default: "", null: false
|
||||||
t.string "domain"
|
t.string "domain"
|
||||||
t.string "secret", default: "", null: false
|
t.string "secret", default: "", null: false
|
||||||
t.text "private_key"
|
|
||||||
t.text "public_key", default: "", null: false
|
|
||||||
t.string "remote_url", default: "", null: false
|
t.string "remote_url", default: "", null: false
|
||||||
t.string "salmon_url", default: "", null: false
|
t.string "salmon_url", default: "", null: false
|
||||||
t.string "hub_url", default: "", null: false
|
t.string "hub_url", default: "", null: false
|
||||||
|
|
|
@ -101,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||||
t.string "username", default: "", null: false
|
t.string "username", default: "", null: false
|
||||||
t.string "domain"
|
t.string "domain"
|
||||||
t.string "secret", default: "", null: false
|
t.string "secret", default: "", null: false
|
||||||
t.text "private_key"
|
|
||||||
t.text "public_key", default: "", null: false
|
|
||||||
t.string "remote_url", default: "", null: false
|
t.string "remote_url", default: "", null: false
|
||||||
t.string "salmon_url", default: "", null: false
|
t.string "salmon_url", default: "", null: false
|
||||||
t.string "hub_url", default: "", null: false
|
t.string "hub_url", default: "", null: false
|
||||||
|
|
|
@ -520,15 +520,5 @@ module GabSocial
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def rotate_keys_for_account(account, delay = 0)
|
|
||||||
if account.nil?
|
|
||||||
say('No such account', :red)
|
|
||||||
exit(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
old_key = account.private_key
|
|
||||||
new_key = OpenSSL::PKey::RSA.new(2048)
|
|
||||||
account.update(private_key: new_key.to_pem, public_key: new_key.public_key.to_pem)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
task fix_key_pairs: 'gabsocial:fix_key_pairs'
|
|
||||||
|
|
||||||
namespace :gabsocial do
|
|
||||||
desc 'Generates key pairs for migrated accounts'
|
|
||||||
task :fix_key_pairs => :environment do
|
|
||||||
Account.select(:id, :username, :private_key, :public_key).all.each do |a|
|
|
||||||
if a.public_key == "tobefilled"
|
|
||||||
keypair = OpenSSL::PKey::RSA.new(2048)
|
|
||||||
private_key = keypair.to_pem
|
|
||||||
public_key = keypair.public_key.to_pem
|
|
||||||
a.update_columns private_key: private_key, public_key: public_key
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in New Issue