Compare commits

...

9 Commits

Author SHA1 Message Date
nachtjasmin 7b3070de05
Add missing numeric value for "dislike" category
This is diverging behaviour from upstream and was fixed by me in [1]
already. It is working fine on queer.group and therefore now going to be
merged into this fork.

[1]: https://github.com/hometown-fork/hometown/pull/1321
2023-11-23 00:12:38 +01:00
nachtjasmin 8802fd30b5
Use upstream code for exclusive lists 2023-11-23 00:12:38 +01:00
Claire bf4a523877
Fix incoming status creation date not being restricted to standard ISO8601 (#27655) 2023-11-23 00:12:38 +01:00
nachtjasmin 27370f61cf
Move norss settings to privacy subpage 2023-11-23 00:12:38 +01:00
nachtjasmin a2e77cd359
Add site title to all mails 2023-11-23 00:12:38 +01:00
nachtjasmin 10639a4e1b
Fix several merge errors (whitespace, duplicate lines)
- Align webfinger_controller with upstream
- Remove validation from webhook (It's not in v4.2.1, I don't know where it came from)
- Remove show_application from other view (merge error)
- Remove duplicate display name from account header
- Fix misspelled className for navigation bar
2023-11-23 00:12:01 +01:00
nachtjasmin d0f076bc8b
Respect user settings for RSS feeds 2023-11-23 00:11:21 +01:00
nachtjasmin a0cf51a52c
Switch to the JS-based start page for now
I like the plain homepage more, but for now I just want to get it
running.
2023-11-23 00:11:21 +01:00
nachtjasmin 8f2ced63e2
Update setting migration to include Hometown settings
Fixes: a9b5598c97
2023-11-22 21:56:05 +01:00
22 changed files with 93 additions and 97 deletions

View File

@ -1,58 +1,19 @@
# frozen_string_literal: true
class AboutController < ApplicationController
include RegistrationSpamConcern
include WebAppControllerConcern
layout 'public'
skip_before_action :require_functional!
before_action :set_body_classes, only: :show
before_action :set_instance_presenter
before_action :set_expires_in, only: [:more, :terms]
before_action :set_registration_form_time, only: :show
skip_before_action :require_functional!, only: [:more, :terms]
def show
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
end
def terms; end
helper_method :display_blocks?
helper_method :display_blocks_rationale?
helper_method :public_fetch_mode?
helper_method :new_user
private
def markdown
@markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, escape_html: true, no_images: true)
end
def display_blocks?
Setting.show_domain_blocks == 'all' || (Setting.show_domain_blocks == 'users' && user_signed_in?)
end
def display_blocks_rationale?
Setting.show_domain_blocks_rationale == 'all' || (Setting.show_domain_blocks_rationale == 'users' && user_signed_in?)
end
def new_user
User.new.tap do |user|
user.build_account
user.build_invite_request
end
end
def set_instance_presenter
@instance_presenter = InstancePresenter.new
end
def set_body_classes
@hide_navbar = true
end
def set_expires_in
expires_in 0, public: true
end
end

View File

@ -25,6 +25,12 @@ class AccountsController < ApplicationController
format.rss do
expires_in 1.minute, public: true
# Hometown: Do not display any entries in the RSS feed if it's disabled
if @account&.user&.setting_norss == true
@statuses = []
next
end
limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE
@statuses = filtered_statuses.without_reblogs.limit(limit)
@statuses = cache_collection(@statuses, Status)
@ -48,7 +54,12 @@ class AccountsController < ApplicationController
end
def default_statuses
@account.statuses.where(visibility: [:public, :unlisted])
# Hometown: local-only posts are not meant for RSS feeds, even if they are public.
if current_user.nil?
@account.statuses.without_local_only.where(visibility: [:public, :unlisted])
else
@account.statuses.where(visibility: [:public, :unlisted])
end
end
def only_media_scope

View File

@ -11,8 +11,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
before_action :set_last_used_at_by_app, only: :index, unless: -> { request.format == :json }
before_action :set_last_used_at_by_app, only: :index, unless: -> { request.format == :json }
skip_before_action :require_functional!
include Localized

View File

@ -19,6 +19,7 @@ module WellKnown
def set_account
username = username_from_resource
@account = begin
if username == Rails.configuration.x.local_domain
Account.representative

View File

