Merge remote-tracking branch 'tootsuite/master' into merge-upstream
Conflicts:
      app/javascript/styles/mastodon/components.scss
			
			
This commit is contained in:
		
						commit
						6d1023b2e9
					
				
					 30 changed files with 244 additions and 95 deletions
				
			
		
							
								
								
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							| 
						 | 
					@ -31,6 +31,9 @@ gem 'iso-639'
 | 
				
			||||||
gem 'cld3', '~> 3.2.0'
 | 
					gem 'cld3', '~> 3.2.0'
 | 
				
			||||||
gem 'devise', '~> 4.4'
 | 
					gem 'devise', '~> 4.4'
 | 
				
			||||||
gem 'devise-two-factor', '~> 3.0'
 | 
					gem 'devise-two-factor', '~> 3.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gem 'devise_pam_authenticatable2', '~> 8.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gem 'doorkeeper', '~> 4.2'
 | 
					gem 'doorkeeper', '~> 4.2'
 | 
				
			||||||
gem 'fast_blank', '~> 1.0'
 | 
					gem 'fast_blank', '~> 1.0'
 | 
				
			||||||
gem 'goldfinger', '~> 2.1'
 | 
					gem 'goldfinger', '~> 2.1'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Gemfile.lock
									
									
									
									
									
								
							| 
						 | 
					@ -137,6 +137,9 @@ GEM
 | 
				
			||||||
      devise (~> 4.0)
 | 
					      devise (~> 4.0)
 | 
				
			||||||
      railties (< 5.2)
 | 
					      railties (< 5.2)
 | 
				
			||||||
      rotp (~> 2.0)
 | 
					      rotp (~> 2.0)
 | 
				
			||||||
 | 
					    devise_pam_authenticatable2 (8.0.1)
 | 
				
			||||||
 | 
					      devise (>= 4.0.0)
 | 
				
			||||||
 | 
					      rpam2 (~> 3.0)
 | 
				
			||||||
    diff-lcs (1.3)
 | 
					    diff-lcs (1.3)
 | 
				
			||||||
    docile (1.1.5)
 | 
					    docile (1.1.5)
 | 
				
			||||||
    domain_name (0.5.20170404)
 | 
					    domain_name (0.5.20170404)
 | 
				
			||||||
| 
						 | 
					@ -215,7 +218,7 @@ GEM
 | 
				
			||||||
    httplog (0.99.7)
 | 
					    httplog (0.99.7)
 | 
				
			||||||
      colorize
 | 
					      colorize
 | 
				
			||||||
      rack
 | 
					      rack
 | 
				
			||||||
    i18n (0.9.1)
 | 
					    i18n (0.9.3)
 | 
				
			||||||
      concurrent-ruby (~> 1.0)
 | 
					      concurrent-ruby (~> 1.0)
 | 
				
			||||||
    i18n-tasks (0.9.19)
 | 
					    i18n-tasks (0.9.19)
 | 
				
			||||||
      activesupport (>= 4.0.2)
 | 
					      activesupport (>= 4.0.2)
 | 
				
			||||||
| 
						 | 
					@ -284,7 +287,7 @@ GEM
 | 
				
			||||||
    mimemagic (0.3.2)
 | 
					    mimemagic (0.3.2)
 | 
				
			||||||
    mini_mime (1.0.0)
 | 
					    mini_mime (1.0.0)
 | 
				
			||||||
    mini_portile2 (2.3.0)
 | 
					    mini_portile2 (2.3.0)
 | 
				
			||||||
    minitest (5.10.3)
 | 
					    minitest (5.11.3)
 | 
				
			||||||
    msgpack (1.1.0)
 | 
					    msgpack (1.1.0)
 | 
				
			||||||
    multi_json (1.12.2)
 | 
					    multi_json (1.12.2)
 | 
				
			||||||
    net-scp (1.2.1)
 | 
					    net-scp (1.2.1)
 | 
				
			||||||
| 
						 | 
					@ -307,7 +310,7 @@ GEM
 | 
				
			||||||
      http (~> 3.0)
 | 
					      http (~> 3.0)
 | 
				
			||||||
      nokogiri (~> 1.8)
 | 
					      nokogiri (~> 1.8)
 | 
				
			||||||
    ox (2.8.2)
 | 
					    ox (2.8.2)
 | 
				
			||||||
    paperclip (5.1.0)
 | 
					    paperclip (5.2.1)
 | 
				
			||||||
      activemodel (>= 4.2.0)
 | 
					      activemodel (>= 4.2.0)
 | 
				
			||||||
      activesupport (>= 4.2.0)
 | 
					      activesupport (>= 4.2.0)
 | 
				
			||||||
      cocaine (~> 0.5.5)
 | 
					      cocaine (~> 0.5.5)
 | 
				
			||||||