@ -419,8 +419,8 @@ class Header extends ImmutablePureComponent {
<div className='account__header__tabs__name'>
<h1>
<a href={account.get('url')} target='_blank' rel='noopener noreferrer'><span dangerouslySetInnerHTML={displayNameHtml} /></a>{isRemote ? <span> <IconButton icon='external-link' size={14} onClick={this.handleDisplayNameClick} /></span> : null}
<span dangerouslySetInnerHTML={displayNameHtml} />
<a href={account.get('url')} target='_blank' rel='noopener noreferrer'><span dangerouslySetInnerHTML={displayNameHtml} /></a>{isRemote ? <span> <IconButton icon='external-link' size={14} onClick={this.handleDisplayNameClick} /></span> : null}
<small>
<span>@{acct}</span> {lockedIcon}
</small>

View File

@ -23,7 +23,7 @@ export default class NavigationBar extends ImmutablePureComponent {
const username = this.props.account.get('acct')
const url = this.props.account.get('url')
return (
<div classNamesName='navigation-bar'>
<div className='navigation-bar'>
<Link to={`/@${username}`} href={url}>
<span style={{ display: 'none' }}>{username}</span>
<Avatar account={this.props.account} size={46} />

View File

@ -30,7 +30,6 @@ class ListEditor extends ImmutablePureComponent {
static propTypes = {
listId: PropTypes.string.isRequired,
isExclusive: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onInitialize: PropTypes.func.isRequired,
@ -56,7 +55,7 @@ class ListEditor extends ImmutablePureComponent {
return (
<div className='modal-root__modal list-editor'>
<EditListForm isExclusive={this.props.isExclusive} />
<EditListForm />
<Search />

View File

@ -15,6 +15,7 @@ const messages = defineMessages({
spam: { id: 'report_notification.categories.spam', defaultMessage: 'Spam' },
legal: { id: 'report_notification.categories.legal', defaultMessage: 'Legal' },
violation: { id: 'report_notification.categories.violation', defaultMessage: 'Rule violation' },
dislike: { id: 'report_notification.categories.dislike', defaultMessage: 'Dislike' },
});
class Report extends ImmutablePureComponent {

View File

@ -45,6 +45,7 @@ class Category extends PureComponent {
const { onNextStep, category } = this.props;
switch(category) {
// Hometown: also send reports for "disliked" toots, it's quite unfair to do nothing in this case.
case 'dislike':
onNextStep('statuses');
break;

View File

@ -10,7 +10,6 @@ import {
LIST_EDITOR_RESET,
LIST_EDITOR_SETUP,
LIST_EDITOR_TITLE_CHANGE,
LIST_EDITOR_IS_EXCLUSIVE_CHANGE,
LIST_ACCOUNTS_FETCH_REQUEST,
LIST_ACCOUNTS_FETCH_SUCCESS,
LIST_ACCOUNTS_FETCH_FAIL,
@ -56,11 +55,6 @@ export default function listEditorReducer(state = initialState, action) {
map.set('title', action.value);
map.set('isChanged', true);
});
case LIST_EDITOR_IS_EXCLUSIVE_CHANGE:
return state.withMutations(map => {
map.set('isExclusive', action.value);
map.set('isChanged', true);
});
case LIST_CREATE_REQUEST:
case LIST_UPDATE_REQUEST:
return state.withMutations(map => {

View File

@ -40,8 +40,4 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
def report_comment
(@json['content'] || '')[0...5000]
end
def report_comment
(@json['content'] || '')[0...5000]
end
end

View File

@ -53,7 +53,8 @@ class ActivityPub::Parser::StatusParser
end
def created_at
@object['published']&.to_datetime
datetime = @object['published']&.to_datetime
datetime if datetime.present? && (0..9999).cover?(datetime.year)
rescue ArgumentError
nil
end

View File

@ -1,8 +1,6 @@
# frozen_string_literal: true
class PlainTextFormatter
include ActionView::Helpers::TextHelper
NEWLINE_TAGS_RE = %r{(<br />|<br>|</p>)+}
attr_reader :text, :local

View File

@ -20,10 +20,4 @@ class ApplicationMailer < ActionMailer::Base
headers['X-Auto-Response-Suppress'] = 'All'
headers['Auto-Submitted'] = 'auto-generated'
end
def set_autoreply_headers!
headers['Precedence'] = 'list'
headers['X-Auto-Response-Suppress'] = 'All'
headers['Auto-Submitted'] = 'auto-generated'
end
end

View File

@ -66,7 +66,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_enabled.subject')
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_enabled.subject', title: Setting.site_title)
end
end
@ -77,7 +77,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_disabled.subject')
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_disabled.subject', title: Setting.site_title)
end
end
@ -88,7 +88,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject')
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject', title: Setting.site_title)
end
end
@ -99,7 +99,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_enabled.subject')
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_enabled.subject', title: Setting.site_title)
end
end
@ -110,7 +110,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_disabled.subject')
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_disabled.subject', title: Setting.site_title)
end
end
@ -122,7 +122,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.added.subject')
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.added.subject', title: Setting.site_title)
end
end
@ -134,7 +134,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.deleted.subject')
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.deleted.subject', title: Setting.site_title)
end
end
@ -145,7 +145,6 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.welcome.subject')
mail to: @resource.email, subject: I18n.t('user_mailer.welcome.subject', title: Setting.site_title)
end
end
@ -169,7 +168,7 @@ class UserMailer < Devise::Mailer
@statuses = @warning.statuses.includes(:account, :preloadable_poll, :media_attachments, active_mentions: [:account])
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}")
mail to: @resource.email, subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}", title: Setting.site_title)
end
end
@ -179,7 +178,7 @@ class UserMailer < Devise::Mailer
@appeal = appeal
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.appeal_approved.subject', date: l(@appeal.created_at))
mail to: @resource.email, subject: I18n.t('user_mailer.appeal_approved.subject', date: l(@appeal.created_at), title: Setting.site_title)
end
end
@ -189,7 +188,7 @@ class UserMailer < Devise::Mailer
@appeal = appeal
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.appeal_rejected.subject', date: l(@appeal.created_at))
mail to: @resource.email, subject: I18n.t('user_mailer.appeal_rejected.subject', date: l(@appeal.created_at), title: Setting.site_title)
end
end
@ -202,7 +201,7 @@ class UserMailer < Devise::Mailer
@timestamp = timestamp.to_time.utc
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.suspicious_sign_in.subject')
mail to: @resource.email, subject: I18n.t('user_mailer.suspicious_sign_in.subject', title: Setting.site_title)
end
end

View File

@ -57,6 +57,7 @@ class Report < ApplicationRecord
spam: 1_000,
legal: 1_500,
violation: 2_000,
dislike: 3_000,
}
before_validation :set_uri, only: :create

View File

@ -16,6 +16,11 @@ class UserSettings
setting :default_sensitive, default: false
setting :default_privacy, default: nil, in: %w(public unlisted private)
# Hometown-specific: Opt-out of RSS feeds for public posts
setting :norss, default: false
# Hometown: New posts should federate by default
setting :default_federation, default: true
setting_inverse_alias :indexable, :noindex
namespace :web do
@ -32,6 +37,9 @@ class UserSettings
setting :expand_content_warnings, default: false
setting :display_media, default: 'default', in: %w(default show_all hide_all)
setting :auto_play, default: false
# Hometown: Show full username (including domain) for remote users
setting :expand_usernames, default: true
end
namespace :notification_emails do

View File

@ -88,10 +88,6 @@ class Webhook < ApplicationRecord
end
end
def validate_permissions
errors.add(:events, :invalid_permissions) if defined?(@current_account) && required_permissions.any? { |permission| !@current_account.user_role.can?(permission) }
end
def strip_events
self.events = events.filter_map { |str| str.strip.presence } if events.present?
end

View File

@ -11,12 +11,6 @@
.fields-group
= ff.input :noindex, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_noindex'), hint: I18n.t('simple_form.hints.defaults.setting_noindex')
.fields-group
= ff.input :norss, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_norss'), hint: I18n.t('simple_form.hints.defaults.setting_norss')
.fields-group
= ff.input :noindex, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_noindex'), hint: I18n.t('simple_form.hints.defaults.setting_noindex')
.fields-group
= ff.input :aggregate_reblogs, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs')
@ -35,9 +29,6 @@
.fields-group
= ff.input :default_federation, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_federation'), hint: I18n.t('simple_form.hints.defaults.setting_default_federation')
.fields-group
= ff.input :show_application, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_show_application'), hint: I18n.t('simple_form.hints.defaults.setting_show_application')
%h4= t 'preferences.public_timelines'
.fields-group

View File

@ -20,6 +20,9 @@
.fields-group
= f.input :unlocked, as: :boolean, wrapper: :with_label
.fields-group
= f.input :norss, as: boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_norss'), hint: I18n.t('simple_form.hints.defaults.setting_norss')
%h4= t('privacy.search')
%p.lead= t('privacy.search_hint_html')

View File

@ -44,6 +44,11 @@ class MoveUserSettings < ActiveRecord::Migration[6.1]
must_be_following: 'interactions.must_be_following',
must_be_following_dm: 'interactions.must_be_following_dm',
}.freeze,
# Hometown-specific fields
norss: 'norss',
default_federation: 'default_federation',
expand_usernames: 'web.expand_usernames',
}.freeze
class LegacySetting < ApplicationRecord

View File

@ -31,6 +31,46 @@ RSpec.describe ActivityPub::Activity::Create do
subject.perform
end
context 'when object publication date is below ISO8601 range' do
let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
content: 'Lorem ipsum',
published: '-0977-11-03T08:31:22Z',
}
end
it 'creates status with a valid creation date', :aggregate_failures do
status = sender.statuses.first
expect(status).to_not be_nil
expect(status.text).to eq 'Lorem ipsum'
expect(status.created_at).to be_within(30).of(Time.now.utc)
end
end
context 'when object publication date is above ISO8601 range' do
let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
content: 'Lorem ipsum',
published: '10000-11-03T08:31:22Z',
}
end
it 'creates status with a valid creation date', :aggregate_failures do
status = sender.statuses.first
expect(status).to_not be_nil
expect(status.text).to eq 'Lorem ipsum'
expect(status.created_at).to be_within(30).of(Time.now.utc)
end
end
context 'when object has been edited' do
let(:object_json) do
{
@ -42,18 +82,16 @@ RSpec.describe ActivityPub::Activity::Create do
}
end
it 'creates status' do
it 'creates status with appropriate creation and edition dates', :aggregate_failures do
status = sender.statuses.first
expect(status).to_not be_nil
expect(status.text).to eq 'Lorem ipsum'
end
it 'marks status as edited' do
status = sender.statuses.first
expect(status.created_at).to eq '2022-01-22T15:00:00Z'.to_datetime
expect(status).to_not be_nil
expect(status.edited?).to be true
expect(status.edited_at).to eq '2022-01-22T16:00:00Z'.to_datetime
end
end