| 
						 | 
					@ -421,6 +424,7 @@ GEM
 | 
				
			||||||
      actionpack (>= 4.2.0, < 5.3)
 | 
					      actionpack (>= 4.2.0, < 5.3)
 | 
				
			||||||
      railties (>= 4.2.0, < 5.3)
 | 
					      railties (>= 4.2.0, < 5.3)
 | 
				
			||||||
    rotp (2.1.2)
 | 
					    rotp (2.1.2)
 | 
				
			||||||
 | 
					    rpam2 (3.1.0)
 | 
				
			||||||
    rqrcode (0.10.1)
 | 
					    rqrcode (0.10.1)
 | 
				
			||||||
      chunky_png (~> 1.0)
 | 
					      chunky_png (~> 1.0)
 | 
				
			||||||
    rspec-core (3.7.0)
 | 
					    rspec-core (3.7.0)
 | 
				
			||||||
| 
						 | 
					@ -571,6 +575,7 @@ DEPENDENCIES
 | 
				
			||||||
  climate_control (~> 0.2)
 | 
					  climate_control (~> 0.2)
 | 
				
			||||||
  devise (~> 4.4)
 | 
					  devise (~> 4.4)
 | 
				
			||||||
  devise-two-factor (~> 3.0)
 | 
					  devise-two-factor (~> 3.0)
 | 
				
			||||||
 | 
					  devise_pam_authenticatable2 (~> 8.0)
 | 
				
			||||||
  doorkeeper (~> 4.2)
 | 
					  doorkeeper (~> 4.2)
 | 
				
			||||||
  dotenv-rails (~> 2.2)
 | 
					  dotenv-rails (~> 2.2)
 | 
				
			||||||
  fabrication (~> 2.18)
 | 
					  fabrication (~> 2.18)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,12 @@
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ActivityPub::OutboxesController < Api::BaseController
 | 
					class ActivityPub::OutboxesController < Api::BaseController
 | 
				
			||||||
 | 
					  include SignatureVerification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before_action :set_account
 | 
					  before_action :set_account
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    @statuses = @account.statuses.permitted_for(@account, current_account).paginate_by_max_id(20, params[:max_id], params[:since_id])
 | 
					    @statuses = @account.statuses.permitted_for(@account, signed_request_account).paginate_by_max_id(20, params[:max_id], params[:since_id])
 | 
				
			||||||
    @statuses = cache_collection(@statuses, Status)
 | 
					    @statuses = cache_collection(@statuses, Status)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render json: outbox_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
 | 
					    render json: outbox_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ class ApplicationController < ActionController::Base
 | 
				
			||||||
  helper_method :current_flavour
 | 
					  helper_method :current_flavour
 | 
				
			||||||
  helper_method :current_skin
 | 
					  helper_method :current_skin
 | 
				
			||||||
  helper_method :single_user_mode?
 | 
					  helper_method :single_user_mode?
 | 
				
			||||||
 | 
					  helper_method :use_pam?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rescue_from ActionController::RoutingError, with: :not_found
 | 
					  rescue_from ActionController::RoutingError, with: :not_found
 | 
				
			||||||
  rescue_from ActiveRecord::RecordNotFound, with: :not_found
 | 
					  rescue_from ActiveRecord::RecordNotFound, with: :not_found
 | 
				
			||||||
| 
						 | 
					@ -145,6 +146,10 @@ class ApplicationController < ActionController::Base
 | 
				
			||||||
    @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.exists?
 | 
					    @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.exists?
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def use_pam?
 | 
				
			||||||
 | 
					    Devise.pam_authentication
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def current_account
 | 
					  def current_account
 | 
				
			||||||
    @current_account ||= current_user.try(:account)
 | 
					    @current_account ||= current_user.try(:account)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def update_resource(resource, params)
 | 
				
			||||||
 | 
					    params[:password] = nil if Devise.pam_authentication && resource.encrypted_password.blank?
 | 
				
			||||||
 | 
					    super
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def build_resource(hash = nil)
 | 
					  def build_resource(hash = nil)
 | 
				
			||||||
    super(hash)
 | 
					    super(hash)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,11 @@ class Auth::SessionsController < Devise::SessionsController
 | 
				
			||||||
    if session[:otp_user_id]
 | 
					    if session[:otp_user_id]
 | 
				
			||||||
      User.find(session[:otp_user_id])
 | 
					      User.find(session[:otp_user_id])
 | 
				
			||||||
    elsif user_params[:email]
 | 
					    elsif user_params[:email]
 | 
				
			||||||
      User.find_for_authentication(email: user_params[:email])
 | 
					      if use_pam? && Devise.check_at_sign && user_params[:email].index('@').nil?
 | 
				
			||||||
 | 
					        User.joins(:account).find_by(accounts: { username: user_params[:email] })
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        User.find_for_authentication(email: user_params[:email])
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								app/controllers/concerns/signature_authentication.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/controllers/concerns/signature_authentication.rb
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module SignatureAuthentication
 | 
				
			||||||
 | 
					  extend ActiveSupport::Concern
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  include SignatureVerification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def current_account
 | 
				
			||||||
 | 
					    super || signed_request_account
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StatusesController < ApplicationController
 | 
					class StatusesController < ApplicationController
 | 
				
			||||||
 | 
					  include SignatureAuthentication
 | 
				
			||||||
  include Authorization
 | 
					  include Authorization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  layout 'public'
 | 
					  layout 'public'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@ class StreamEntriesController < ApplicationController
 | 
				
			||||||
  before_action :set_stream_entry
 | 
					  before_action :set_stream_entry
 | 
				
			||||||
  before_action :set_link_headers
 | 
					  before_action :set_link_headers
 | 
				
			||||||
  before_action :check_account_suspension
 | 
					  before_action :check_account_suspension
 | 
				
			||||||
 | 
					  before_action :set_cache_headers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    respond_to do |format|
 | 
					    respond_to do |format|
 | 
				
			||||||
| 
						 | 
					@ -20,6 +21,10 @@ class StreamEntriesController < ApplicationController
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      format.atom do
 | 
					      format.atom do
 | 
				
			||||||
 | 
					        unless @stream_entry.hidden?
 | 
				
			||||||
 | 
					          skip_session!
 | 
				
			||||||
 | 
					          expires_in 3.minutes, public: true
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
        render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.entry(@stream_entry, true))
 | 
					        render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.entry(@stream_entry, true))
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,9 +133,7 @@ export default class ColumnHeader extends React.PureComponent {
 | 
				
			||||||
        <h1 className={buttonClassName}>
 | 
					        <h1 className={buttonClassName}>
 | 
				
			||||||
          <button onClick={this.handleTitleClick}>
 | 
					          <button onClick={this.handleTitleClick}>
 | 
				
			||||||
            <i className={`fa fa-fw fa-${icon} column-header__icon`} />
 | 
					            <i className={`fa fa-fw fa-${icon} column-header__icon`} />
 | 
				
			||||||
            <span className='column-header__title'>
 | 
					            {title}
 | 
				
			||||||
              {title}
 | 
					 | 
				
			||||||
            </span>
 | 
					 | 
				
			||||||
          </button>
 | 
					          </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div className='column-header__buttons'>
 | 
					          <div className='column-header__buttons'>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ import Motion from '../ui/util/optional_motion';
 | 
				
			||||||
import spring from 'react-motion/lib/spring';
 | 
					import spring from 'react-motion/lib/spring';
 | 
				
			||||||
import SearchResultsContainer from './containers/search_results_container';
 | 
					import SearchResultsContainer from './containers/search_results_container';
 | 
				
			||||||
import { changeComposing } from '../../actions/compose';
 | 
					import { changeComposing } from '../../actions/compose';
 | 
				
			||||||
 | 
					import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const messages = defineMessages({
 | 
					const messages = defineMessages({
 | 
				
			||||||
  start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
 | 
					  start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
 | 
				
			||||||
| 
						 | 
					@ -94,7 +95,11 @@ export default class Compose extends React.PureComponent {
 | 
				
			||||||
          <div className='drawer__inner' onFocus={this.onFocus}>
 | 
					          <div className='drawer__inner' onFocus={this.onFocus}>
 | 
				
			||||||
            <NavigationContainer onClose={this.onBlur} />
 | 
					            <NavigationContainer onClose={this.onBlur} />
 | 
				
			||||||
            <ComposeFormContainer />
 | 
					            <ComposeFormContainer />
 | 
				
			||||||
            {multiColumn && <div className='mastodon' />}
 | 
					            {multiColumn && (
 | 
				
			||||||
 | 
					              <div className='drawer__inner__mastodon'>
 | 
				
			||||||
 | 
					                <img alt='' src={elephantUIPlane} />
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
 | 
					          <Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1766,7 +1766,7 @@
 | 
				
			||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
  top: 0;
 | 
					  top: 0;
 | 
				
			||||||
  left: 0;
 | 
					  left: 0;
 | 
				
			||||||
  background: lighten($ui-base-color, 13%) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-color)}"/></svg>') no-repeat bottom / 100% auto;
 | 
					  background: lighten($ui-base-color, 13%);
 | 
				
			||||||
  box-sizing: border-box;
 | 
					  box-sizing: border-box;
 | 
				
			||||||
  padding: 0;
 | 
					  padding: 0;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
| 
						 | 
					@ -1779,10 +1779,19 @@
 | 
				
			||||||
  &.darker {
 | 
					  &.darker {
 | 
				
			||||||
    background: $ui-base-color;
 | 
					    background: $ui-base-color;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  > .mastodon {
 | 
					.drawer__inner__mastodon {
 | 
				
			||||||
    background: url('~images/elephant_ui_plane.svg') no-repeat left bottom / contain;
 | 
					  background: lighten($ui-base-color, 13%) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-color)}"/></svg>') no-repeat bottom / 100% auto;
 | 
				
			||||||
    flex: 1;
 | 
					  flex: 1;
 | 
				
			||||||
 | 
					  min-height: 47px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  > img { 
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    object-fit: contain;
 | 
				
			||||||
 | 
					    object-position: bottom left;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1913,7 +1922,7 @@
 | 
				
			||||||
  font-family: inherit;
 | 
					  font-family: inherit;
 | 
				
			||||||
  color: $ui-highlight-color;
 | 
					  color: $ui-highlight-color;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  flex: 0 0 auto;
 | 
					  white-space: nowrap;
 | 
				
			||||||
  font-size: 16px;
 | 
					  font-size: 16px;
 | 
				
			||||||
  padding: 0 5px 0 0;
 | 
					  padding: 0 5px 0 0;
 | 
				
			||||||
  z-index: 3;
 | 
					  z-index: 3;
 | 
				
			||||||
| 
						 | 
					@ -2403,15 +2412,17 @@
 | 
				
			||||||
  overflow: hidden;
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  & > button {
 | 
					  & > button {
 | 
				
			||||||
    display: flex;
 | 
					 | 
				
			||||||
    flex: auto;
 | 
					 | 
				
			||||||
    margin: 0;
 | 
					    margin: 0;
 | 
				
			||||||
    border: none;
 | 
					    border: none;
 | 
				
			||||||
    padding: 15px;
 | 
					    padding: 15px 0 15px 15px;
 | 
				
			||||||
    color: inherit;
 | 
					    color: inherit;
 | 
				
			||||||
    background: transparent;
 | 
					    background: transparent;
 | 
				
			||||||
    font: inherit;
 | 
					    font: inherit;
 | 
				
			||||||
    text-align: left;
 | 
					    text-align: left;
 | 
				
			||||||
 | 
					    text-overflow: ellipsis;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    white-space: nowrap;
 | 
				
			||||||
 | 
					    flex: 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &.active {
 | 
					  &.active {
 | 
				
			||||||
| 
						 | 
					@ -2432,7 +2443,6 @@
 | 
				
			||||||
.column-header__buttons {
 | 
					.column-header__buttons {
 | 
				
			||||||
  height: 48px;
 | 
					  height: 48px;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  margin-left: 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.column-header__links .text-btn {
 | 
					.column-header__links .text-btn {
 | 
				
			||||||
| 
						 | 
					@ -2512,14 +2522,6 @@
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.column-header__title {
 | 
					 | 
				
			||||||
  display: inline-block;
 | 
					 | 
				
			||||||
  text-overflow: ellipsis;
 | 
					 | 
				
			||||||
  overflow: hidden;
 | 
					 | 
				
			||||||
  white-space: nowrap;
 | 
					 | 
				
			||||||
  flex: 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.text-btn {
 | 
					.text-btn {
 | 
				
			||||||
  display: inline-block;
 | 
					  display: inline-block;
 | 
				
			||||||
  padding: 0;
 | 
					  padding: 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,8 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
 | 
				
			||||||
      account: @account,
 | 
					      account: @account,
 | 
				
			||||||
      reblog: original_status,
 | 
					      reblog: original_status,
 | 
				
			||||||
      uri: @json['id'],
 | 
					      uri: @json['id'],
 | 
				
			||||||
      created_at: @options[:override_timestamps] ? nil : @json['published']
 | 
					      created_at: @options[:override_timestamps] ? nil : @json['published'],
 | 
				
			||||||
 | 
					      visibility: original_status.visibility
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    distribute(status)
 | 
					    distribute(status)
 | 
				
			||||||
| 
						 | 
					@ -35,6 +36,6 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def announceable?(status)
 | 
					  def announceable?(status)
 | 
				
			||||||
    status.public_visibility? || status.unlisted_visibility?
 | 
					    status.account_id == @account.id || status.public_visibility? || status.unlisted_visibility?
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
#  disabled                  :boolean          default(FALSE), not null
 | 
					#  disabled                  :boolean          default(FALSE), not null
 | 
				
			||||||
#  moderator                 :boolean          default(FALSE), not null
 | 
					#  moderator                 :boolean          default(FALSE), not null
 | 
				
			||||||
#  invite_id                 :integer
 | 
					#  invite_id                 :integer
 | 
				
			||||||
 | 
					#  remember_token            :string
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class User < ApplicationRecord
 | 
					class User < ApplicationRecord
 | 
				
			||||||
| 
						 | 
					@ -50,6 +51,8 @@ class User < ApplicationRecord
 | 
				
			||||||
  devise :registerable, :recoverable, :rememberable, :trackable, :validatable,
 | 
					  devise :registerable, :recoverable, :rememberable, :trackable, :validatable,
 | 
				
			||||||
         :confirmable
 | 
					         :confirmable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  devise :pam_authenticatable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  belongs_to :account, inverse_of: :user
 | 
					  belongs_to :account, inverse_of: :user
 | 
				
			||||||
  belongs_to :invite, counter_cache: :uses, optional: true
 | 
					  belongs_to :invite, counter_cache: :uses, optional: true
 | 
				
			||||||
  accepts_nested_attributes_for :account
 | 
					  accepts_nested_attributes_for :account
 | 
				
			||||||
| 
						 | 
					@ -84,6 +87,33 @@ class User < ApplicationRecord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  attr_accessor :invite_code
 | 
					  attr_accessor :invite_code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def pam_conflict(_)
 | 
				
			||||||
 | 
					    # block pam login tries on traditional account
 | 
				
			||||||
 | 
					    nil
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def pam_conflict?
 | 
				
			||||||
 | 
					    return false unless Devise.pam_authentication
 | 
				
			||||||
 | 
					    encrypted_password.present? && is_pam_account?
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def pam_get_name
 | 
				
			||||||
 | 
					    return account.username if account.present?
 | 
				
			||||||
 | 
					    super
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def pam_setup(_attributes)
 | 
				
			||||||
 | 
					    acc = Account.new(username: pam_get_name)
 | 
				
			||||||
 | 
					    acc.save!(validate: false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.email = "#{acc.username}@#{find_pam_suffix}" if email.nil? && find_pam_suffix
 | 
				
			||||||
 | 
					    self.confirmed_at = Time.now.utc
 | 
				
			||||||
 | 
					    self.admin = false
 | 
				
			||||||
 | 
					    self.account = acc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    acc.destroy! unless save
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def confirmed?
 | 
					  def confirmed?
 | 
				
			||||||
    confirmed_at.present?
 | 
					    confirmed_at.present?
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -213,6 +243,45 @@ class User < ApplicationRecord
 | 
				
			||||||
    @invite_code = code
 | 
					    @invite_code = code
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def password_required?
 | 
				
			||||||
 | 
					    return false if Devise.pam_authentication
 | 
				
			||||||
 | 
					    super
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def send_reset_password_instructions
 | 
				
			||||||
 | 
					    return false if encrypted_password.blank? && Devise.pam_authentication
 | 
				
			||||||
 | 
					    super
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def reset_password!(new_password, new_password_confirmation)
 | 
				
			||||||
 | 
					    return false if encrypted_password.blank? && Devise.pam_authentication
 | 
				
			||||||
 | 
					    super
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def self.pam_get_user(attributes = {})
 | 
				
			||||||
 | 
					    if attributes[:email]
 | 
				
			||||||
 | 
					      resource =
 | 
				
			||||||
 | 
					        if Devise.check_at_sign && !attributes[:email].index('@')
 | 
				
			||||||
 | 
					          joins(:account).find_by(accounts: { username: attributes[:email] })
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          find_by(email: attributes[:email])
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if resource.blank?
 | 
				
			||||||
 | 
					        resource = new(email: attributes[:email])
 | 
				
			||||||
 | 
					        if Devise.check_at_sign && !resource[:email].index('@')
 | 
				
			||||||
 | 
					          resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}"
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      resource
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def self.authenticate_with_pam(attributes = {})
 | 
				
			||||||
 | 
					    return nil unless Devise.pam_authentication
 | 
				
			||||||
 | 
					    super
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def send_devise_notification(notification, *args)
 | 
					  def send_devise_notification(notification, *args)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,13 +91,13 @@ class FetchLinkCardService < BaseService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case @card.type
 | 
					    case @card.type
 | 
				
			||||||
    when 'link'
 | 
					    when 'link'
 | 
				
			||||||
      @card.image = URI.parse(embed.thumbnail_url) if embed.respond_to?(:thumbnail_url)
 | 
					      @card.image_remote_url = embed.thumbnail_url if embed.respond_to?(:thumbnail_url)
 | 
				
			||||||
    when 'photo'
 | 
					    when 'photo'
 | 
				
			||||||
      return false unless embed.respond_to?(:url)
 | 
					      return false unless embed.respond_to?(:url)
 | 
				
			||||||
      @card.embed_url = embed.url
 | 
					      @card.embed_url        = embed.url
 | 
				
			||||||
      @card.image     = URI.parse(embed.url)
 | 
					      @card.image_remote_url = embed.url
 | 
				
			||||||
      @card.width     = embed.width.presence  || 0
 | 
					      @card.width            = embed.width.presence  || 0
 | 
				
			||||||
      @card.height    = embed.height.presence || 0
 | 
					      @card.height           = embed.height.presence || 0
 | 
				
			||||||
    when 'video'
 | 
					    when 'video'
 | 
				
			||||||
      @card.width  = embed.width.presence  || 0
 | 
					      @card.width  = embed.width.presence  || 0
 | 
				
			||||||
      @card.height = embed.height.presence || 0
 | 
					      @card.height = embed.height.presence || 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,13 @@ class UnreservedUsernameValidator < ActiveModel::Validator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def pam_controlled?(value)
 | 
				
			||||||
 | 
					    return false unless Devise.pam_authentication && Devise.pam_controlled_service
 | 
				
			||||||
 | 
					    Rpam2.account(Devise.pam_controlled_service, value).present?
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def reserved_username?(value)
 | 
					  def reserved_username?(value)
 | 
				
			||||||
 | 
					    return true if pam_controlled?(value)
 | 
				
			||||||
    return false unless Setting.reserved_usernames
 | 
					    return false unless Setting.reserved_usernames
 | 
				
			||||||
    Setting.reserved_usernames.include?(value.downcase)
 | 
					    Setting.reserved_usernames.include?(value.downcase)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								app/views/about/_links.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/views/about/_links.html.haml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					.container.links
 | 
				
			||||||
 | 
					  .brand
 | 
				
			||||||
 | 
					    = link_to root_url do
 | 
				
			||||||
 | 
					      = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  %ul.nav
 | 
				
			||||||
 | 
					    %li
 | 
				
			||||||
 | 
					      - if user_signed_in?
 | 
				
			||||||
 | 
					        = link_to t('settings.back'), root_url, class: 'webapp-btn'
 | 
				
			||||||
 | 
					      - else
 | 
				
			||||||
 | 
					        = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
 | 
				
			||||||
 | 
					    %li= link_to t('about.about_this'), about_more_path
 | 
				
			||||||
 | 
					    %li
 | 
				
			||||||
 | 
					      = link_to 'https://joinmastodon.org/' do
 | 
				
			||||||
 | 
					        = "#{t('about.other_instances')}"
 | 
				
			||||||
 | 
					        %i.fa.fa-external-link{ style: 'padding-left: 5px;' }
 | 
				
			||||||
| 
						 | 
					@ -7,22 +7,7 @@
 | 
				
			||||||
.landing-page
 | 
					.landing-page
 | 
				
			||||||
  .header-wrapper.compact
 | 
					  .header-wrapper.compact
 | 
				
			||||||
    .header
 | 
					    .header
 | 
				
			||||||
      .container.links
 | 
					      = render 'links'
 | 
				
			||||||
        .brand
 | 
					 | 
				
			||||||
          = link_to root_url do
 | 
					 | 
				
			||||||
            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        %ul.nav
 | 
					 | 
				
			||||||
          %li
 | 
					 | 
				
			||||||
            - if user_signed_in?
 | 
					 | 
				
			||||||
              = link_to t('settings.back'), root_url, class: 'webapp-btn'
 | 
					 | 
				
			||||||
            - else
 | 
					 | 
				
			||||||
              = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
 | 
					 | 
				
			||||||
          %li= link_to t('about.about_this'), about_more_path
 | 
					 | 
				
			||||||
          %li
 | 
					 | 
				
			||||||
            = link_to 'https://joinmastodon.org/' do
 | 
					 | 
				
			||||||
              = "#{t('about.other_instances')}"
 | 
					 | 
				
			||||||
              %i.fa.fa-external-link{ style: 'padding-left: 5px;' }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      .container.hero
 | 
					      .container.hero
 | 
				
			||||||
        .heading
 | 
					        .heading
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,22 +11,7 @@
 | 
				
			||||||
      = image_tag asset_pack_path('elephant-fren.png'), alt: '', role: 'presentation', class: 'mascot'
 | 
					      = image_tag asset_pack_path('elephant-fren.png'), alt: '', role: 'presentation', class: 'mascot'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .header
 | 
					    .header
 | 
				
			||||||
      .container.links
 | 
					      = render 'links'
 | 
				
			||||||
        .brand
 | 
					 | 
				
			||||||
          = link_to root_url do
 | 
					 | 
				
			||||||
            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        %ul.nav
 | 
					 | 
				
			||||||
          %li
 | 
					 | 
				
			||||||
            - if user_signed_in?
 | 
					 | 
				
			||||||
              = link_to t('settings.back'), root_url, class: 'webapp-btn'
 | 
					 | 
				
			||||||
            - else
 | 
					 | 
				
			||||||
              = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
 | 
					 | 
				
			||||||
          %li= link_to t('about.about_this'), about_more_path
 | 
					 | 
				
			||||||
          %li
 | 
					 | 
				
			||||||
            = link_to 'https://joinmastodon.org/' do
 | 
					 | 
				
			||||||
              = "#{t('about.other_instances')}"
 | 
					 | 
				
			||||||
              %i.fa.fa-external-link{ style: 'padding-left: 5px;' }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      .container.hero
 | 
					      .container.hero
 | 
				
			||||||
        .floats
 | 
					        .floats
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,19 +4,7 @@
 | 
				
			||||||
.landing-page
 | 
					.landing-page
 | 
				
			||||||
  .header-wrapper.compact
 | 
					  .header-wrapper.compact
 | 
				
			||||||
    .header
 | 
					    .header
 | 
				
			||||||
      .container.links
 | 
					      = render 'links'
 | 
				
			||||||
        .brand
 | 
					 | 
				
			||||||
          = link_to root_url do
 | 
					 | 
				
			||||||
            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        %ul.nav
 | 
					 | 
				
			||||||
          %li
 | 
					 | 
				
			||||||
            - if user_signed_in?
 | 
					 | 
				
			||||||
              = link_to t('settings.back'), root_url, class: 'webapp-btn'
 | 
					 | 
				
			||||||
            - else
 | 
					 | 
				
			||||||
              = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
 | 
					 | 
				
			||||||
          %li= link_to t('about.about_this'), about_more_path
 | 
					 | 
				
			||||||
          %li= link_to t('about.other_instances'), 'https://joinmastodon.org/'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .extended-description
 | 
					  .extended-description
 | 
				
			||||||
    .container
 | 
					    .container
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,18 @@
 | 
				
			||||||
- content_for :page_title do
 | 
					- content_for :page_title do
 | 
				
			||||||
  = t('auth.set_new_password')
 | 
					  = t('auth.set_new_password')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
 | 
					  = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
 | 
				
			||||||
  = render 'shared/error_messages', object: resource
 | 
					    = render 'shared/error_messages', object: resource
 | 
				
			||||||
  = f.input :reset_password_token, as: :hidden
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  = f.input :password, autofocus: true, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
 | 
					    - if use_pam? || current_user.encrypted_password.present?
 | 
				
			||||||
  = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
 | 
					      = f.input :reset_password_token, as: :hidden
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .actions
 | 
					      = f.input :password, autofocus: true, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
 | 
				
			||||||
    = f.button :button, t('auth.set_new_password'), type: :submit
 | 
					      = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      .actions
 | 
				
			||||||
 | 
					        = f.button :button, t('auth.set_new_password'), type: :submit
 | 
				
			||||||
 | 
					    - else
 | 
				
			||||||
 | 
					      = t('simple_form.labels.defaults.pam_account')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.form-footer= render 'auth/shared/links'
 | 
					.form-footer= render 'auth/shared/links'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,13 +4,16 @@
 | 
				
			||||||
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'auth_edit' }) do |f|
 | 
					= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'auth_edit' }) do |f|
 | 
				
			||||||
  = render 'shared/error_messages', object: resource
 | 
					  = render 'shared/error_messages', object: resource
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  = f.input :email, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
 | 
					  - if !use_pam? || current_user.encrypted_password.present?
 | 
				
			||||||
  = f.input :password, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
 | 
					    = f.input :email, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
 | 
				
			||||||
  = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
 | 
					    = f.input :password, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
 | 
				
			||||||
  = f.input :current_password, placeholder: t('simple_form.labels.defaults.current_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'off' }
 | 
					    = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
 | 
				
			||||||
 | 
					    = f.input :current_password, placeholder: t('simple_form.labels.defaults.current_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'off' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .actions
 | 
					    .actions
 | 
				
			||||||
    = f.button :button, t('generic.save_changes'), type: :submit
 | 
					      = f.button :button, t('generic.save_changes'), type: :submit
 | 
				
			||||||
 | 
					  - else
 | 
				
			||||||
 | 
					    = t('simple_form.labels.defaults.pam_account')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%hr/
 | 
					%hr/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,10 @@
 | 
				
			||||||
  = render partial: 'shared/og'
 | 
					  = render partial: 'shared/og'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
 | 
					= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
 | 
				
			||||||
  = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
 | 
					  - if use_pam?
 | 
				
			||||||
 | 
					    = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.username_or_email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }
 | 
				
			||||||
 | 
					  - else
 | 
				
			||||||
 | 
					    = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
 | 
				
			||||||
  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
 | 
					  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .actions
 | 
					  .actions
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,9 @@
 | 
				
			||||||
= simple_form_for current_user, url: settings_preferences_path, html: { method: :put } do |f|
 | 
					= simple_form_for current_user, url: settings_preferences_path, html: { method: :put } do |f|
 | 
				
			||||||
  = render 'shared/error_messages', object: current_user
 | 
					  = render 'shared/error_messages', object: current_user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .actions
 | 
				
			||||||
 | 
					    = f.button :button, t('generic.save_changes'), type: :submit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  %h4= t 'preferences.languages'
 | 
					  %h4= t 'preferences.languages'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .fields-group
 | 
					  .fields-group
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,19 @@ Warden::Manager.before_logout do |_, warden|
 | 
				
			||||||
  warden.cookies.delete('_session_id')
 | 
					  warden.cookies.delete('_session_id')
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Devise
 | 
				
			||||||
 | 
					  mattr_accessor :pam_authentication
 | 
				
			||||||
 | 
					  @@pam_authentication = false
 | 
				
			||||||
 | 
					  mattr_accessor :pam_controlled_service
 | 
				
			||||||
 | 
					  @@pam_controlled_service = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  class Strategies::PamAuthenticatable
 | 
				
			||||||
 | 
					    def valid?
 | 
				
			||||||
 | 
					      super && ::Devise.pam_authentication
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Devise.setup do |config|
 | 
					Devise.setup do |config|
 | 
				
			||||||
  config.warden do |manager|
 | 
					  config.warden do |manager|
 | 
				
			||||||
    manager.default_strategies(scope: :user).unshift :two_factor_authenticatable
 | 
					    manager.default_strategies(scope: :user).unshift :two_factor_authenticatable
 | 
				
			||||||
| 
						 | 
					@ -96,7 +109,7 @@ Devise.setup do |config|
 | 
				
			||||||
  # given strategies, for example, `config.http_authenticatable = [:database]` will
 | 
					  # given strategies, for example, `config.http_authenticatable = [:database]` will
 | 
				
			||||||
  # enable it only for database authentication. The supported strategies are:
 | 
					  # enable it only for database authentication. The supported strategies are:
 | 
				
			||||||
  # :database      = Support basic authentication with authentication key + password
 | 
					  # :database      = Support basic authentication with authentication key + password
 | 
				
			||||||
  config.http_authenticatable = [:database]
 | 
					  config.http_authenticatable = [:pam, :database]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # If 401 status code should be returned for AJAX requests. True by default.
 | 
					  # If 401 status code should be returned for AJAX requests. True by default.
 | 
				
			||||||
  # config.http_authenticatable_on_xhr = true
 | 
					  # config.http_authenticatable_on_xhr = true
 | 
				
			||||||
| 
						 | 
					@ -301,4 +314,23 @@ Devise.setup do |config|
 | 
				
			||||||
  # When using OmniAuth, Devise cannot automatically set OmniAuth path,
 | 
					  # When using OmniAuth, Devise cannot automatically set OmniAuth path,
 | 
				
			||||||
  # so you need to do it manually. For the users scope, it would be:
 | 
					  # so you need to do it manually. For the users scope, it would be:
 | 
				
			||||||
  # config.omniauth_path_prefix = '/my_engine/users/auth'
 | 
					  # config.omniauth_path_prefix = '/my_engine/users/auth'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # PAM: only look for email field
 | 
				
			||||||
 | 
					  config.usernamefield = nil
 | 
				
			||||||
 | 
					  config.emailfield = "email"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # authentication with pam possible
 | 
				
			||||||
 | 
					  # if not enabled, all pam settings are ignored
 | 
				
			||||||
 | 
					  #config.pam_authentication = true
 | 
				
			||||||
 | 
					  # check if email is actually a username
 | 
				
			||||||
 | 
					  config.check_at_sign = true
 | 
				
			||||||
 | 
					  # suffix for email address generation (warning: without pam must provide email in the pam environment)
 | 
				
			||||||
 | 
					  config.pam_default_suffix = "pam"
 | 
				
			||||||
 | 
					  # name of the pam service
 | 
				
			||||||
 | 
					  # pam "auth" section is evaluated
 | 
				
			||||||
 | 
					  config.pam_default_service = "rpam"
 | 
				
			||||||
 | 
					  # name of the pam service used for checking if an user can register
 | 
				
			||||||
 | 
					  # pam "account" section is evaluated
 | 
				
			||||||
 | 
					  # nil for allowing registration of pam names (not recommended)
 | 
				
			||||||
 | 
					  config.pam_controlled_service = "rpam"
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +53,7 @@ de:
 | 
				
			||||||
        severity: Gewichtung
 | 
					        severity: Gewichtung
 | 
				
			||||||
        type: Importtyp
 | 
					        type: Importtyp
 | 
				
			||||||
        username: Profilname
 | 
					        username: Profilname
 | 
				
			||||||
 | 
					        username_or_email: Profilname oder Email
 | 
				
			||||||
      interactions:
 | 
					      interactions:
 | 
				
			||||||
        must_be_follower: Benachrichtigungen von Nicht-Folgenden blockieren
 | 
					        must_be_follower: Benachrichtigungen von Nicht-Folgenden blockieren
 | 
				
			||||||
        must_be_following: Benachrichtigungen von Profilen blockieren, denen ich nicht folge
 | 
					        must_be_following: Benachrichtigungen von Profilen blockieren, denen ich nicht folge
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,7 @@ en:
 | 
				
			||||||
        severity: Severity
 | 
					        severity: Severity
 | 
				
			||||||
        type: Import type
 | 
					        type: Import type
 | 
				
			||||||
        username: Username
 | 
					        username: Username
 | 
				
			||||||
 | 
					        username_or_email: Username or Email
 | 
				
			||||||
      interactions:
 | 
					      interactions:
 | 
				
			||||||
        must_be_follower: Block notifications from non-followers
 | 
					        must_be_follower: Block notifications from non-followers
 | 
				
			||||||
        must_be_following: Block notifications from people you don't follow
 | 
					        must_be_following: Block notifications from people you don't follow
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								db/migrate/20180109143959_add_remember_token_to_users.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								db/migrate/20180109143959_add_remember_token_to_users.rb
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					class AddRememberTokenToUsers < ActiveRecord::Migration[5.1]
 | 
				
			||||||
 | 
					  def change
 | 
				
			||||||
 | 
					    add_column :users, :remember_token, :string, null: true
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# 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: 20180106000232) do
 | 
					ActiveRecord::Schema.define(version: 20180109143959) 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 "plpgsql"
 | 
					  enable_extension "plpgsql"
 | 
				
			||||||
| 
						 | 
					@ -496,6 +496,7 @@ ActiveRecord::Schema.define(version: 20180106000232) do
 | 
				
			||||||
    t.boolean "disabled", default: false, null: false
 | 
					    t.boolean "disabled", default: false, null: false
 | 
				
			||||||
    t.boolean "moderator", default: false, null: false
 | 
					    t.boolean "moderator", default: false, null: false
 | 
				
			||||||
    t.bigint "invite_id"
 | 
					    t.bigint "invite_id"
 | 
				
			||||||
 | 
					    t.string "remember_token"
 | 
				
			||||||
    t.index ["account_id"], name: "index_users_on_account_id"
 | 
					    t.index ["account_id"], name: "index_users_on_account_id"
 | 
				
			||||||
    t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
 | 
					    t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
 | 
				
			||||||
    t.index ["email"], name: "index_users_on_email", unique: true
 | 
					    t.index ["email"], name: "index_users_on_email", unique: true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,7 @@ RSpec.describe Setting, type: :model do
 | 
				
			||||||
          allow(RailsSettings::Settings).to receive(:object).with(key).and_return(object)
 | 
					          allow(RailsSettings::Settings).to receive(:object).with(key).and_return(object)
 | 
				
			||||||
          allow(described_class).to receive(:default_settings).and_return(default_settings)
 | 
					          allow(described_class).to receive(:default_settings).and_return(default_settings)
 | 
				
			||||||
          allow_any_instance_of(Settings::ScopedSettings).to receive(:thing_scoped).and_return(records)
 | 
					          allow_any_instance_of(Settings::ScopedSettings).to receive(:thing_scoped).and_return(records)
 | 
				
			||||||
          Rails.cache.clear(cache_key)
 | 
					          Rails.cache.delete(cache_key)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let(:object)           { nil }
 | 
					        let(:object)           { nil }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue