diff options
author | Benjamin Neff <benjamin@coding4coffee.ch> | 2022-08-01 00:10:38 +0300 |
---|---|---|
committer | Benjamin Neff <benjamin@coding4coffee.ch> | 2022-08-01 00:12:00 +0300 |
commit | 9485a0263985a5c2a41446e020e02c2accabc2bb (patch) | |
tree | 01bf7a345b4cc80009586c8832ff2a5fdb905a8a | |
parent | 02eba842aed40e6411fbed8db9e32fcd0e59c642 (diff) | |
parent | eaedd3d26ca7e993e42fba02bc4e4fc5e72ae73e (diff) |
Merge branch 'next-minor'v0.7.18.0
211 files changed, 2033 insertions, 1174 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c0964a1a..bd8fbefb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ jobs: fail-fast: false matrix: ruby: + - 2.7 - 2.6 - - 2.5 db: - mysql - postgresql diff --git a/.gitignore b/.gitignore index 7ea15e804..9ecc81afb 100644 --- a/.gitignore +++ b/.gitignore @@ -82,3 +82,9 @@ diaspora.iml # WebTranslateIt .wti + +# MacOS +/__MACOSX/ + +# yarn +node_modules diff --git a/.rubocop.yml b/.rubocop.yml index e1a7219a2..fa0c9d76c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -57,6 +57,12 @@ Layout/SpaceAroundEqualsInParameterDefault: # are needed. Style/StringLiterals: EnforcedStyle: double_quotes + Exclude: + # These files are generated by rails, so it's best to keep them close to the original for smaller diffs + - "config/application.rb" + - "config/boot.rb" + - "config/environment.rb" + - "config/environments/*.rb" # We do not need to support Ruby 1.9, so this is good to use. Style/SymbolArray: diff --git a/.ruby-version b/.ruby-version index 5154b3f68..1effb0034 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6 +2.7 diff --git a/Changelog.md b/Changelog.md index 31c081fb0..83d223c5f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,27 @@ +# 0.7.18.0 + +## Refactor +* Fix order-dependent jasmine test failures and switch to random order [#8333](https://github.com/diaspora/diaspora/pull/8333) +* Get rid of some uses of "execute\_script" in feature specs [#8331](https://github.com/diaspora/diaspora/pull/8331) +* Fix deprecation warnings for sidekiq 7.0 [#8359](https://github.com/diaspora/diaspora/pull/8359) +* Remove entypo-rails dependency to prepare for rails 6 [#8361](https://github.com/diaspora/diaspora/pull/8361) +* Remove compass-rails dependency which is not supported anymore [#8362](https://github.com/diaspora/diaspora/pull/8362) +* Switch to sassc-rails which speeds up `assets:precompile` a lot [#8362](https://github.com/diaspora/diaspora/pull/8362) +* Remove markerb dependency which doesn't exist anymore [#8365](https://github.com/diaspora/diaspora/pull/8365) +* Upgrade to rails 6.1 [#8366](https://github.com/diaspora/diaspora/pull/8366) +* Update the suggested Ruby version to 2.7. If you run into trouble during the update and you followed our installation guides, run `rvm install 2.7`. [#8366](https://github.com/diaspora/diaspora/pull/8366) +* Upgrade to bundler 2 [#8366](https://github.com/diaspora/diaspora/pull/8366) +* Stop checking `/.well-known/host-meta`, check for `/.well-known/nodeinfo` instead [#8377](https://github.com/diaspora/diaspora/pull/8377) +* Handle NodeInfo timeouts gracefully [#8380](https://github.com/diaspora/diaspora/pull/8380) + +## Bug fixes +* Fix that no mails were sent after photo export [#8365](https://github.com/diaspora/diaspora/pull/8365) +* Fix people with quotes in the name causing issues with mail sender [#8365](https://github.com/diaspora/diaspora/pull/8365) + +## Features +* Render posts and comments as HTML in HTML mails [#8365](https://github.com/diaspora/diaspora/pull/8365) +* Add NodeInfo 2.1 support and also read newer versions of NodeInfo [#8379](https://github.com/diaspora/diaspora/pull/8379) + # 0.7.17.0 ## Security @@ -2,7 +2,7 @@ source "https://rubygems.org" -gem "rails", "5.2.7.1" +gem "rails", "6.1.6.1" # Legacy Rails features, remove me! # responders (class level) @@ -10,26 +10,26 @@ gem "responders", "3.0.1" # Appserver -gem "unicorn", "6.0.0", require: false +gem "unicorn", "6.1.0", require: false gem "unicorn-worker-killer", "0.4.5" # Federation -gem "diaspora_federation-json_schema", "0.2.7" -gem "diaspora_federation-rails", "0.2.7" +gem "diaspora_federation-json_schema", "0.2.8" +gem "diaspora_federation-rails", "0.2.8" # API and JSON gem "acts_as_api", "1.0.1" -gem "json", "2.3.0" -gem "json-schema", "2.8.1" +gem "json", "2.6.2" +gem "json-schema", "3.0.0" # Authentication -gem "devise", "4.8.0" +gem "devise", "4.8.1" gem "devise_lastseenable", "0.0.6" -gem "devise-two-factor", "4.0.1" -gem "rqrcode", "2.1.0" +gem "devise-two-factor", "4.0.2" +gem "rqrcode", "2.1.1" # Captcha @@ -37,21 +37,21 @@ gem "simple_captcha2", "0.5.0", require: "simple_captcha" # Background processing -gem "redis", "4.5.1" -gem "sidekiq", "6.2.2" +gem "redis", "4.7.0" +gem "sidekiq", "6.5.1" # Scheduled processing -gem "sidekiq-cron", "1.2.0" +gem "sidekiq-cron", "1.6.0" # Compression -gem "terser", "1.1.7" +gem "terser", "1.1.10" # Configuration gem "configurate", "0.5.0" -gem "toml-rb", "2.1.0" +gem "toml-rb", "2.1.2" # Cross-origin resource sharing @@ -59,46 +59,41 @@ gem "rack-cors", "1.1.1", require: "rack/cors" # CSS -gem "autoprefixer-rails", "10.3.3.0" +gem "autoprefixer-rails", "10.4.7.0" gem "bootstrap-sass", "3.4.1" gem "bootstrap-switch-rails", "3.3.3" # 3.3.4 and 3.3.5 is broken, see https://github.com/Bttstrp/bootstrap-switch/issues/691 -gem "compass-rails", "3.1.0" -gem "sass-rails", "5.0.7" -gem "sprockets-rails", "3.2.2" +gem "sassc-rails", "2.1.2" +gem "sprockets-rails", "3.4.2" # Database group :mysql, optional: true do - gem "mysql2", "0.5.3" + gem "mysql2", "0.5.4" end group :postgresql, optional: true do - gem "pg", "1.2.3" + gem "pg", "1.4.1" end -gem "activerecord-import", "1.1.0" +gem "activerecord-import", "1.4.0" # File uploading gem "carrierwave", "2.2.2" -gem "fog-aws", "3.12.0" +gem "fog-aws", "3.14.0" gem "mini_magick", "4.11.0" # GUID generation gem "uuid", "2.3.9" -# Icons - -gem "entypo-rails", "3.0.0" - # JavaScript gem "handlebars_assets", "0.23.9" -gem "jquery-rails", "4.4.0" -gem "js-routes", "2.1.2" -gem "js_image_paths", "0.1.1" +gem "jquery-rails", "4.5.0" +gem "js_image_paths", "0.2.0" +gem "js-routes", "2.2.4" source "https://gems.diasporafoundation.org" do - gem "rails-assets-jquery", "3.5.1" # Should be kept in sync with jquery-rails + gem "rails-assets-jquery", "3.6.0" # Should be kept in sync with jquery-rails gem "rails-assets-jquery.ui", "1.11.4" gem "rails-assets-highlightjs", "9.12.0" @@ -112,6 +107,7 @@ source "https://gems.diasporafoundation.org" do gem "rails-assets-markdown-it-sup", "1.0.0" gem "rails-assets-backbone", "1.3.3" + gem "rails-assets-bootstrap", "3.4.1" gem "rails-assets-bootstrap-markdown", "2.10.0" gem "rails-assets-corejs-typeahead", "1.2.1" gem "rails-assets-fine-uploader", "5.13.0" @@ -132,21 +128,17 @@ gem "markdown-it-html5-embed", "1.0.0" gem "http_accept_language", "2.1.1" gem "i18n-inflector-rails", "1.0.7" -gem "rails-i18n", "5.1.3" - -# Mail - -gem "markerb", "1.1.0" +gem "rails-i18n", "6.0.0" # Map gem "leaflet-rails", "1.7.0" # Parsing -gem "nokogiri", "1.12.5" +gem "nokogiri", "1.13.7" gem "open_graph_reader", "0.7.2" # also update User-Agent in features/support/webmock.rb and open_graph_cache_spec.rb gem "redcarpet", "3.5.1" -gem "ruby-oembed", "0.15.0" +gem "ruby-oembed", "0.16.1" gem "twitter-text", "1.14.7" # RTL support @@ -159,8 +151,8 @@ gem "secure_headers", "6.3.3" # Services -gem "omniauth", "2.0.4" -gem "omniauth-rails_csrf_protection", "1.0.0" +gem "omniauth", "2.1.0" +gem "omniauth-rails_csrf_protection", "1.0.1" gem "omniauth-tumblr", "1.2" gem "omniauth-twitter", "1.4.0" gem "omniauth-wordpress", "0.2.2" @@ -171,7 +163,7 @@ gem "openid_connect", "1.3.0" # Serializers -gem "active_model_serializers", "0.9.7" +gem "active_model_serializers", "0.9.8" # XMPP chat dependencies gem "diaspora-prosody-config", "0.0.7" @@ -179,12 +171,12 @@ gem "rails-assets-diaspora_jsxc", "0.1.5.develop.7", source: "https://gems.diasp # Tags -gem "acts-as-taggable-on", "8.1.0" +gem "acts-as-taggable-on", "9.0.1" # URIs and HTTP gem "addressable", "2.8.0", require: "addressable/uri" -gem "faraday", "0.17.4" +gem "faraday", "0.17.5" gem "faraday-cookie_jar", "0.0.7" gem "faraday_middleware", "0.14.0" gem "typhoeus", "1.4.0" @@ -192,9 +184,9 @@ gem "typhoeus", "1.4.0" # Views gem "gon", "6.4.0" -gem "hamlit", "2.15.1" +gem "hamlit", "2.16.0" gem "mobile-fu", "1.4.0" -gem "rails-timeago", "2.19.1" +gem "rails-timeago", "2.20.0" gem "will_paginate", "3.3.1" # Logging @@ -210,7 +202,7 @@ gem "rubyzip", "2.3.2", require: "zip" # https://github.com/gitlabhq/gitlabhq/issues/3826 # https://github.com/gitlabhq/gitlabhq/pull/3852 # https://github.com/discourse/discourse/pull/238 -gem "minitest" +gem "minitest", "5.15.0" gem "versionist", "2.0.1" @@ -238,15 +230,15 @@ group :production do # we don"t install these on travis to speed up test runs # Third party asset hosting - gem "asset_sync", "2.15.0", require: false + gem "asset_sync", "2.15.2", require: false end group :development do # Linters - gem "haml_lint", "0.37.1", require: false + gem "haml_lint", "0.40.0", require: false gem "pronto", "0.11.0", require: false gem "pronto-eslint", "0.11.0", require: false - gem "pronto-haml", "0.11.0", require: false + gem "pronto-haml", "0.11.1", require: false gem "pronto-rubocop", "0.11.1", require: false gem "pronto-scss", "0.11.0", require: false gem "rubocop", "0.93.1", require: false @@ -261,7 +253,7 @@ group :development do gem "turbo_dev_assets", "0.0.2" - gem "listen", "3.5.1" + gem "listen", "3.7.1" end group :test do @@ -269,7 +261,6 @@ group :test do gem "fixture_builder", "0.5.2" gem "fuubar", "2.5.1" - gem "json-schema-rspec", "0.0.4" gem "rspec-json_expectations", "~> 2.1" # Cucumber (integration tests) @@ -284,18 +275,18 @@ group :test do gem "factory_girl_rails", "4.9.0" gem "shoulda-matchers", "4.5.1" - gem "timecop", "0.9.4" + gem "timecop", "0.9.5" gem "webmock", "3.14.0", require: false - gem "diaspora_federation-test", "0.2.7" + gem "diaspora_federation-test", "0.2.8" end group :development, :test do # RSpec (unit tests, some integration tests) - gem "rspec-rails", "5.0.2" + gem "rspec-rails", "5.1.2" # Cucumber (integration tests) - gem "cucumber-rails", "2.4.0", require: false + gem "cucumber-rails", "2.5.1", require: false # Jasmine (client side application tests (JS)) gem "chrome_remote", "0.3.0" diff --git a/Gemfile.lock b/Gemfile.lock index c0fb9eecf..fe7e5403d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,54 +2,72 @@ GEM remote: https://rubygems.org/ remote: https://gems.diasporafoundation.org/ specs: - actioncable (5.2.7.1) - actionpack (= 5.2.7.1) + actioncable (6.1.6.1) + actionpack (= 6.1.6.1) + activesupport (= 6.1.6.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.7.1) - actionpack (= 5.2.7.1) - actionview (= 5.2.7.1) - activejob (= 5.2.7.1) + actionmailbox (6.1.6.1) + actionpack (= 6.1.6.1) + activejob (= 6.1.6.1) + activerecord (= 6.1.6.1) + activestorage (= 6.1.6.1) + activesupport (= 6.1.6.1) + mail (>= 2.7.1) + actionmailer (6.1.6.1) + actionpack (= 6.1.6.1) + actionview (= 6.1.6.1) + activejob (= 6.1.6.1) + activesupport (= 6.1.6.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.7.1) - actionview (= 5.2.7.1) - activesupport (= 5.2.7.1) - rack (~> 2.0, >= 2.0.8) + actionpack (6.1.6.1) + actionview (= 6.1.6.1) + activesupport (= 6.1.6.1) + rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.7.1) - activesupport (= 5.2.7.1) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (6.1.6.1) + actionpack (= 6.1.6.1) + activerecord (= 6.1.6.1) + activestorage (= 6.1.6.1) + activesupport (= 6.1.6.1) + nokogiri (>= 1.8.5) + actionview (6.1.6.1) + activesupport (= 6.1.6.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - active_model_serializers (0.9.7) + rails-html-sanitizer (~> 1.1, >= 1.2.0) + active_model_serializers (0.9.8) activemodel (>= 3.2) concurrent-ruby (~> 1.0) - activejob (5.2.7.1) - activesupport (= 5.2.7.1) + activejob (6.1.6.1) + activesupport (= 6.1.6.1) globalid (>= 0.3.6) - activemodel (5.2.7.1) - activesupport (= 5.2.7.1) - activerecord (5.2.7.1) - activemodel (= 5.2.7.1) - activesupport (= 5.2.7.1) - arel (>= 9.0) - activerecord-import (1.1.0) - activerecord (>= 3.2) - activestorage (5.2.7.1) - actionpack (= 5.2.7.1) - activerecord (= 5.2.7.1) - marcel (~> 1.0.0) - activesupport (5.2.7.1) + activemodel (6.1.6.1) + activesupport (= 6.1.6.1) + activerecord (6.1.6.1) + activemodel (= 6.1.6.1) + activesupport (= 6.1.6.1) + activerecord-import (1.4.0) + activerecord (>= 4.2) + activestorage (6.1.6.1) + actionpack (= 6.1.6.1) + activejob (= 6.1.6.1) + activerecord (= 6.1.6.1) + activesupport (= 6.1.6.1) + marcel (~> 1.0) + mini_mime (>= 1.1.0) + activesupport (6.1.6.1) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - acts-as-taggable-on (8.1.0) - activerecord (>= 5.0, < 6.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + acts-as-taggable-on (9.0.1) + activerecord (>= 6.0, < 7.1) acts_as_api (1.0.1) activemodel (>= 3.0.0) activesupport (>= 3.0.0) @@ -60,8 +78,7 @@ GEM apparition (0.6.0) capybara (~> 3.13, < 4) websocket-driver (>= 0.6.5) - arel (9.0.0) - asset_sync (2.15.0) + asset_sync (2.15.2) activemodel (>= 4.1.0) fog-core mime-types (>= 2.99) @@ -70,9 +87,9 @@ GEM attr_encrypted (3.1.0) encryptor (~> 3.0.0) attr_required (1.0.1) - autoprefixer-rails (10.3.3.0) + autoprefixer-rails (10.4.7.0) execjs (~> 2) - bcrypt (3.1.16) + bcrypt (3.1.18) bindata (2.4.10) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) @@ -123,22 +140,6 @@ GEM chunky_png (1.4.0) citrus (3.0.2) coderay (1.1.3) - compass (1.0.3) - chunky_png (~> 1.2) - compass-core (~> 1.0.2) - compass-import-once (~> 1.0.5) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) - sass (>= 3.3.13, < 3.5) - compass-core (1.0.3) - multi_json (~> 1.0) - sass (>= 3.3.0, < 3.5) - compass-import-once (1.0.5) - sass (>= 3.2, < 3.5) - compass-rails (3.1.0) - compass (~> 1.0.0) - sass-rails (< 5.1) - sprockets (< 4.0) concurrent-ruby (1.1.10) configurate (0.5.0) connection_pool (2.2.5) @@ -161,11 +162,11 @@ GEM cucumber-api-steps (0.14.0) cucumber (>= 2.0.2) jsonpath (>= 0.1.2) - cucumber-core (10.1.0) + cucumber-core (10.1.1) cucumber-gherkin (~> 22.0, >= 22.0.0) cucumber-messages (~> 17.1, >= 17.1.1) - cucumber-tag-expressions (~> 4.0, >= 4.0.2) - cucumber-create-meta (6.0.2) + cucumber-tag-expressions (~> 4.1, >= 4.1.0) + cucumber-create-meta (6.0.4) cucumber-messages (~> 17.1, >= 17.1.1) sys-uname (~> 1.2, >= 1.2.2) cucumber-cucumber-expressions (14.0.0) @@ -174,71 +175,68 @@ GEM cucumber-html-formatter (17.0.0) cucumber-messages (~> 17.1, >= 17.1.0) cucumber-messages (17.1.1) - cucumber-rails (2.4.0) + cucumber-rails (2.5.1) capybara (>= 2.18, < 4) cucumber (>= 3.2, < 8) mime-types (~> 3.3) nokogiri (~> 1.10) - railties (>= 5.0, < 7) + railties (>= 5.0, < 8) rexml (~> 3.0) webrick (~> 1.7) cucumber-tag-expressions (4.1.0) - cucumber-wire (6.2.0) + cucumber-wire (6.2.1) cucumber-core (~> 10.1, >= 10.1.0) cucumber-cucumber-expressions (~> 14.0, >= 14.0.0) - cucumber-messages (~> 17.1, >= 17.1.1) database_cleaner-active_record (2.0.1) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - devise (4.8.0) + devise (4.8.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-two-factor (4.0.1) - activesupport (< 6.2) + devise-two-factor (4.0.2) + activesupport (< 7.1) attr_encrypted (>= 1.3, < 4, != 2) devise (~> 4.0) - railties (< 6.2) + railties (< 7.1) rotp (~> 6.0) devise_lastseenable (0.0.6) devise rails (>= 3.0.4) diaspora-prosody-config (0.0.7) - diaspora_federation (0.2.7) + diaspora_federation (0.2.8) faraday (>= 0.9.0, < 1.0) faraday_middleware (>= 0.10.0, < 1.0) nokogiri (~> 1.6, >= 1.6.8) typhoeus (~> 1.0) valid (~> 1.0) - diaspora_federation-json_schema (0.2.7) - diaspora_federation-rails (0.2.7) - actionpack (>= 4.2, < 6) - diaspora_federation (= 0.2.7) - diaspora_federation-test (0.2.7) - diaspora_federation (= 0.2.7) + diaspora_federation-json_schema (0.2.8) + diaspora_federation-rails (0.2.8) + actionpack (>= 4.2, < 7) + diaspora_federation (= 0.2.8) + diaspora_federation-test (0.2.8) + diaspora_federation (= 0.2.8) fabrication (~> 2.16) uuid (~> 2.3, >= 2.3.8) - diff-lcs (1.4.4) + diff-lcs (1.5.0) docile (1.4.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) encryptor (3.0.0) - entypo-rails (3.0.0) - railties (>= 4.1, < 6) equalizer (0.0.11) erubi (1.10.0) eslintrb (2.1.0) execjs multi_json (>= 1.3) rake - et-orbi (1.2.6) + et-orbi (1.2.7) tzinfo ethon (0.15.0) ffi (>= 1.15.0) - excon (0.88.0) + excon (0.92.3) execjs (2.8.1) eye (0.10.0) celluloid (~> 0.17.3) @@ -252,14 +250,14 @@ GEM factory_girl_rails (4.9.0) factory_girl (~> 4.9.0) railties (>= 3.0.0) - faraday (0.17.4) + faraday (0.17.5) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.7) faraday (>= 0.8.0) http-cookie (~> 1.0.0) faraday_middleware (0.14.0) faraday (>= 0.7.4, < 1.0) - ffi (1.15.4) + ffi (1.15.5) ffi-compiler (1.0.1) ffi (>= 1.0.0) rake @@ -267,15 +265,14 @@ GEM activerecord (>= 2) activesupport (>= 2) hashdiff - fog-aws (3.12.0) + fog-aws (3.14.0) fog-core (~> 2.1) fog-json (~> 1.1) fog-xml (~> 0.1) - ipaddress (~> 0.8) - fog-core (2.2.4) + fog-core (2.3.0) builder excon (~> 0.71) - formatador (~> 0.2) + formatador (>= 0.2, < 2.0) mime-types fog-json (1.2.0) fog-core @@ -283,18 +280,18 @@ GEM fog-xml (0.1.4) fog-core nokogiri (>= 1.5.11, < 2.0.0) - formatador (0.3.0) - fugit (1.5.2) - et-orbi (~> 1.1, >= 1.1.8) + formatador (1.1.0) + fugit (1.5.3) + et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) fuubar (2.5.1) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) get_process_mem (0.2.7) ffi (~> 1.0) - gitlab (4.17.0) + gitlab (4.18.0) httparty (~> 0.18) - terminal-table (~> 1.5, >= 1.5.1) + terminal-table (>= 1.5.1) globalid (1.0.0) activesupport (>= 5.0) gon (6.4.0) @@ -305,13 +302,13 @@ GEM haml (5.2.2) temple (>= 0.8.0) tilt - haml_lint (0.37.1) + haml_lint (0.40.0) haml (>= 4.0, < 5.3) parallel (~> 1.10) rainbow rubocop (>= 0.50.0) sysexits (~> 1.1) - hamlit (2.15.1) + hamlit (2.16.0) temple (>= 0.8.2) thor tilt @@ -320,13 +317,13 @@ GEM sprockets (>= 2.0.0) tilt (>= 1.2) hashdiff (1.0.1) - hashie (4.1.0) + hashie (5.0.0) http (4.4.1) addressable (~> 2.3) http-cookie (~> 1.0) http-form_data (~> 2.2) http-parser (~> 1.2.0) - http-cookie (1.0.4) + http-cookie (1.0.5) domain_name (~> 0.5) http-form_data (2.3.0) http-parser (1.2.3) @@ -337,7 +334,7 @@ GEM mime-types (~> 3.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - i18n (1.10.0) + i18n (1.12.0) concurrent-ruby (~> 1.0) i18n-inflector (2.6.7) i18n (>= 0.4.1) @@ -345,10 +342,9 @@ GEM actionpack (>= 3.0.0) i18n-inflector (~> 2.6) railties (>= 3.0.0) - image_processing (1.12.1) + image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) - ipaddress (0.8.3) jasmine (3.10.0) jasmine-core (~> 3.10.0) phantomjs @@ -357,42 +353,39 @@ GEM webrick jasmine-core (3.10.1) jasmine-jquery-rails (2.0.3) - jquery-rails (4.4.0) + jquery-rails (4.5.0) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - js-routes (2.1.2) + js-routes (2.2.4) railties (>= 4) - js_image_paths (0.1.1) - rails (>= 4.0, < 6.0) + js_image_paths (0.2.0) + rails (>= 4.0, < 8.0) sprockets (>= 3.0.0) - json (2.3.0) + json (2.6.2) json-jwt (1.13.0) activesupport (>= 4.2) aes_key_wrap bindata - json-schema (2.8.1) - addressable (>= 2.4) - json-schema-rspec (0.0.4) - json-schema (~> 2.5) - rspec - jsonpath (1.1.0) + json-schema (3.0.0) + addressable (>= 2.8) + jsonpath (1.1.2) multi_json - jwt (2.3.0) + jwt (2.4.1) kgio (2.11.4) kostya-sigar (2.0.10) leaflet-rails (1.7.0) rails (>= 4.2.0) - listen (3.5.1) + listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) little-plugger (1.1.4) - logging (2.3.0) + logging (2.3.1) little-plugger (~> 1.1) multi_json (~> 1.14) logging-rails (0.6.0) logging (>= 1.8) - loofah (2.16.0) + loofah (2.18.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) macaddr (1.7.2) @@ -401,16 +394,15 @@ GEM mini_mime (>= 0.1.1) marcel (1.0.2) markdown-it-html5-embed (1.0.0) - markerb (1.1.0) memoizable (0.4.2) thread_safe (~> 0.3, >= 0.3.1) method_source (1.0.0) - mime-types (3.3.1) + mime-types (3.4.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.0901) + mime-types-data (3.2022.0105) mini_magick (4.11.0) mini_mime (1.1.2) - mini_portile2 (2.6.1) + mini_portile2 (2.8.0) minitest (5.15.0) mobile-fu (1.4.0) rack-mobile-detect @@ -418,34 +410,35 @@ GEM multi_json (1.15.0) multi_test (0.1.2) multi_xml (0.6.0) - multipart-post (2.1.1) - mysql2 (0.5.3) + multipart-post (2.2.3) + mysql2 (0.5.4) naught (1.1.0) nio4r (2.5.8) - nokogiri (1.12.5) - mini_portile2 (~> 2.6.1) + nokogiri (1.13.7) + mini_portile2 (~> 2.8.0) racc (~> 1.4) - oauth (0.5.7) - oauth2 (1.4.7) - faraday (>= 0.8, < 2.0) + oauth (0.5.10) + oauth2 (2.0.2) + faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) - multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - octokit (4.21.0) + rash_alt (>= 0.4, < 1) + version_gem (~> 1.0) + octokit (4.22.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) - omniauth (2.0.4) + omniauth (2.1.0) hashie (>= 3.4.6) - rack (>= 1.6.2, < 3) + rack (>= 2.2.3) rack-protection omniauth-oauth (1.2.0) oauth omniauth (>= 1.0, < 3) - omniauth-oauth2 (1.7.2) - oauth2 (~> 1.4) - omniauth (>= 1.9, < 3) - omniauth-rails_csrf_protection (1.0.0) + omniauth-oauth2 (1.8.0) + oauth2 (>= 1.4, < 3) + omniauth (~> 2.0) + omniauth-rails_csrf_protection (1.0.1) actionpack (>= 4.2) omniauth (~> 2.0) omniauth-tumblr (1.2) @@ -470,10 +463,10 @@ GEM validate_url webfinger (>= 1.0.1) orm_adapter (0.5.0) - parallel (1.21.0) - parser (3.0.2.0) + parallel (1.22.1) + parser (3.1.2.0) ast (~> 2.4.1) - pg (1.2.3) + pg (1.4.1) phantomjs (2.1.1.0) pronto (0.11.0) gitlab (~> 4.4, >= 4.4.0) @@ -486,10 +479,9 @@ GEM pronto-eslint (0.11.0) eslintrb (~> 2.0, >= 2.0.0) pronto (~> 0.11.0) - pronto-haml (0.11.0) + pronto-haml (0.11.1) haml_lint (~> 0.23) pronto (~> 0.11.0) - rubocop (< 1.0) pronto-rubocop (0.11.1) pronto (~> 0.11.0) rubocop (>= 0.63.1, < 2.0) @@ -502,10 +494,10 @@ GEM pry-byebug (3.8.0) byebug (~> 11.0) pry (~> 0.10) - public_suffix (4.0.6) + public_suffix (4.0.7) raabro (1.4.0) racc (1.6.0) - rack (2.2.3) + rack (2.2.4) rack-cors (1.1.1) rack (>= 2.0.0) rack-google-analytics (1.2.0) @@ -520,25 +512,27 @@ GEM json-jwt (>= 1.11.0) rack (>= 2.1.0) rack-piwik (0.3.0) - rack-protection (2.1.0) + rack-protection (2.2.0) rack rack-rewrite (1.5.1) rack-ssl (1.4.1) rack - rack-test (1.1.0) - rack (>= 1.0, < 3) - rails (5.2.7.1) - actioncable (= 5.2.7.1) - actionmailer (= 5.2.7.1) - actionpack (= 5.2.7.1) - actionview (= 5.2.7.1) - activejob (= 5.2.7.1) - activemodel (= 5.2.7.1) - activerecord (= 5.2.7.1) - activestorage (= 5.2.7.1) - activesupport (= 5.2.7.1) - bundler (>= 1.3.0) - railties (= 5.2.7.1) + rack-test (2.0.2) + rack (>= 1.3) + rails (6.1.6.1) + actioncable (= 6.1.6.1) + actionmailbox (= 6.1.6.1) + actionmailer (= 6.1.6.1) + actionpack (= 6.1.6.1) + actiontext (= 6.1.6.1) + actionview (= 6.1.6.1) + activejob (= 6.1.6.1) + activemodel (= 6.1.6.1) + activerecord (= 6.1.6.1) + activestorage (= 6.1.6.1) + activesupport (= 6.1.6.1) + bundler (>= 1.15.0) + railties (= 6.1.6.1) sprockets-rails (>= 2.0.0) rails-assets-autosize (4.0.2) rails-assets-backbone (1.3.3) @@ -564,7 +558,7 @@ GEM rails-assets-jasmine (3.4.0) rails-assets-jasmine-ajax (4.0.0) rails-assets-jasmine (~> 3) - rails-assets-jquery (3.5.1) + rails-assets-jquery (3.6.0) rails-assets-jquery-colorbox (1.6.4) rails-assets-jquery (>= 1.3.2) rails-assets-jquery-fullscreen-plugin (0.5.0) @@ -594,54 +588,52 @@ GEM rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.4.2) + rails-html-sanitizer (1.4.3) loofah (~> 2.3) - rails-i18n (5.1.3) + rails-i18n (6.0.0) i18n (>= 0.7, < 2) - railties (>= 5.0, < 6) - rails-timeago (2.19.1) - actionpack (>= 3.1) - activesupport (>= 3.1) - railties (5.2.7.1) - actionpack (= 5.2.7.1) - activesupport (= 5.2.7.1) + railties (>= 6.0.0, < 7) + rails-timeago (2.20.0) + actionpack (>= 5.2) + activesupport (>= 5.2) + railties (6.1.6.1) + actionpack (= 6.1.6.1) + activesupport (= 6.1.6.1) method_source - rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) - rainbow (3.0.0) - raindrops (0.19.2) + rake (>= 12.2) + thor (~> 1.0) + rainbow (3.1.1) + raindrops (0.20.0) rake (12.3.3) - rb-fsevent (0.11.0) + rash_alt (0.4.12) + hashie (>= 3.4) + rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) redcarpet (3.5.1) - redis (4.5.1) - regexp_parser (2.1.1) - request_store (1.5.0) + redis (4.7.0) + regexp_parser (2.5.0) + request_store (1.5.1) rack (>= 1.4) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) rexml (3.2.5) rotp (6.2.0) - rqrcode (2.1.0) + rqrcode (2.1.1) chunky_png (~> 1.0) rqrcode_core (~> 1.0) rqrcode_core (1.2.0) - rspec (3.10.0) - rspec-core (~> 3.10.0) - rspec-expectations (~> 3.10.0) - rspec-mocks (~> 3.10.0) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) + rspec-support (~> 3.11.0) rspec-json_expectations (2.2.0) - rspec-mocks (3.10.2) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-rails (5.0.2) + rspec-support (~> 3.11.0) + rspec-rails (5.1.2) actionpack (>= 5.2) activesupport (>= 5.2) railties (>= 5.2) @@ -649,7 +641,7 @@ GEM rspec-expectations (~> 3.10) rspec-mocks (~> 3.10) rspec-support (~> 3.10) - rspec-support (3.10.3) + rspec-support (3.11.0) rubocop (0.93.1) parallel (~> 1.10) parser (>= 2.7.1.5) @@ -659,27 +651,27 @@ GEM rubocop-ast (>= 0.6.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (1.7.0) - parser (>= 3.0.1.1) + rubocop-ast (1.17.0) + parser (>= 3.1.1.0) rubocop-rails (2.9.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 0.90.0, < 2.0) - ruby-oembed (0.15.0) + ruby-oembed (0.16.1) ruby-progressbar (1.11.0) - ruby-vips (2.1.3) + ruby-vips (2.1.4) ffi (~> 1.12) rubyzip (2.3.2) rugged (1.0.1) sass (3.4.25) - sass-rails (5.0.7) - railties (>= 4.0.0, < 6) - sass (~> 3.1) - sprockets (>= 2.8, < 4.0) - sprockets-rails (>= 2.0, < 4.0) - tilt (>= 1.1, < 3) sassc (2.4.0) ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) @@ -689,12 +681,12 @@ GEM secure_headers (6.3.3) shoulda-matchers (4.5.1) activesupport (>= 4.2.0) - sidekiq (6.2.2) + sidekiq (6.5.1) connection_pool (>= 2.2.2) rack (~> 2.0) redis (>= 4.2.0) - sidekiq-cron (1.2.0) - fugit (~> 1.1) + sidekiq-cron (1.6.0) + fugit (~> 1) sidekiq (>= 4.2.1) simple_captcha2 (0.5.0) rails (>= 4.1) @@ -704,15 +696,15 @@ GEM simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) - simplecov_json_formatter (0.1.3) + simplecov_json_formatter (0.1.4) sinon-rails (1.15.0) railties (>= 3.1) - sprockets (3.7.2) + sprockets (4.1.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.2) - actionpack (>= 4.0) - activesupport (>= 4.0) + sprockets-rails (3.4.2) + actionpack (>= 5.2) + activesupport (>= 5.2) sprockets (>= 3.0.0) ssrf_filter (1.0.7) state_machines (0.5.0) @@ -726,16 +718,16 @@ GEM sysexits (1.2.0) systemu (2.6.5) temple (0.8.2) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - terser (1.1.7) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + terser (1.1.10) execjs (>= 0.3.0, < 3) thor (1.2.1) thread_safe (0.3.6) tilt (2.0.10) - timecop (0.9.4) + timecop (0.9.5) timers (4.3.3) - toml-rb (2.1.0) + toml-rb (2.1.2) citrus (~> 3.0, > 3.0) turbo_dev_assets (0.0.2) twitter (7.0.0) @@ -753,13 +745,13 @@ GEM unf (~> 0.1.0) typhoeus (1.4.0) ethon (>= 0.9.0) - tzinfo (1.2.9) - thread_safe (~> 0.1) + tzinfo (2.0.4) + concurrent-ruby (~> 1.0) unf (0.1.4) unf_ext - unf_ext (0.0.8) + unf_ext (0.0.8.2) unicode-display_width (1.8.0) - unicorn (6.0.0) + unicorn (6.1.0) kgio (~> 2.6) raindrops (~> 0.7) unicorn-worker-killer (0.4.5) @@ -771,9 +763,10 @@ GEM validate_email (0.1.6) activemodel (>= 3.0) mail (>= 2.2.5) - validate_url (1.0.13) + validate_url (1.0.15) activemodel (>= 3.0.0) public_suffix + version_gem (1.1.0) versionist (2.0.1) activesupport (>= 3) railties (>= 3) @@ -794,81 +787,79 @@ GEM will_paginate (3.3.1) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.26) + yard (0.9.28) + webrick (~> 1.7.0) + zeitwerk (2.6.0) PLATFORMS ruby DEPENDENCIES - active_model_serializers (= 0.9.7) - activerecord-import (= 1.1.0) - acts-as-taggable-on (= 8.1.0) + active_model_serializers (= 0.9.8) + activerecord-import (= 1.4.0) + acts-as-taggable-on (= 9.0.1) acts_as_api (= 1.0.1) addressable (= 2.8.0) apparition (= 0.6.0) - asset_sync (= 2.15.0) - autoprefixer-rails (= 10.3.3.0) + asset_sync (= 2.15.2) + autoprefixer-rails (= 10.4.7.0) bootstrap-sass (= 3.4.1) bootstrap-switch-rails (= 3.3.3) capybara (= 3.35.3) carrierwave (= 2.2.2) chrome_remote (= 0.3.0) - compass-rails (= 3.1.0) configurate (= 0.5.0) cucumber-api-steps (= 0.14) - cucumber-rails (= 2.4.0) + cucumber-rails (= 2.5.1) database_cleaner-active_record (= 2.0.1) - devise (= 4.8.0) - devise-two-factor (= 4.0.1) + devise (= 4.8.1) + devise-two-factor (= 4.0.2) devise_lastseenable (= 0.0.6) diaspora-prosody-config (= 0.0.7) - diaspora_federation-json_schema (= 0.2.7) - diaspora_federation-rails (= 0.2.7) - diaspora_federation-test (= 0.2.7) - entypo-rails (= 3.0.0) + diaspora_federation-json_schema (= 0.2.8) + diaspora_federation-rails (= 0.2.8) + diaspora_federation-test (= 0.2.8) eye (= 0.10.0) factory_girl_rails (= 4.9.0) - faraday (= 0.17.4) + faraday (= 0.17.5) faraday-cookie_jar (= 0.0.7) faraday_middleware (= 0.14.0) fixture_builder (= 0.5.2) - fog-aws (= 3.12.0) + fog-aws (= 3.14.0) fuubar (= 2.5.1) gon (= 6.4.0) - haml_lint (= 0.37.1) - hamlit (= 2.15.1) + haml_lint (= 0.40.0) + hamlit (= 2.16.0) handlebars_assets (= 0.23.9) http_accept_language (= 2.1.1) i18n-inflector-rails (= 1.0.7) jasmine (= 3.10.0) jasmine-jquery-rails (= 2.0.3) - jquery-rails (= 4.4.0) - js-routes (= 2.1.2) - js_image_paths (= 0.1.1) - json (= 2.3.0) - json-schema (= 2.8.1) - json-schema-rspec (= 0.0.4) + jquery-rails (= 4.5.0) + js-routes (= 2.2.4) + js_image_paths (= 0.2.0) + json (= 2.6.2) + json-schema (= 3.0.0) leaflet-rails (= 1.7.0) - listen (= 3.5.1) + listen (= 3.7.1) logging-rails (= 0.6.0) markdown-it-html5-embed (= 1.0.0) - markerb (= 1.1.0) mini_magick (= 4.11.0) - minitest + minitest (= 5.15.0) mobile-fu (= 1.4.0) - mysql2 (= 0.5.3) - nokogiri (= 1.12.5) - omniauth (= 2.0.4) - omniauth-rails_csrf_protection (= 1.0.0) + mysql2 (= 0.5.4) + nokogiri (= 1.13.7) + omniauth (= 2.1.0) + omniauth-rails_csrf_protection (= 1.0.1) omniauth-tumblr (= 1.2) omniauth-twitter (= 1.4.0) omniauth-wordpress (= 0.2.2) open_graph_reader (= 0.7.2) openid_connect (= 1.3.0) - pg (= 1.2.3) + pg (= 1.4.1) pronto (= 0.11.0) pronto-eslint (= 0.11.0) - pronto-haml (= 0.11.0) + pronto-haml (= 0.11.1) pronto-rubocop (= 0.11.1) pronto-scss (= 0.11.0) pry @@ -878,17 +869,18 @@ DEPENDENCIES rack-piwik (= 0.3.0) rack-rewrite (= 1.5.1) rack-ssl (= 1.4.1) - rails (= 5.2.7.1) + rails (= 6.1.6.1) rails-assets-autosize (= 4.0.2)! rails-assets-backbone (= 1.3.3)! rails-assets-blueimp-gallery (= 2.33.0)! + rails-assets-bootstrap (= 3.4.1)! rails-assets-bootstrap-markdown (= 2.10.0)! rails-assets-corejs-typeahead (= 1.2.1)! rails-assets-diaspora_jsxc (= 0.1.5.develop.7)! rails-assets-fine-uploader (= 5.13.0)! rails-assets-highlightjs (= 9.12.0)! rails-assets-jasmine-ajax (= 4.0.0)! - rails-assets-jquery (= 3.5.1)! + rails-assets-jquery (= 3.6.0)! rails-assets-jquery-placeholder (= 2.3.1)! rails-assets-jquery-textchange (= 0.2.3)! rails-assets-jquery.are-you-sure (= 1.9.0)! @@ -903,36 +895,36 @@ DEPENDENCIES rails-assets-markdown-it-sup (= 1.0.0)! rails-assets-utatti-perfect-scrollbar (= 1.4.0)! rails-controller-testing (= 1.0.5) - rails-i18n (= 5.1.3) - rails-timeago (= 2.19.1) + rails-i18n (= 6.0.0) + rails-timeago (= 2.20.0) redcarpet (= 3.5.1) - redis (= 4.5.1) + redis (= 4.7.0) responders (= 3.0.1) - rqrcode (= 2.1.0) + rqrcode (= 2.1.1) rspec-json_expectations (~> 2.1) - rspec-rails (= 5.0.2) + rspec-rails (= 5.1.2) rubocop (= 0.93.1) rubocop-rails (= 2.9.1) - ruby-oembed (= 0.15.0) + ruby-oembed (= 0.16.1) rubyzip (= 2.3.2) - sass-rails (= 5.0.7) + sassc-rails (= 2.1.2) secure_headers (= 6.3.3) shoulda-matchers (= 4.5.1) - sidekiq (= 6.2.2) - sidekiq-cron (= 1.2.0) + sidekiq (= 6.5.1) + sidekiq-cron (= 1.6.0) simple_captcha2 (= 0.5.0) simplecov (= 0.21.2) sinon-rails (= 1.15.0) - sprockets-rails (= 3.2.2) + sprockets-rails (= 3.4.2) string-direction (= 1.2.2) - terser (= 1.1.7) - timecop (= 0.9.4) - toml-rb (= 2.1.0) + terser (= 1.1.10) + timecop (= 0.9.5) + toml-rb (= 2.1.2) turbo_dev_assets (= 0.0.2) twitter (= 7.0.0) twitter-text (= 1.14.7) typhoeus (= 1.4.0) - unicorn (= 6.0.0) + unicorn (= 6.1.0) unicorn-worker-killer (= 0.4.5) uuid (= 2.3.9) versionist (= 2.0.1) @@ -940,4 +932,4 @@ DEPENDENCIES will_paginate (= 3.3.1) BUNDLED WITH - 1.17.3 + 2.1.4 diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index fc75a31f6..3b8db2b12 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -1,11 +1,14 @@ +//= link_tree ../images + +//= link main.js +//= link mobile/mobile.js //= link contact-list.js //= link jquery3.js //= link jquery_ujs.js -//= link main.js //= link jsxc.js //= link bookmarklet.js //= link mobile/bookmarklet.js -//= link mobile/mobile.js -//= link error_pages.css + //= link admin.css +//= link error_pages.css //= link rtl.css diff --git a/app/assets/javascripts/app/helpers/text_formatter.js b/app/assets/javascripts/app/helpers/text_formatter.js index c9a302fe9..814665959 100644 --- a/app/assets/javascripts/app/helpers/text_formatter.js +++ b/app/assets/javascripts/app/helpers/text_formatter.js @@ -43,7 +43,7 @@ var hashtagPlugin = window.markdownitHashtag; md.use(hashtagPlugin, { - // compare tag_text_regexp in app/models/acts_as_taggable_on-tag.rb + // compare tag_text_regexp in config/initializers/acts_as_taggable_on.rb hashtagRegExp: "[" + PosixBracketExpressions.word + "\\u055b" + // Armenian emphasis mark "\\u055c" + // Armenian exclamation mark diff --git a/app/assets/javascripts/app/views/tag_following_list_view.js b/app/assets/javascripts/app/views/tag_following_list_view.js index d284f137c..41af8e7e5 100644 --- a/app/assets/javascripts/app/views/tag_following_list_view.js +++ b/app/assets/javascripts/app/views/tag_following_list_view.js @@ -48,7 +48,7 @@ app.views.TagFollowingList = app.views.Base.extend({ if(evt){ evt.preventDefault(); } var name = this.$(".tag_input").val(); - // compare tag_text_regexp in app/models/acts_as_taggable_on-tag.rb + // compare tag_text_regexp in config/initializers/acts_as_taggable_on.rb var normalizedName = (name === "<3" ? name : name.replace( new RegExp("[^" + PosixBracketExpressions.alnum + "_\\-]+", "gi"), "").toLowerCase()); diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss index 06c6d9507..ecaeab657 100644 --- a/app/assets/stylesheets/_application.scss +++ b/app/assets/stylesheets/_application.scss @@ -11,7 +11,6 @@ @import 'icons'; @import 'animations'; @import 'flash_messages'; -@import 'sprites'; @import 'hovercard'; @import 'base'; @import 'interactions'; diff --git a/app/assets/stylesheets/login.scss b/app/assets/stylesheets/login.scss index bdb62a343..13a8c0757 100644 --- a/app/assets/stylesheets/login.scss +++ b/app/assets/stylesheets/login.scss @@ -5,9 +5,9 @@ padding-top: 25px; .logos-asterisk { + background: image-url('branding/logos/asterisk.png') no-repeat; height: 154px; - margin: auto; - margin-bottom: 12px; + margin: auto auto 12px; width: 154px; } diff --git a/app/assets/stylesheets/navbar_left.scss b/app/assets/stylesheets/navbar_left.scss index 3fde9e3a8..6d062bf3a 100644 --- a/app/assets/stylesheets/navbar_left.scss +++ b/app/assets/stylesheets/navbar_left.scss @@ -202,10 +202,23 @@ .social-media-logos-twitter-24x24, .social-media-logos-tumblr-24x24, .social-media-logos-wordpress-24x24 { + background-repeat: no-repeat; height: 24px; width: 24px; } + .social-media-logos-twitter-24x24 { + background-image: image-url('social-media-logos/twitter-24x24.png'); + } + + .social-media-logos-tumblr-24x24 { + background-image: image-url('social-media-logos/tumblr-24x24.png'); + } + + .social-media-logos-wordpress-24x24 { + background-image: image-url('social-media-logos/wordpress-24x24.png'); + } + a { display: inline-block; } diff --git a/app/assets/stylesheets/publisher.scss b/app/assets/stylesheets/publisher.scss index 6db248519..e07293d25 100644 --- a/app/assets/stylesheets/publisher.scss +++ b/app/assets/stylesheets/publisher.scss @@ -43,6 +43,7 @@ .btn.btn-link.question_mark:hover .entypo-cog { color: $black; } .dim { opacity: 0.3; } .social-media-logos-wordpress-16x16 { + background: image-url('social-media-logos/wordpress-16x16.png') no-repeat; display: inline-block; height: 16px; width: 16px; diff --git a/app/assets/stylesheets/sprites.scss b/app/assets/stylesheets/sprites.scss deleted file mode 100644 index 981e20cc3..000000000 --- a/app/assets/stylesheets/sprites.scss +++ /dev/null @@ -1,5 +0,0 @@ -/* ===== sprites ===== */ -@import 'branding/logos/*.png'; -@import 'social-media-logos/*.png'; -@include all-logos-sprites; -@include all-social-media-logos-sprites; diff --git a/app/assets/templates/pod_table_entry_tpl.jst.hbs b/app/assets/templates/pod_table_entry_tpl.jst.hbs index 46f0a9909..3c2bb0605 100644 --- a/app/assets/templates/pod_table_entry_tpl.jst.hbs +++ b/app/assets/templates/pod_table_entry_tpl.jst.hbs @@ -1,5 +1,5 @@ -<td class="ssl-status""> +<td class="ssl-status"> {{#if ssl}} <i title="{{t 'admin.pods.ssl_enabled'}}" class="entypo-check"> {{else}} @@ -14,6 +14,7 @@ <td> {{#if has_no_errors}} <i title="{{status_text}}" class="glyphicon glyphicon-ok"></i> + {{software}} {{else}} {{status_text}} {{/if}} diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index f03036e10..f7d4a49a4 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -15,8 +15,7 @@ class PeopleController < ApplicationController respond_to :json, :only => [:index, :show] rescue_from ActiveRecord::RecordNotFound do - render :file => Rails.root.join('public', '404').to_s, - :format => :html, :layout => false, :status => 404 + render file: Rails.root.join("public/404.html").to_s, format: :html, layout: false, status: :not_found end rescue_from Diaspora::AccountClosed do diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 99a0297a0..f129ecb05 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -34,7 +34,7 @@ class UsersController < ApplicationController def update_privacy_settings privacy_params = params.fetch(:user).permit(:strip_exif) - if current_user.update_attributes(strip_exif: privacy_params[:strip_exif]) + if current_user.update(strip_exif: privacy_params[:strip_exif]) flash[:notice] = t("users.update.settings_updated") else flash[:error] = t("users.update.settings_not_updated") @@ -199,7 +199,7 @@ class UsersController < ApplicationController end def change_language(user_data) - if @user.update_attributes(user_data) + if @user.update(user_data) I18n.locale = @user.language flash.now[:notice] = t("users.update.language_changed") else @@ -229,7 +229,7 @@ class UsersController < ApplicationController end def change_settings(user_data, successful="users.update.settings_updated", error="users.update.settings_not_updated") - if @user.update_attributes(user_data) + if @user.update(user_data) flash.now[:notice] = t(successful) else flash.now[:error] = t(error) diff --git a/app/helpers/notifier_helper.rb b/app/helpers/notifier_helper.rb index e7a05af5f..9edcea043 100644 --- a/app/helpers/notifier_helper.rb +++ b/app/helpers/notifier_helper.rb @@ -4,21 +4,19 @@ module NotifierHelper include PostsHelper # @param post [Post] The post object. - # @param opts [Hash] Optional hash. Accepts :length parameters. + # @param opts [Hash] Optional hash. Accepts :html parameter. # @return [String] The formatted post. def post_message(post, opts={}) - if post.respond_to? :message - post.message.try(:plain_text_without_markdown).presence || post_page_title(post) - else - I18n.translate "notifier.a_post_you_shared" - end + rendered = opts[:html] ? post.message&.markdownified_for_mail : post.message&.plain_text_without_markdown + rendered.presence || post_page_title(post) end # @param comment [Comment] The comment to process. + # @param opts [Hash] Optional hash. Accepts :html parameter. # @return [String] The formatted comment. def comment_message(comment, opts={}) if comment.post.public? - comment.message.plain_text_without_markdown + opts[:html] ? comment.message.markdownified_for_mail : comment.message.plain_text_without_markdown else I18n.translate "notifier.a_limited_post_comment" end diff --git a/app/helpers/people_helper.rb b/app/helpers/people_helper.rb index 40c79bb43..87c622503 100644 --- a/app/helpers/people_helper.rb +++ b/app/helpers/people_helper.rb @@ -27,10 +27,10 @@ module PeopleHelper def person_link(person, opts={}) css_class = person_link_class(person, opts[:class]) - remote_or_hovercard_link = Rails.application.routes.url_helpers.person_path(person).html_safe - "<a data-hovercard='#{remote_or_hovercard_link}' href='#{remote_or_hovercard_link}' class='#{css_class}'>"\ - "#{html_escape_once(opts[:display_name] || person.name)}</a>"\ - .html_safe + remote_or_hovercard_link = person_path(person) + tag.a('data-hovercard': remote_or_hovercard_link, href: remote_or_hovercard_link, class: css_class) do + opts[:display_name] || person.name + end end def person_image_tag(person, size = :thumb_small) @@ -44,15 +44,12 @@ module PeopleHelper if opts[:to] == :photos link_to person_image_tag(person, opts[:size]), person_photos_path(person) else - css_class = person_link_class(person, opts[:class]) - remote_or_hovercard_link = Rails.application.routes.url_helpers.person_path(person).html_safe - "<a href='#{remote_or_hovercard_link}' class='#{css_class}' #{('target=' + opts[:target]) if opts[:target]}> - #{person_image_tag(person, opts[:size])} - </a>".html_safe + tag.a(href: person_path(person), class: person_link_class(person, opts[:class])) do + person_image_tag(person, opts[:size]) + end end end - # Rails.application.routes.url_helpers is needed since this is indirectly called from a model def local_or_remote_person_path(person, opts={}) opts.merge!(:protocol => AppConfig.pod_uri.scheme, :host => AppConfig.pod_uri.authority) absolute = opts.delete(:absolute) @@ -61,19 +58,11 @@ module PeopleHelper username = person.username unless username.include?('.') opts.merge!(:username => username) - if absolute - return Rails.application.routes.url_helpers.user_profile_url(opts) - else - return Rails.application.routes.url_helpers.user_profile_path(opts) - end + return absolute ? user_profile_url(opts) : user_profile_path(opts) end end - if absolute - return Rails.application.routes.url_helpers.person_url(person, opts) - else - return Rails.application.routes.url_helpers.person_path(person, opts) - end + absolute ? person_url(person, opts) : person_path(person, opts) end private diff --git a/app/mailers/export_mailer.rb b/app/mailers/export_mailer.rb index da4af5f30..e7219353d 100644 --- a/app/mailers/export_mailer.rb +++ b/app/mailers/export_mailer.rb @@ -2,38 +2,31 @@ class ExportMailer < ApplicationMailer def export_complete_for(user) - @user = user - - mail(to: @user.email, subject: I18n.t('notifier.export_email.subject', name: @user.name)) do |format| - format.html { render 'users/export_email' } - format.text { render 'users/export_email' } - end + send_mail(user, I18n.t("notifier.export_email.subject", name: user.name), + I18n.t("notifier.export_email.body", url: download_profile_user_url, name: user.first_name)) end def export_failure_for(user) - @user = user - - mail(to: @user.email, subject: I18n.t('notifier.export_failure_email.subject', name: @user.name)) do |format| - format.html { render 'users/export_failure_email' } - format.text { render 'users/export_failure_email' } - end + send_mail(user, I18n.t("notifier.export_failure_email.subject", name: user.name), + I18n.t("notifier.export_failure_email.body", name: user.first_name)) end def export_photos_complete_for(user) - @user = user - - mail(to: @user.email, subject: I18n.t('notifier.export_photos_email.subject', name: @user.name)) do |format| - format.html { render 'users/export_photos_email' } - format.text { render 'users/export_photos_email' } - end + send_mail(user, I18n.t("notifier.export_photos_email.subject", name: user.name), + I18n.t("notifier.export_photos_email.body", url: download_photos_user_url, name: user.first_name)) end def export_photos_failure_for(user) - @user = user + send_mail(user, I18n.t("notifier.export_photos_failure_email.subject", name: user.name), + I18n.t("notifier.export_photos_failure_email.body", name: user.first_name)) + end + + private - mail(to: @user.email, subject: I18n.t('notifier.export_photos_failure_email.subject', name: @user.name)) do |format| - format.html { render 'users/export_photos_failure_email' } - format.text { render 'users/export_photos_failure_email' } + def send_mail(user, subject, body) + mail(to: user.email, subject: subject) do |format| + format.html { render "notifier/plain_markdown_email", locals: {body: body} } + format.text { render "notifier/plain_markdown_email", locals: {body: body} } end end end diff --git a/app/mailers/maintenance.rb b/app/mailers/maintenance.rb index 1ff5d4ac3..5c23ce53d 100644 --- a/app/mailers/maintenance.rb +++ b/app/mailers/maintenance.rb @@ -2,16 +2,15 @@ class Maintenance < ApplicationMailer def account_removal_warning(user) - @user = user - @login_url = new_user_session_url - @pod_url = AppConfig.environment.url - @after_days = AppConfig.settings.maintenance.remove_old_users.after_days.to_s - @remove_after = @user.remove_after - - I18n.with_locale(@user.language) do - mail(to: @user.email, subject: I18n.t("notifier.remove_old_user.subject")) do |format| - format.text - format.html + I18n.with_locale(user.language) do + body = I18n.t("notifier.remove_old_user.body", + pod_url: AppConfig.environment.url, + login_url: new_user_session_url, + after_days: AppConfig.settings.maintenance.remove_old_users.after_days.to_s, + remove_after: user.remove_after) + mail(to: user.email, subject: I18n.t("notifier.remove_old_user.subject")) do |format| + format.text { render "notifier/plain_markdown_email", locals: {body: body} } + format.html { render "notifier/plain_markdown_email", locals: {body: body} } end end end diff --git a/app/mailers/notification_mailers/base.rb b/app/mailers/notification_mailers/base.rb index 8aa3d28c6..7b2a6135c 100644 --- a/app/mailers/notification_mailers/base.rb +++ b/app/mailers/notification_mailers/base.rb @@ -35,16 +35,14 @@ module NotificationMailers private def default_headers - headers = { - from: "\"#{AppConfig.settings.pod_name}\" <#{AppConfig.mail.sender_address}>", - host: "#{AppConfig.pod_uri.host}", - to: name_and_address(@recipient.name, @recipient.email) - } - return headers if @sender.blank? - sender_in_header = @sender.profile.full_name.empty? ? @sender.username : @sender.name - headers[:from] = "\"#{AppConfig.settings.pod_name} (#{sender_in_header})\" <#{AppConfig.mail.sender_address}>" + from_name = AppConfig.settings.pod_name + from_name += " (#{@sender.profile.full_name.empty? ? @sender.username : @sender.name})" if @sender.present? - headers + { + from: name_and_address(from_name, AppConfig.mail.sender_address), + to: name_and_address(@recipient.name, @recipient.email), + template_name: self.class.name.demodulize.underscore + } end def with_recipient_locale(&block) diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index 47c3b71bf..a04949486 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -24,46 +24,37 @@ class Notifier < ApplicationMailer } end - unless subject - subject = I18n.t('notifier.single_admin.subject') - end + subject ||= I18n.t("notifier.single_admin.subject") - default_opts = {:to => @receiver.email, - :from => AppConfig.mail.sender_address, - :subject => subject, :host => AppConfig.pod_uri.host} + default_opts = {to: @receiver.email, from: AppConfig.mail.sender_address, subject: subject} default_opts.merge!(opts) - mail(default_opts) do |format| - format.text - format.html - end + mail(default_opts) end def invite(email, inviter, invitation_code, locale) - @inviter = inviter - @invitation_code = invitation_code - I18n.with_locale(locale) do mail_opts = {to: email, from: "\"#{AppConfig.settings.pod_name}\" <#{AppConfig.mail.sender_address}>", - subject: I18n.t("notifier.invited_you", name: @inviter.name), - host: AppConfig.pod_uri.host} + subject: I18n.t("notifier.invited_you", name: inviter.name)} + name = inviter.full_name.empty? ? inviter.diaspora_handle : "#{inviter.name} (#{inviter.diaspora_handle})" + body = I18n.t("notifier.invite.message", + invite_url: invite_code_url(invitation_code), + diasporafoundation_url: "https://diasporafoundation.org/", + user: name, + diaspora_id: inviter.diaspora_handle) mail(mail_opts) do |format| - format.text { render :layout => nil } - format.html { render :layout => nil } + format.text { render "notifier/plain_markdown_email", layout: nil, locals: {body: body} } + format.html { render "notifier/plain_markdown_email", layout: nil, locals: {body: body} } end end end def send_notification(type, *args) - @notification = NotificationMailers.const_get(type.to_s.camelize).new(*args) + @notification = NotificationMailers.const_get(type.camelize).new(*args) with_recipient_locale do - mail(@notification.headers) do |format| - self.action_name = type - format.text - format.html - end + mail(@notification.headers) end end diff --git a/app/mailers/report_mailer.rb b/app/mailers/report_mailer.rb index 507e02600..ad69332fd 100644 --- a/app/mailers/report_mailer.rb +++ b/app/mailers/report_mailer.rb @@ -26,9 +26,10 @@ class ReportMailer < ApplicationMailer private def format(resource) + body = I18n.t("notifier.report_email.body", resource) mail(to: resource[:email], subject: I18n.t("notifier.report_email.subject", type: resource[:type])) do |format| - format.html { render "report/report_email", locals: {resource: resource} } - format.text { render "report/report_email", locals: {resource: resource} } + format.html { render "notifier/plain_markdown_email", locals: {body: body} } + format.text { render "notifier/plain_markdown_email", locals: {body: body} } end end end diff --git a/app/models/acts_as_taggable_on-tag.rb b/app/models/acts_as_taggable_on-tag.rb deleted file mode 100644 index dc5ece4cc..000000000 --- a/app/models/acts_as_taggable_on-tag.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module ActsAsTaggableOn - class Tag - - self.include_root_in_json = false - - def self.tag_text_regexp - @tag_text_regexp ||= "[[:word:]]\u055b\u055c\u055e\u058a_-" - end - - def self.autocomplete(name) - where("name LIKE ?", "#{name.downcase}%").order("name ASC") - end - - def self.normalize(name) - if name =~ /^#?<3/ - # Special case for love, because the world needs more love. - '<3' - elsif name - name.gsub(/[^#{self.tag_text_regexp}]/, '').downcase - end - end - end -end diff --git a/app/models/block.rb b/app/models/block.rb index 48254071a..1d835dc46 100644 --- a/app/models/block.rb +++ b/app/models/block.rb @@ -11,9 +11,9 @@ class Block < ApplicationRecord validate :not_blocking_yourself def not_blocking_yourself - if self.user.person.id == self.person_id - errors[:person_id] << "stop blocking yourself!" - end + return unless user.person.id == person_id + + errors.add(:person_id, "stop blocking yourself!") end # @return [Array<Person>] The recipient of the block diff --git a/app/models/invitation_code.rb b/app/models/invitation_code.rb index 428096756..1f941c818 100644 --- a/app/models/invitation_code.rb +++ b/app/models/invitation_code.rb @@ -16,17 +16,18 @@ class InvitationCode < ApplicationRecord end def add_invites! - self.update_attributes(:count => self.count+100) + update(count: count + 100) end def use! - self.update_attributes(:count => self.count-1) + update(count: count - 1) end def generate_token - begin + loop do self.token = SecureRandom.hex(6) - end while InvitationCode.exists?(:token => self[:token]) + break unless InvitationCode.default_scoped.exists?(token: token) + end end def self.default_inviter_or(user) diff --git a/app/models/message.rb b/app/models/message.rb index e0c738d00..1dd4d9f72 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -37,10 +37,8 @@ class Message < ApplicationRecord private def participant_of_parent_conversation - if conversation && !conversation.participants.include?(author) - errors[:base] << "Author is not participating in the conversation" - else - true - end + return unless conversation&.participants&.exclude?(author) + + errors.add(:base, "Author is not participating in the conversation") end end diff --git a/app/models/pod.rb b/app/models/pod.rb index c64bf4ce2..08692f280 100644 --- a/app/models/pod.rb +++ b/app/models/pod.rb @@ -114,7 +114,7 @@ class Pod < ApplicationRecord def update_from_result(result) self.status = status_from_result(result) update_offline_since - logger.warn "OFFLINE #{result.failure_message}" if offline? + logger.warn "#{uri} OFFLINE: #{result.failure_message}" if offline? attributes_from_result(result) touch(:checked_at) @@ -125,7 +125,7 @@ class Pod < ApplicationRecord def attributes_from_result(result) self.ssl ||= result.ssl - self.error = result.failure_message[0..254] if result.error? + self.error = result.error? ? result.failure_message[0..254] : nil self.software = result.software_version[0..254] if result.software_version.present? self.response_time = result.rt end diff --git a/app/models/report.rb b/app/models/report.rb index ab169e7f1..1da8c4b24 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -22,15 +22,15 @@ class Report < ApplicationRecord end def entry_does_not_exist - if Report.where(item_id: item_id, item_type: item_type).exists?(user_id: user_id) - errors[:base] << 'You cannot report the same post twice.' - end + return unless Report.where(item_id: item_id, item_type: item_type).exists?(user_id: user_id) + + errors.add(:base, "You cannot report the same post twice.") end def post_or_comment_does_exist - if Post.find_by_id(item_id).nil? && Comment.find_by_id(item_id).nil? - errors[:base] << 'Post or comment was already deleted or doesn\'t exists.' - end + return unless Post.find_by(id: item_id).nil? && Comment.find_by(id: item_id).nil? + + errors.add(:base, "Post or comment was already deleted or doesn't exists.") end def destroy_reported_item diff --git a/app/models/reshare.rb b/app/models/reshare.rb index ecbd64971..d3e5115d7 100644 --- a/app/models/reshare.rb +++ b/app/models/reshare.rb @@ -86,9 +86,6 @@ class Reshare < Post private def root_must_be_public - if self.root && !self.root.public - errors[:base] << "Only posts which are public may be reshared." - return false - end + errors.add(:base, "Only posts which are public may be reshared.") if root && !root.public end end diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 4f8e192d7..418b53ed8 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -130,7 +130,7 @@ class StatusMessage < Post private def presence_of_content - errors[:base] << "Cannot create a StatusMessage without content" if text_and_photos_blank? + errors.add(:base, "Cannot create a StatusMessage without content") if text_and_photos_blank? end end diff --git a/app/models/user.rb b/app/models/user.rb index 788fe6aba..4cfd9eb4b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -250,7 +250,7 @@ class User < ApplicationRecord def update_post(post, post_hash={}) if self.owns? post - post.update_attributes(post_hash) + post.update(post_hash) self.dispatch_post(post) end end @@ -375,7 +375,7 @@ class User < ApplicationRecord ########### Profile ###################### def update_profile(params) if photo = params.delete(:photo) - photo.update_attributes(:pending => false) if photo.pending + photo.update(pending: false) if photo.pending params[:image_url] = photo.url(:thumb_large) params[:image_url_medium] = photo.url(:thumb_medium) params[:image_url_small] = photo.url(:thumb_small) @@ -383,7 +383,7 @@ class User < ApplicationRecord params.stringify_keys! params.slice!(*(Profile.column_names+['tag_string', 'date'])) - if self.profile.update_attributes(params) + if profile.update(params) deliver_profile_update true else @@ -535,10 +535,10 @@ class User < ApplicationRecord end def no_person_with_same_username - diaspora_id = "#{self.username}#{User.diaspora_id_host}" - if self.username_changed? && Person.exists?(:diaspora_handle => diaspora_id) - errors[:base] << 'That username has already been taken' - end + diaspora_id = "#{username}#{User.diaspora_id_host}" + return unless username_changed? && Person.exists?(diaspora_handle: diaspora_id) + + errors.add(:base, "That username has already been taken") end def close_account! diff --git a/app/models/user/connecting.rb b/app/models/user/connecting.rb index 232dba405..62a3a4a02 100644 --- a/app/models/user/connecting.rb +++ b/app/models/user/connecting.rb @@ -58,7 +58,7 @@ class User if destroy contact.destroy else - contact.update_attributes(direction => false) + contact.update(direction => false) end end end diff --git a/app/presenters/node_info_presenter.rb b/app/presenters/node_info_presenter.rb index 8eeda65d3..f0c231e27 100644 --- a/app/presenters/node_info_presenter.rb +++ b/app/presenters/node_info_presenter.rb @@ -30,6 +30,8 @@ class NodeInfoPresenter def add_static_data(doc) doc.software.name = "diaspora" + doc.software.repository = "https://github.com/diaspora/diaspora" + doc.software.homepage = "https://diasporafoundation.org/" doc.protocols.protocols << "diaspora" end diff --git a/app/views/devise/mailer/confirmation_instructions.html.haml b/app/views/devise/mailer/confirmation_instructions.html.haml new file mode 100644 index 000000000..f1824c54f --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.haml @@ -0,0 +1,6 @@ +%p + = t("devise.mailer.welcome", username: @resource.username) +%p + = t(".you_can_confirm") +%p + = link_to t(".confirm"), confirmation_url(@resource, confirmation_token: @token) diff --git a/app/views/devise/mailer/confirmation_instructions.markerb b/app/views/devise/mailer/confirmation_instructions.markerb deleted file mode 100644 index 6e0211f1f..000000000 --- a/app/views/devise/mailer/confirmation_instructions.markerb +++ /dev/null @@ -1,7 +0,0 @@ -<%= t('devise.mailer.welcome', username: @resource.username) %> - -<%= t('.you_can_confirm') %> - -[<%= t('.confirm') %>][1] - -[1]: <%= confirmation_url(@resource, confirmation_token: @token) %> diff --git a/app/views/devise/mailer/confirmation_instructions.text.erb b/app/views/devise/mailer/confirmation_instructions.text.erb new file mode 100644 index 000000000..9ce086053 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.text.erb @@ -0,0 +1,4 @@ +<%= t("devise.mailer.welcome", username: @resource.username) %> + +<%= t(".you_can_confirm") %> +<%= confirmation_url(@resource, confirmation_token: @token) %> diff --git a/app/views/devise/mailer/invitation_instructions.markerb b/app/views/devise/mailer/invitation_instructions.markerb deleted file mode 100644 index 8d39da1c6..000000000 --- a/app/views/devise/mailer/invitation_instructions.markerb +++ /dev/null @@ -1 +0,0 @@ -<%= t('.message', :invite_url => invite_code_url(@invitation_code)) %> diff --git a/app/views/devise/mailer/reset_password_instructions.html.haml b/app/views/devise/mailer/reset_password_instructions.html.haml new file mode 100644 index 000000000..0c8f44a3f --- /dev/null +++ b/app/views/devise/mailer/reset_password_instructions.html.haml @@ -0,0 +1,12 @@ +%p + = t("devise.mailer.hello", username: @resource.username) +%p + = t(".someone_requested") +%p + = link_to t(".change"), edit_password_url(@resource, reset_password_token: @token) +%p + = t(".then_connect", username: @resource.username) +%p + = t(".wont_change") +%p + = t(".ignore") diff --git a/app/views/devise/mailer/reset_password_instructions.markerb b/app/views/devise/mailer/reset_password_instructions.markerb deleted file mode 100644 index ac800dd25..000000000 --- a/app/views/devise/mailer/reset_password_instructions.markerb +++ /dev/null @@ -1,13 +0,0 @@ -<%= t('devise.mailer.hello', username: @resource.username) %> - -<%= t('.someone_requested') %> - -[<%= t('.change') %>][1] - -[1]: <%= edit_password_url(@resource, reset_password_token: @token) %> - -<%= t('.then_connect', username: @resource.username) %> - -<%= t('.wont_change') %> - -<%= t('.ignore') %> diff --git a/app/views/devise/mailer/reset_password_instructions.text.erb b/app/views/devise/mailer/reset_password_instructions.text.erb new file mode 100644 index 000000000..48f1dfee4 --- /dev/null +++ b/app/views/devise/mailer/reset_password_instructions.text.erb @@ -0,0 +1,11 @@ +<%= t("devise.mailer.hello", username: @resource.username) %> + +<%= t(".someone_requested") %> + +<%= t(".change") %>: <%= edit_password_url(@resource, reset_password_token: @token) %> + +<%= t(".then_connect", username: @resource.username) %> + +<%= t(".wont_change") %> + +<%= t(".ignore") %> diff --git a/app/views/devise/mailer/unlock_instructions.html.haml b/app/views/devise/mailer/unlock_instructions.html.haml new file mode 100644 index 000000000..c16e8dee7 --- /dev/null +++ b/app/views/devise/mailer/unlock_instructions.html.haml @@ -0,0 +1,8 @@ +%p + = t("devise.mailer.hello", username: @resource.username) +%p + = t(".account_locked") +%p + = t(".click_to_unlock") +%p + = link_to t(".unlock"), unlock_url(@resource, unlock_token: @token) diff --git a/app/views/devise/mailer/unlock_instructions.markerb b/app/views/devise/mailer/unlock_instructions.markerb deleted file mode 100644 index d207a1bb9..000000000 --- a/app/views/devise/mailer/unlock_instructions.markerb +++ /dev/null @@ -1,9 +0,0 @@ -<%= t('devise.mailer.hello', username: @resource.username) %> - -<%= t('.account_locked') %> - -<%= t('.click_to_unlock') %> - -[<%= t('.unlock') %>][1] - -[1]: <%= unlock_url(@resource, unlock_token: @token) %> diff --git a/app/views/devise/mailer/unlock_instructions.text.erb b/app/views/devise/mailer/unlock_instructions.text.erb new file mode 100644 index 000000000..e89aa4353 --- /dev/null +++ b/app/views/devise/mailer/unlock_instructions.text.erb @@ -0,0 +1,6 @@ +<%= t("devise.mailer.hello", username: @resource.username) %> + +<%= t(".account_locked") %> + +<%= t(".click_to_unlock") %> +<%= unlock_url(@resource, unlock_token: @token) %> diff --git a/app/views/errors/error_404.haml b/app/views/errors/error_404.haml index 847b92ef6..d04dbef99 100644 --- a/app/views/errors/error_404.haml +++ b/app/views/errors/error_404.haml @@ -1,10 +1,5 @@ - content_for(:page_title) do The page you were looking for doesn't exist (404) -.transparent.big-number - 404 %h3 These are not the kittens you're looking for. Move along. -%p - %a{href: "javascript:history.back()"} - Go Back? diff --git a/app/views/errors/error_422.haml b/app/views/errors/error_422.haml index cd3af7d46..3c7ff409f 100644 --- a/app/views/errors/error_422.haml +++ b/app/views/errors/error_422.haml @@ -1,13 +1,7 @@ - content_for(:page_title) do The change you wanted was rejected (422) -.transparent.big-number - 422 %h3 The change you wanted was rejected. %p Maybe you tried to change something you didn't have access to. - -%p - %a{href: "javascript:history.back()"} - Go Back? diff --git a/app/views/errors/error_500.haml b/app/views/errors/error_500.haml index d566b86ca..61ed69e54 100644 --- a/app/views/errors/error_500.haml +++ b/app/views/errors/error_500.haml @@ -1,8 +1,6 @@ - content_for(:page_title) do We're sorry, but something went wrong (500) -.transparent.big-number - 500 %h3 Internal server error. Our bad! Sorry about that. :( @@ -10,7 +8,3 @@ - if AppConfig.admins.podmin_email? %p Drop us an email to <a href="mailto:#{AppConfig.admins.podmin_email}">#{AppConfig.admins.podmin_email}</a>. - -%p - %a{href: "javascript:history.back()"} - Go Back? diff --git a/app/views/layouts/error_page.haml b/app/views/layouts/error_page.haml index 258ce9cb3..15f7047ea 100644 --- a/app/views/layouts/error_page.haml +++ b/app/views/layouts/error_page.haml @@ -11,5 +11,12 @@ = yield(:head) - %body{class: "error-#{@code}", id: "error_#{@code}"} + %body{class: "error-#{local_assigns[:code]}", id: "error_#{local_assigns[:code]}"} + .transparent.big-number + = local_assigns[:code] + = yield + + %p + %a{href: "javascript:history.back()"} + Go Back? diff --git a/app/views/layouts/notifier.html.haml b/app/views/layouts/notifier.html.haml index 74acfc8b1..1c497b543 100644 --- a/app/views/layouts/notifier.html.haml +++ b/app/views/layouts/notifier.html.haml @@ -1,7 +1,7 @@ %table{cellspacing: 0, cellpadding: 0, border: 0, style: "font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px"} %tr - - if @notification.try(:sender) + - if @notification&.sender.present? %td{width: "60px", style: "vertical-align: top"}> %div{style: "background-color: #eee; height: 50px; width: 50px"} = image_tag @notification.sender.profile.image_url(:thumb_small), alt: @notification.sender.name, diff --git a/app/views/layouts/notifier.text.haml b/app/views/layouts/notifier.text.haml index e018e0311..8a7a083a5 100644 --- a/app/views/layouts/notifier.text.haml +++ b/app/views/layouts/notifier.text.haml @@ -1,4 +1,5 @@ != yield + +!= "-- " != t("notifier.email_sent_by_diaspora", pod_name: pod_name) -!= t("notifier.to_change_your_notification_settings") -!= edit_user_url +!= "#{t('notifier.to_change_your_notification_settings')}: #{edit_user_url}" diff --git a/app/views/maintenance/account_removal_warning.markerb b/app/views/maintenance/account_removal_warning.markerb deleted file mode 100644 index 7303bafae..000000000 --- a/app/views/maintenance/account_removal_warning.markerb +++ /dev/null @@ -1,2 +0,0 @@ -<%= t('notifier.remove_old_user.body', pod_url: @pod_url, login_url: @login_url, after_days: @after_days, remove_after: @remove_after) %> - diff --git a/app/views/notifier/_notifier_css.haml b/app/views/notifier/_notifier_css.haml deleted file mode 100644 index 4ca518b2d..000000000 --- a/app/views/notifier/_notifier_css.haml +++ /dev/null @@ -1,28 +0,0 @@ -:css - body{ - width:600px; - font-family: 'Helvetica',sans-serif; - } - #container{ - } - header{ - margin-bottom: 25px; - } - p{ - padding:5px; - } - p.small{ - font-size:smaller; - color:#999; - font-style:italic; - } - a{ - color:#107FC9; - font-weight:bold; - } - a:hover{ - color: #22AAE0; - } - a:active{ - color: #005D9C; - } diff --git a/app/views/notifier/also_commented.html.haml b/app/views/notifier/also_commented.html.haml new file mode 100644 index 000000000..ec6fdfc94 --- /dev/null +++ b/app/views/notifier/also_commented.html.haml @@ -0,0 +1,4 @@ += comment_message(@notification.comment, html: true) +%p + = link_to t("notifier.comment_on_post.reply", name: @notification.comment.post.author_first_name), + post_url(@notification.comment.post, anchor: @notification.comment.guid) diff --git a/app/views/notifier/also_commented.markerb b/app/views/notifier/also_commented.markerb deleted file mode 100644 index 8c5023664..000000000 --- a/app/views/notifier/also_commented.markerb +++ /dev/null @@ -1,5 +0,0 @@ -<%= comment_message(@notification.comment, :process_newlines => true) %> - -[<%= t('notifier.comment_on_post.reply', :name => @notification.comment_post.author_first_name) %>][1] - -[1]: <%= post_url(@notification.comment_post, anchor: @notification.comment.guid) %> diff --git a/app/views/notifier/also_commented.text.erb b/app/views/notifier/also_commented.text.erb new file mode 100644 index 000000000..bce14edd8 --- /dev/null +++ b/app/views/notifier/also_commented.text.erb @@ -0,0 +1,4 @@ +<%= comment_message(@notification.comment) %> + +<%= t("notifier.comment_on_post.reply", name: @notification.comment.post.author_first_name) %> +<%= post_url(@notification.comment.post, anchor: @notification.comment.guid) %> diff --git a/app/views/notifier/comment_on_post.html.haml b/app/views/notifier/comment_on_post.html.haml new file mode 100644 index 000000000..ec6fdfc94 --- /dev/null +++ b/app/views/notifier/comment_on_post.html.haml @@ -0,0 +1,4 @@ += comment_message(@notification.comment, html: true) +%p + = link_to t("notifier.comment_on_post.reply", name: @notification.comment.post.author_first_name), + post_url(@notification.comment.post, anchor: @notification.comment.guid) diff --git a/app/views/notifier/comment_on_post.markerb b/app/views/notifier/comment_on_post.markerb deleted file mode 100644 index 7d4d86802..000000000 --- a/app/views/notifier/comment_on_post.markerb +++ /dev/null @@ -1,5 +0,0 @@ -<%= comment_message(@notification.comment, :process_newlines => true) %> - -[<%= t('notifier.comment_on_post.reply', :name => @notification.comment.parent_author_name) %>][1] - -[1]: <%= post_url(@notification.comment.post, anchor: @notification.comment.guid) %> diff --git a/app/views/notifier/comment_on_post.text.erb b/app/views/notifier/comment_on_post.text.erb new file mode 100644 index 000000000..bce14edd8 --- /dev/null +++ b/app/views/notifier/comment_on_post.text.erb @@ -0,0 +1,4 @@ +<%= comment_message(@notification.comment) %> + +<%= t("notifier.comment_on_post.reply", name: @notification.comment.post.author_first_name) %> +<%= post_url(@notification.comment.post, anchor: @notification.comment.guid) %> diff --git a/app/views/notifier/confirm_email.html.haml b/app/views/notifier/confirm_email.html.haml new file mode 100644 index 000000000..87e334688 --- /dev/null +++ b/app/views/notifier/confirm_email.html.haml @@ -0,0 +1,6 @@ +%p + = t("notifier.hello", name: @notification.recipient_first_name) +%p + = t("notifier.confirm_email.click_link", unconfirmed_email: @notification.recipient_unconfirmed_email) +%p + = link_to nil, confirm_email_url(token: @notification.recipient_confirm_email_token) diff --git a/app/views/notifier/confirm_email.markerb b/app/views/notifier/confirm_email.markerb deleted file mode 100644 index 6b32bfa0a..000000000 --- a/app/views/notifier/confirm_email.markerb +++ /dev/null @@ -1,5 +0,0 @@ -<%= t('notifier.hello', :name => @notification.recipient_first_name) %> - -<%= t('notifier.confirm_email.click_link', :unconfirmed_email => @notification.recipient_unconfirmed_email) %> - -<<%= confirm_email_url(:token => @notification.recipient_confirm_email_token) %>> diff --git a/app/views/notifier/confirm_email.text.erb b/app/views/notifier/confirm_email.text.erb new file mode 100644 index 000000000..4b310db63 --- /dev/null +++ b/app/views/notifier/confirm_email.text.erb @@ -0,0 +1,5 @@ +<%= t("notifier.hello", name: @notification.recipient_first_name) %> + +<%= t("notifier.confirm_email.click_link", unconfirmed_email: @notification.recipient_unconfirmed_email) %> + +<%= confirm_email_url(token: @notification.recipient_confirm_email_token) %> diff --git a/app/views/notifier/contacts_birthday.html.haml b/app/views/notifier/contacts_birthday.html.haml new file mode 100644 index 000000000..4402cf41d --- /dev/null +++ b/app/views/notifier/contacts_birthday.html.haml @@ -0,0 +1,5 @@ +%p + = t(".birthday", name: @notification.person.name) +%p + = link_to t(".view_profile", name: @notification.person.first_name), + local_or_remote_person_path(@notification.person, absolute: true) diff --git a/app/views/notifier/contacts_birthday.markerb b/app/views/notifier/contacts_birthday.markerb deleted file mode 100644 index ee4d27770..000000000 --- a/app/views/notifier/contacts_birthday.markerb +++ /dev/null @@ -1,6 +0,0 @@ - -<%= t(".birthday", name: @notification.person.name) %> - -[<%= t(".view_profile", name: @notification.person.name) %>][1] - -[1]: <%= local_or_remote_person_path(@notification.person, absolute: true) %> diff --git a/app/views/notifier/contacts_birthday.text.erb b/app/views/notifier/contacts_birthday.text.erb new file mode 100644 index 000000000..773fc41c1 --- /dev/null +++ b/app/views/notifier/contacts_birthday.text.erb @@ -0,0 +1,4 @@ +<%= t(".birthday", name: @notification.person.name) %> + +<%= t(".view_profile", name: @notification.person.first_name) %> +<%= local_or_remote_person_path(@notification.person, absolute: true) %> diff --git a/app/views/notifier/csrf_token_fail.html.haml b/app/views/notifier/csrf_token_fail.html.haml new file mode 100644 index 000000000..08c27d4b9 --- /dev/null +++ b/app/views/notifier/csrf_token_fail.html.haml @@ -0,0 +1,4 @@ +- message = t("notifier.csrf_token_fail.body", + name: @notification.recipient_first_name, + link: "https://owasp.org/www-community/attacks/csrf") +!= Redcarpet::Markdown.new(Diaspora::Markdownify::Email).render(message) diff --git a/app/views/notifier/csrf_token_fail.markerb b/app/views/notifier/csrf_token_fail.markerb deleted file mode 100644 index 22f3164ea..000000000 --- a/app/views/notifier/csrf_token_fail.markerb +++ /dev/null @@ -1 +0,0 @@ -<%= t("notifier.csrf_token_fail.body", name: @notification.recipient_first_name, link: "https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)") %> diff --git a/app/views/notifier/csrf_token_fail.text.erb b/app/views/notifier/csrf_token_fail.text.erb new file mode 100644 index 000000000..ef034ed02 --- /dev/null +++ b/app/views/notifier/csrf_token_fail.text.erb @@ -0,0 +1,3 @@ +<%= t("notifier.csrf_token_fail.body", + name: @notification.recipient_first_name, + link: "https://owasp.org/www-community/attacks/csrf") %> diff --git a/app/views/notifier/invite.markerb b/app/views/notifier/invite.markerb deleted file mode 100644 index 8c20a00c0..000000000 --- a/app/views/notifier/invite.markerb +++ /dev/null @@ -1,6 +0,0 @@ -<%= t('.message', - invite_url: invite_code_url(@invitation_code), - diasporafoundation_url: 'https://diasporafoundation.org/', - user: @inviter.try(:full_name).empty? ? @inviter.try(:diaspora_handle) : "#{@inviter.name} (#{@inviter.diaspora_handle})", - diaspora_id: @inviter.try(:diaspora_handle)) -%> diff --git a/app/views/notifier/liked.html.haml b/app/views/notifier/liked.html.haml new file mode 100644 index 000000000..96cf3770f --- /dev/null +++ b/app/views/notifier/liked.html.haml @@ -0,0 +1,10 @@ +- if @notification.like_target.public? + %p + #{t('.liked', name: @notification.sender_name)}: + = post_message(@notification.like_target, html: true) +- else + %p + #{t('notifier.liked.limited_post', name: @notification.sender_name)}. + +%p + = link_to t(".view_post"), post_url(@notification.like_target) diff --git a/app/views/notifier/liked.markerb b/app/views/notifier/liked.markerb deleted file mode 100644 index 8ed88a979..000000000 --- a/app/views/notifier/liked.markerb +++ /dev/null @@ -1,11 +0,0 @@ -<% if @notification.like_target.public? %> -<%= "#{t('.liked', :name => "#{@notification.sender_name}")}:" %> - -<%= post_message(@notification.like_target, :process_newlines => true) %> -<% else %> -<%= "#{t('notifier.liked.limited_post', :name => "#{@notification.sender_name}")}." %> -<% end %> - -[<%= t('.view_post') %>][1] - -[1]: <%= post_url(@notification.like_target) %> diff --git a/app/views/notifier/liked.text.erb b/app/views/notifier/liked.text.erb new file mode 100644 index 000000000..ce743ade3 --- /dev/null +++ b/app/views/notifier/liked.text.erb @@ -0,0 +1,10 @@ +<% if @notification.like_target.public? %> +<%= "#{t(".liked", name: @notification.sender_name)}:" %> + +<%= post_message(@notification.like_target) %> +<% else %> +<%= "#{t("notifier.liked.limited_post", name: @notification.sender_name)}." %> +<% end %> + +<%= t(".view_post") %> +<%= post_url(@notification.like_target) %> diff --git a/app/views/notifier/mentioned.html.haml b/app/views/notifier/mentioned.html.haml new file mode 100644 index 000000000..715de7647 --- /dev/null +++ b/app/views/notifier/mentioned.html.haml @@ -0,0 +1,9 @@ +- if @notification.post.public? + = post_message(@notification.post, html: true) +- else + %p + = t("notifier.mentioned.limited_post") + +%p + = link_to t("notifier.comment_on_post.reply", name: @notification.post.author_first_name), + post_url(@notification.post) diff --git a/app/views/notifier/mentioned.markerb b/app/views/notifier/mentioned.markerb deleted file mode 100644 index 414739665..000000000 --- a/app/views/notifier/mentioned.markerb +++ /dev/null @@ -1,9 +0,0 @@ -<% if @notification.post.public? %> -<%= post_message(@notification.post, :process_newlines => true) %> -<% else %> -<%= t('notifier.mentioned.limited_post') %> -<% end %> - -[<%= t("notifier.comment_on_post.reply", name: @notification.post_author_name) %>][1] - -[1]: <%= post_url(@notification.post) %> diff --git a/app/views/notifier/mentioned.text.erb b/app/views/notifier/mentioned.text.erb new file mode 100644 index 000000000..fbce0dbb4 --- /dev/null +++ b/app/views/notifier/mentioned.text.erb @@ -0,0 +1,8 @@ +<% if @notification.post.public? %> +<%= post_message(@notification.post) %> +<% else %> +<%= t("notifier.mentioned.limited_post") %> +<% end %> + +<%= t("notifier.comment_on_post.reply", name: @notification.post.author_first_name) %> +<%= post_url(@notification.post) %> diff --git a/app/views/notifier/mentioned_in_comment.html.haml b/app/views/notifier/mentioned_in_comment.html.haml new file mode 100644 index 000000000..89d04cb49 --- /dev/null +++ b/app/views/notifier/mentioned_in_comment.html.haml @@ -0,0 +1,9 @@ +- if @notification.comment.public? + = @notification.comment.message.markdownified_for_mail +- else + %p + = t("notifier.mentioned_in_comment.limited_post") + +%p + = link_to t("notifier.mentioned_in_comment.reply"), + post_url(@notification.comment.post, anchor: @notification.comment.guid) diff --git a/app/views/notifier/mentioned_in_comment.markerb b/app/views/notifier/mentioned_in_comment.text.erb index 3b86f409b..8f327a2a6 100644 --- a/app/views/notifier/mentioned_in_comment.markerb +++ b/app/views/notifier/mentioned_in_comment.text.erb @@ -4,6 +4,5 @@ <%= t("notifier.mentioned_in_comment.limited_post") %> <% end %> -[<%= t("notifier.mentioned_in_comment.reply") %>][1] - -[1]: <%= post_url(@notification.comment.parent, anchor: @notification.comment.guid) %> +<%= t("notifier.mentioned_in_comment.reply") %> +<%= post_url(@notification.comment.parent, anchor: @notification.comment.guid) %> diff --git a/app/views/notifier/plain_markdown_email.html.haml b/app/views/notifier/plain_markdown_email.html.haml new file mode 100644 index 000000000..a102d4ecb --- /dev/null +++ b/app/views/notifier/plain_markdown_email.html.haml @@ -0,0 +1,2 @@ +%div{style: "font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px"} + != Redcarpet::Markdown.new(Diaspora::Markdownify::Email).render(body) diff --git a/app/views/notifier/plain_markdown_email.text.haml b/app/views/notifier/plain_markdown_email.text.haml new file mode 100644 index 000000000..d2059e444 --- /dev/null +++ b/app/views/notifier/plain_markdown_email.text.haml @@ -0,0 +1 @@ +!= body diff --git a/app/views/notifier/private_message.html.haml b/app/views/notifier/private_message.html.haml new file mode 100644 index 000000000..bd4eb72f0 --- /dev/null +++ b/app/views/notifier/private_message.html.haml @@ -0,0 +1,4 @@ +%p + = t("notifier.a_private_message") +%p + = link_to t(".reply_to_or_view"), conversations_url(conversation_id: @notification.conversation) diff --git a/app/views/notifier/private_message.markerb b/app/views/notifier/private_message.markerb deleted file mode 100644 index e41a38cb4..000000000 --- a/app/views/notifier/private_message.markerb +++ /dev/null @@ -1,5 +0,0 @@ -<%= t('notifier.a_private_message') %> - -[<%= t('.reply_to_or_view') %>][1] - -[1]: <%= conversations_url(:conversation_id => @notification.conversation) %> diff --git a/app/views/notifier/private_message.text.erb b/app/views/notifier/private_message.text.erb new file mode 100644 index 000000000..6751ea454 --- /dev/null +++ b/app/views/notifier/private_message.text.erb @@ -0,0 +1,4 @@ +<%= t("notifier.a_private_message") %> + +<%= t(".reply_to_or_view") %> +<%= conversations_url(conversation_id: @notification.conversation) %> diff --git a/app/views/notifier/reshared.html.haml b/app/views/notifier/reshared.html.haml new file mode 100644 index 000000000..1450775e9 --- /dev/null +++ b/app/views/notifier/reshared.html.haml @@ -0,0 +1,5 @@ +%p + #{t('.reshared', name: @notification.sender_name)}: += post_message(@notification.reshare_root, html: true) +%p + = link_to t(".view_post"), post_url(@notification.reshare) diff --git a/app/views/notifier/reshared.markerb b/app/views/notifier/reshared.markerb deleted file mode 100644 index a1c43c6a1..000000000 --- a/app/views/notifier/reshared.markerb +++ /dev/null @@ -1,7 +0,0 @@ -<%= "#{t('.reshared', :name => "#{@notification.sender_name}")}:" %> - -<%= post_message(@notification.reshare_root, :process_newlines => true) %> - -[<%= t('.view_post') %>][1] - -[1]: <%= post_url(@notification.reshare) %> diff --git a/app/views/notifier/reshared.text.erb b/app/views/notifier/reshared.text.erb new file mode 100644 index 000000000..320b626b6 --- /dev/null +++ b/app/views/notifier/reshared.text.erb @@ -0,0 +1,6 @@ +<%= "#{t(".reshared", name: @notification.sender_name)}:" %> + +<%= post_message(@notification.reshare_root) %> + +<%= t(".view_post") %> +<%= post_url(@notification.reshare) %> diff --git a/app/views/notifier/single_admin.html.haml b/app/views/notifier/single_admin.html.haml new file mode 100644 index 000000000..304e2fb92 --- /dev/null +++ b/app/views/notifier/single_admin.html.haml @@ -0,0 +1,8 @@ +%p + = t("notifier.hello", name: @receiver.username) +%p + = @string +%p + = t("notifier.thanks") + %br/ + = t("notifier.single_admin.admin") diff --git a/app/views/notifier/single_admin.markerb b/app/views/notifier/single_admin.markerb deleted file mode 100644 index 0b9f23749..000000000 --- a/app/views/notifier/single_admin.markerb +++ /dev/null @@ -1,7 +0,0 @@ -<%= t('notifier.hello', :name => @receiver.username) %> - -<%= @string %> - -<%= t('notifier.thanks') %> - -<%= t('notifier.single_admin.admin') %> diff --git a/app/views/notifier/single_admin.text.erb b/app/views/notifier/single_admin.text.erb new file mode 100644 index 000000000..ed2c0a4e4 --- /dev/null +++ b/app/views/notifier/single_admin.text.erb @@ -0,0 +1,6 @@ +<%= t("notifier.hello", name: @receiver.username) %> + +<%= @string %> + +<%= t("notifier.thanks") %> +<%= t("notifier.single_admin.admin") %> diff --git a/app/views/notifier/started_sharing.html.haml b/app/views/notifier/started_sharing.html.haml new file mode 100644 index 000000000..bb5084ba7 --- /dev/null +++ b/app/views/notifier/started_sharing.html.haml @@ -0,0 +1,7 @@ +%p + = @notification.sender_name + = t(".sharing") + +%p + = link_to t(".view_profile", name: @notification.sender_first_name), + local_or_remote_person_path(@notification.sender, absolute: true) diff --git a/app/views/notifier/started_sharing.markerb b/app/views/notifier/started_sharing.markerb deleted file mode 100644 index d5e16d74c..000000000 --- a/app/views/notifier/started_sharing.markerb +++ /dev/null @@ -1,5 +0,0 @@ -<%= @notification.sender_name %> <%= t('.sharing') %> - -[<%= t('.view_profile', :name => @notification.sender_first_name) %>][1] - -[1]: <%= local_or_remote_person_path(@notification.sender, :absolute => true) %> diff --git a/app/views/notifier/started_sharing.text.erb b/app/views/notifier/started_sharing.text.erb new file mode 100644 index 000000000..6218f8d9e --- /dev/null +++ b/app/views/notifier/started_sharing.text.erb @@ -0,0 +1,4 @@ +<%= @notification.sender_name %> <%= t(".sharing") %> + +<%= t(".view_profile", name: @notification.sender_first_name) %> +<%= local_or_remote_person_path(@notification.sender, absolute: true) %> diff --git a/app/views/report/report_email.markerb b/app/views/report/report_email.markerb deleted file mode 100644 index 2729aa96b..000000000 --- a/app/views/report/report_email.markerb +++ /dev/null @@ -1,5 +0,0 @@ -<%= t("notifier.report_email.body", - url: resource[:url], - type: resource[:type], - id: resource[:id], - reason: resource[:reason]) %> diff --git a/app/views/users/_edit.haml b/app/views/users/_edit.haml index adeb9bddf..e20bcff44 100644 --- a/app/views/users/_edit.haml +++ b/app/views/users/_edit.haml @@ -34,7 +34,7 @@ .col-md-12 %h3= t(".change_password") = form_for @user, url: edit_user_path, html: {method: :put, class: "form-horizontal"} do |f| - - if (@user.errors.keys & %i(password password_confirmation current_password)).present? + - if (@user.errors.attribute_names & %i[password password_confirmation current_password]).present? = f.error_messages .form-group = f.label :current_password, t(".current_password"), class: "col-sm-6 control-label" diff --git a/app/views/users/export_email.markerb b/app/views/users/export_email.markerb deleted file mode 100644 index c345ae67a..000000000 --- a/app/views/users/export_email.markerb +++ /dev/null @@ -1 +0,0 @@ -<%= t('notifier.export_email.body', url: download_profile_user_url, name: @user.first_name) %> diff --git a/app/views/users/export_failure_email.markerb b/app/views/users/export_failure_email.markerb deleted file mode 100644 index 33da52efb..000000000 --- a/app/views/users/export_failure_email.markerb +++ /dev/null @@ -1 +0,0 @@ -<%= t('notifier.export_failure_email.body', name: @user.first_name) %> diff --git a/app/views/users/export_photos_email.markerb b/app/views/users/export_photos_email.markerb deleted file mode 100644 index 24bc4fd1d..000000000 --- a/app/views/users/export_photos_email.markerb +++ /dev/null @@ -1 +0,0 @@ -<%= t('notifier.export_photos_email.body', url: download_photos_user_url, name: @user.first_name) %> diff --git a/app/views/users/export_photos_failure_email.markerb b/app/views/users/export_photos_failure_email.markerb deleted file mode 100644 index 2067327c9..000000000 --- a/app/views/users/export_photos_failure_email.markerb +++ /dev/null @@ -1 +0,0 @@ -<%= t('notifier.export_photos_failure_email.body', name: @user.first_name) %> diff --git a/app/workers/deferred_dispatch.rb b/app/workers/deferred_dispatch.rb index 24d2eb108..c60ab11d1 100644 --- a/app/workers/deferred_dispatch.rb +++ b/app/workers/deferred_dispatch.rb @@ -11,9 +11,8 @@ module Workers def perform(user_id, object_class_name, object_id, opts) user = User.find(user_id) object = object_class_name.constantize.find(object_id) - opts = ActiveSupport::HashWithIndifferentAccess.new(opts) - Diaspora::Federation::Dispatcher.build(user, object, opts).dispatch + Diaspora::Federation::Dispatcher.build(user, object, opts.deep_symbolize_keys).dispatch rescue ActiveRecord::RecordNotFound # The target got deleted before the job was run end end diff --git a/app/workers/deferred_retraction.rb b/app/workers/deferred_retraction.rb index d8a3220fd..1593d49e0 100644 --- a/app/workers/deferred_retraction.rb +++ b/app/workers/deferred_retraction.rb @@ -12,9 +12,8 @@ module Workers user = User.find(user_id) subscribers = Person.where(id: recipient_ids) object = retraction_class.constantize.new(retraction_data.deep_symbolize_keys, subscribers) - opts = ActiveSupport::HashWithIndifferentAccess.new(opts) - Diaspora::Federation::Dispatcher.build(user, object, opts).dispatch + Diaspora::Federation::Dispatcher.build(user, object, opts.deep_symbolize_keys).dispatch end end end diff --git a/app/workers/delete_post_from_service.rb b/app/workers/delete_post_from_service.rb index c97a7c077..6eae7c43b 100644 --- a/app/workers/delete_post_from_service.rb +++ b/app/workers/delete_post_from_service.rb @@ -10,8 +10,7 @@ module Workers def perform(service_id, opts) service = Service.find_by_id(service_id) - opts = ActiveSupport::HashWithIndifferentAccess.new(opts) - service.delete_from_service(opts) + service.delete_from_service(opts.deep_symbolize_keys) end end end diff --git a/app/workers/export_photos.rb b/app/workers/export_photos.rb index 2fe4c007f..cf62cd144 100644 --- a/app/workers/export_photos.rb +++ b/app/workers/export_photos.rb @@ -4,7 +4,6 @@ # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. - module Workers class ExportPhotos < Base sidekiq_options queue: :low @@ -14,9 +13,9 @@ module Workers @user.perform_export_photos! if @user.reload.exported_photos_file.present? - ExportMailer.export_photos_complete_for(@user) + ExportMailer.export_photos_complete_for(@user).deliver_now else - ExportMailer.export_photos_failure_for(@user) + ExportMailer.export_photos_failure_for(@user).deliver_now end end end diff --git a/app/workers/mail/notifier_base.rb b/app/workers/mail/notifier_base.rb index 8e9924a0f..d0a703280 100644 --- a/app/workers/mail/notifier_base.rb +++ b/app/workers/mail/notifier_base.rb @@ -6,7 +6,7 @@ module Workers sidekiq_options queue: :low def perform(*args) - Notifier.send_notification(self.class.name.gsub("Workers::Mail::", "").underscore, *args).deliver_now + Notifier.send_notification(self.class.name.demodulize.underscore, *args).deliver_now end end end @@ -1,4 +1,4 @@ #!/usr/bin/env ruby APP_PATH = File.expand_path('../config/application', __dir__) -require_relative '../config/boot' -require 'rails/commands' +require_relative "../config/boot" +require "rails/commands" @@ -1,4 +1,4 @@ #!/usr/bin/env ruby -require_relative '../config/boot' -require 'rake' +require_relative "../config/boot" +require "rake" Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 000000000..57923026c --- /dev/null +++ b/bin/setup @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby +require "fileutils" + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:prepare' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end @@ -6,7 +6,7 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path("../config/environment", __FILE__) +require_relative "config/environment" # Kill unicorn workers really aggressively (at 300mb) if defined?(Unicorn) @@ -18,4 +18,5 @@ if defined?(Unicorn) end use Rack::Deflater -run Diaspora::Application +run Rails.application +Rails.application.load_server diff --git a/config/application.rb b/config/application.rb index 50524a735..9b1c1050b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require_relative 'boot' +require_relative "boot" -require 'rails/all' +require "rails/all" require_relative "bundler_helper" @@ -10,63 +10,39 @@ require_relative "bundler_helper" # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups(BundlerHelper.database)) -# Do not dump the limit of boolean fields on MySQL, -# since that generates a db/schema.rb that's incompatible -# with PostgreSQL -require 'active_record/connection_adapters/abstract_mysql_adapter' -module ActiveRecord - module ConnectionAdapters - class Mysql2Adapter < AbstractMysqlAdapter - def prepare_column_options(column, *_) - super.tap {|spec| - spec.delete(:limit) if column.type == :boolean - } - end - end - end -end - # Load asset_sync early require_relative 'asset_sync' module Diaspora class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.1 + config.load_defaults 6.1 + + # Use classic autoloader for now + config.autoloader = :classic - # Settings in config/environments/* take precedence over those specified here. - # Application configuration should go into files in config/initializers - # -- all .rb files in that directory are automatically loaded. + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.time_zone = "Central Time (US & Canada)" + # config.eager_load_paths << Rails.root.join("extras") # Custom directories with classes and modules you want to be autoloadable. config.autoload_paths += %W[#{config.root}/app] config.autoload_once_paths += %W[#{config.root}/lib] - # Only load the plugins named here, in the order given (default is alphabetical). - # :all can be used as a placeholder for all plugins not explicitly named. - # config.plugins = [ :exception_notification, :ssl_requirement, :all ] - - # Activate observers that should always be running. - # config.active_record.observers = :cacher, :garbage_collector, :forum_observer - - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. - # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. - # config.time_zone = 'Central Time (US & Canada)' - - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - # config.i18n.default_locale = :de - - # Configure the default encoding used in templates for Ruby 1.9. - config.encoding = "utf-8" + # Allow to decode Time from serialized columns + config.active_record.yaml_column_permitted_classes = [Time] # Enable escaping HTML in JSON. config.active_support.escape_html_entities_in_json = true - # Use SQL instead of Active Record's schema dumper when creating the database. - # This is necessary if your schema can't be completely dumped by the schema dumper, - # like if you have constraints or database-specific column types - # config.active_record.schema_format = :sql + # We specify CSRF protection manually in ApplicationController with + # protect_from_forgery - having it enabled anywhere by default breaks + # federation. + config.action_controller.default_protect_from_forgery = false # Enable the asset pipeline config.assets.enabled = true @@ -74,16 +50,8 @@ module Diaspora # Speed up precompile by not loading the environment config.assets.initialize_on_precompile = false - # Precompile additional assets. - # (application.js, application.css, and all non-JS/CSS in the app/assets are already added) - config.assets.precompile = %w[ - color_themes/*/desktop.css - color_themes/*/mobile.css - manifest.js - ] - # See lib/tasks/assets.rake: non_digest_assets - config.assets.non_digest_assets = %w(branding/logos/asterisk.png) + config.assets.non_digest_assets = %w[branding/logos/asterisk.png] # Configure generators values. Many other options are available, be sure to check the documentation. config.generators do |g| @@ -98,8 +66,6 @@ module Diaspora } config.action_mailer.asset_host = AppConfig.pod_uri.to_s - config.action_view.raise_on_missing_translations = true - config.middleware.use Rack::OAuth2::Server::Resource::Bearer, "OpenID Connect" do |req| Api::OpenidConnect::OAuthAccessToken .valid(Time.zone.now.utc).find_by(token: req.access_token) || req.invalid_token! diff --git a/config/boot.rb b/config/boot.rb index dcd2d28d5..4fe16d4e8 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require "bundler/setup" # Set up gems listed in the Gemfile. diff --git a/config/defaults.yml b/config/defaults.yml index ecd38c6a8..e8d959dfb 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -4,7 +4,7 @@ defaults: version: - number: "0.7.17.0" # Do not touch unless doing a release, do not backport the version number that's in master + number: "0.7.18.0" # Do not touch unless doing a release, do not backport the version number that's in master heroku: false environment: url: "http://localhost:3000/" diff --git a/config/environment.rb b/config/environment.rb index d5abe5580..7df99e89c 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Load the Rails application. -require_relative 'application' +require_relative "application" # Initialize the Rails application. Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb index ea9b17981..4342f872a 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,10 +1,12 @@ # frozen_string_literal: true +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false @@ -15,12 +17,14 @@ Rails.application.configure do config.consider_all_requests_local = true # Enable/disable caching. By default caching is disabled. - if Rails.root.join("tmp", "caching-dev.txt").exist? + # Run rails dev:cache to toggle caching. + if Rails.root.join('tmp/caching-dev.txt').exist? config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{2.days.seconds.to_i}" + 'Cache-Control' => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false @@ -28,6 +32,9 @@ Rails.application.configure do config.cache_store = :null_store end + # Store uploaded files on the local file system (see config/storage.yml for options). + # config.active_storage.service = :local + # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false @@ -36,9 +43,18 @@ Rails.application.configure do # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + # Debug mode disables concatenation and preprocessing of assets. # This option may cause significant delays in view rendering with a large # number of complex assets. @@ -53,13 +69,22 @@ Rails.application.configure do # Show the logging configuration on STDOUT config.show_log_configuration = true - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true + # Raises error for missing translations. + config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. config.file_watcher = ActiveSupport::EventedFileUpdateChecker + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + # Allow the host configured in the diaspora.toml to access the development server + config.hosts << AppConfig.pod_uri.host + # Speed up asset serving config.middleware.insert 0, TurboDevAssets end diff --git a/config/environments/production.rb b/config/environments/production.rb index 13a91a017..ff5ec75b7 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -13,18 +15,22 @@ Rails.application.configure do config.eager_load = true config.eager_load_paths += %W[#{config.root}/lib] + # diaspora* does not use ActiveStroage. But eager loading then loads active_storage/blob.rb, + # which then fails if there isn't a config/storage.yml + # This can be removed if we ever want to use ActiveStorage and a storage.yml exists + config.eager_load_namespaces.delete(ActiveStorage::Engine) + # Full error reports are disabled and caching is turned on. config.consider_all_requests_local = false config.action_controller.perform_caching = true - # Attempt to read encrypted secrets from `config/secrets.yml.enc`. - # Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or - # `config/secrets.yml.key`. - config.read_encrypted_secrets = true + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. - config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? # Compress JavaScripts and CSS. config.assets.js_compressor = :terser @@ -33,19 +39,19 @@ Rails.application.configure do # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false - # Generate digests for assets URLs. - config.assets.digest = true - # Enable serving of images, stylesheets, and JavaScripts from an asset server. if AppConfig.environment.assets.host.present? - config.action_controller.asset_host = AppConfig.environment.assets.host.get + config.asset_host = AppConfig.environment.assets.host.get end # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX - # Mount Action Cable outside main process or domain + # Store uploaded files on the local file system (see config/storage.yml for options). + # config.active_storage.service = :local + + # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil # config.action_cable.url = 'wss://example.com/cable' # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] @@ -53,7 +59,8 @@ Rails.application.configure do # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Log level + # Include generic and useful information about system operation, but avoid logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). config.log_level = :info # Prepend all log lines with the following tags. @@ -68,20 +75,34 @@ Rails.application.configure do # Use a different cache store in production. # config.cache_store = :mem_cache_store + # Use a real queuing backend for Active Job (and separate queues per environment). + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "diaspora_production" + config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify + # Log disallowed deprecations. + config.active_support.disallowed_deprecation = :log + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Use default logging formatter so that PID and timestamp are not suppressed. # config.log_formatter = ::Logger::Formatter.new # Use a different logger for distributed setups. - # require 'syslog/logger' + # require "syslog/logger" # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') # if ENV["RAILS_LOG_TO_STDOUT"].present? @@ -92,4 +113,25 @@ Rails.application.configure do # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Inserts middleware to perform automatic connection switching. + # The `database_selector` hash is used to pass options to the DatabaseSelector + # middleware. The `delay` is used to determine how long to wait after a write + # to send a subsequent read to the primary. + # + # The `database_resolver` class is used by the middleware to determine which + # database is appropriate to use based on the time delay. + # + # The `database_resolver_context` class is used by the middleware to set + # timestamps for the last write to the primary. The resolver uses the context + # class timestamps to determine how long to wait before reading from the + # replica. + # + # By default Rails will store a last write timestamp in the session. The + # DatabaseSelector middleware is designed as such you can define your own + # strategy for connection switching and pass that into the middleware through + # these configuration options. + # config.active_record.database_selector = { delay: 2.seconds } + # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver + # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session end diff --git a/config/environments/test.rb b/config/environments/test.rb index 26db9c226..d629f1e6c 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,12 +1,15 @@ # frozen_string_literal: true +require "active_support/core_ext/integer/time" + +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Do not eager load code on boot. This avoids loading your whole application @@ -17,7 +20,7 @@ Rails.application.configure do # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{1.hour.seconds.to_i}" + 'Cache-Control' => "public, max-age=#{1.hour.to_i}" } # Suppress logger output for asset requests. @@ -27,7 +30,6 @@ Rails.application.configure do config.assets.precompile += %w[poltergeist_disable_transition.css] # Don't precompile all themes for tests - config.assets.precompile -= %w[color_themes/*/desktop.css color_themes/*/mobile.css] config.assets.precompile += %w[ color_themes/original/desktop.css color_themes/dark_green/desktop.css @@ -39,12 +41,17 @@ Rails.application.configure do # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false + config.cache_store = :null_store # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + # config.active_storage.service = :test + config.action_mailer.perform_caching = false # Tell Action Mailer not to deliver emails to the real world. @@ -55,11 +62,20 @@ Rails.application.configure do # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Set the logging destination(s) config.log_to = %w[file] - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true + # Raises error for missing translations. + config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true # for fixture_builder ENV["FIXTURES_PATH"] = "spec/fixtures" diff --git a/config/initializers/acts_as_taggable_on.rb b/config/initializers/acts_as_taggable_on.rb index de8bfc5aa..743fdfa63 100644 --- a/config/initializers/acts_as_taggable_on.rb +++ b/config/initializers/acts_as_taggable_on.rb @@ -1,4 +1,26 @@ # frozen_string_literal: true -require 'models/acts_as_taggable_on-tag' +module ActsAsTaggableOn + class Tag + self.include_root_in_json = false + + def self.tag_text_regexp + @tag_text_regexp ||= "[[:word:]]\u055b\u055c\u055e\u058a_-" + end + + def self.autocomplete(name) + where("name LIKE ?", "#{name.downcase}%").order("name ASC") + end + + def self.normalize(name) + if name =~ /^#?<3/ + # Special case for love, because the world needs more love. + "<3" + elsif name + name.gsub(/[^#{tag_text_regexp}]/, "").downcase + end + end + end +end + ActsAsTaggableOn.force_lowercase = true diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb index 315ac48a9..f4556db39 100644 --- a/config/initializers/application_controller_renderer.rb +++ b/config/initializers/application_controller_renderer.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true # Be sure to restart your server when you modify this file. -# ApplicationController.renderer.defaults.merge!( -# http_host: 'example.org', -# https: false -# ) +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 0874787e3..5cae6d59f 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -25,4 +25,15 @@ Rails.application.config.assets.version = "1.0" # Add Yarn node_modules folder to the asset load path. # Rails.application.config.assets.paths << Rails.root.join("node_modules") +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w( admin.js admin.css ) + Rails.application.config.public_file_server.enabled = AppConfig.environment.assets.serve? + +# assets:precompile can sometimes fail with a Segmentation fault. +# Disabling export_concurrent is a workaround. See: https://github.com/sass/sassc-ruby/issues/207 +Rails.application.config.assets.configure do |env| + env.export_concurrent = false +end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index d0f0d3b5d..9290b5041 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -2,7 +2,8 @@ # Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } +# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code +# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". +Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] diff --git a/config/initializers/color_themes.rb b/config/initializers/color_themes.rb index 7cabdba64..8231c73ac 100644 --- a/config/initializers/color_themes.rb +++ b/config/initializers/color_themes.rb @@ -17,3 +17,10 @@ if color_themes_file.exist? else AVAILABLE_COLOR_THEMES = ["original"].freeze end + +unless Rails.env.test? + AVAILABLE_COLOR_THEMES.each do |theme_code| + Rails.application.config.assets.precompile += + %W[color_themes/#{theme_code}/desktop.css color_themes/#{theme_code}/mobile.css] + end +end diff --git a/config/initializers/entypo.rb b/config/initializers/entypo.rb deleted file mode 100644 index 1a0fa5221..000000000 --- a/config/initializers/entypo.rb +++ /dev/null @@ -1,3 +0,0 @@ -# frozen_string_literal: true - -Entypo.css_prefix = "entypo" diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 791647716..94e395494 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -3,5 +3,6 @@ # Be sure to restart your server when you modify this file. # Configure sensitive parameters which will be filtered from the log file. -Rails.application.config.filter_parameters += %i[password message text bio] -Rails.application.config.filter_parameters += [:otp_attempt] +Rails.application.config.filter_parameters += %i[ + password passw secret token _key crypt salt certificate otp otp_attempt ssn message text bio +] diff --git a/config/initializers/markerb.rb b/config/initializers/markerb.rb deleted file mode 100644 index a39d0cbee..000000000 --- a/config/initializers/markerb.rb +++ /dev/null @@ -1,3 +0,0 @@ -# frozen_string_literal: true - -Rails.application.config.markerb.renderer = Diaspora::Markdownify::Email diff --git a/config/initializers/sidekiq_scheduled.rb b/config/initializers/sidekiq_scheduled.rb index 46fc92adb..7385651ee 100644 --- a/config/initializers/sidekiq_scheduled.rb +++ b/config/initializers/sidekiq_scheduled.rb @@ -79,5 +79,7 @@ if Sidekiq.server? schedule_file_path = Rails.root.join("config", "schedule.yml") regenerate_config(schedule_file_path) unless valid_config?(schedule_file_path) - Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file_path) + Rails.application.reloader.to_prepare do + Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file_path) + end end diff --git a/config/locales/diaspora/bn.yml b/config/locales/diaspora/bn.yml new file mode 100644 index 000000000..1d6c898d3 --- /dev/null +++ b/config/locales/diaspora/bn.yml @@ -0,0 +1,61 @@ +# Copyright (c) 2010-2013, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + + + +bn: + _applications: "প্রয়োগসমূহ" + _contacts: "যোগাযোগ" + _services: "পরিষেবাসমূহ" + account: "বিবরণী" + activerecord: + errors: + models: + contact: + attributes: + person_id: + taken: "ভোক্তার যোগাযোগের সবার থেকে আলাদা হতে হবে" + person: + attributes: + diaspora_handle: + taken: "নেওয়া হয়ে গেছে" + reshare: + attributes: + root_guid: + taken: "বেশ ভাল। আপনি ইতিমধ্যে ডাকটি পুনঃভাগ করেছেন!" + user: + attributes: + email: + taken: "নেওয়া হয়ে গেছে" + person: + invalid: "অকার্যকর" + username: + invalid: "অকার্যকর। শুধু অক্ষর, সংখ্যা ও আন্ডারস্কোর গ্রহণযোগ্য" + taken: "নেওয়া হয়ে গেছে" + all_aspects: "সব দিক" + are_you_sure: "আপনি কি নিশ্চিত?" + are_you_sure_delete_account: "আপনি কি আপনার বিবরণী বন্ধ করতে চান? এটা কিন্তু অপরিবর্তনীয়" + aspects: + edit: + confirm_remove_aspect: "আপনি নিশ্চিত এটি মুছে ফেলতে চান?" + rename: "নবনামাঙ্কণ" + cancel: "বাতিল" + delete: "বাদ" + email: "বৈ-ডাক" + error_messages: + helper: + correct_the_following_errors_and_try_again: "ভুলগুলি ঠিক করে আবার চেষ্টা করুন।" + fill_me_out: "ভর্তি করে দিন" + find_people: "লোক বা #tag খুঁজুন" + limited: "সীমিত" + more: "আরও" + no_results: "এমন কিছু খুঁজে পাওয়া যায়নি" + nsfw: "কাজের জন্য সুরক্ষিত নয়" + ok: "বেশ" + privacy: "একান্ততা" + profile: "পরিলেখ" + public: "সর্বজনীন" + search: "সন্ধান" + settings: "সেটিংস" + username: "ভোক্তার নাম"
\ No newline at end of file diff --git a/config/locales/diaspora/de.yml b/config/locales/diaspora/de.yml index 3af6011a1..a47a05d6c 100644 --- a/config/locales/diaspora/de.yml +++ b/config/locales/diaspora/de.yml @@ -833,7 +833,7 @@ de: contacts_birthday: birthday: "%{name} hat heute Geburtstag. Wünsche doch 'Happy Birthday'!" subject: "%{name} hat heute Geburtstag" - view_profile: "Profil von %{name} anzeigen" + view_profile: "Profil von %{name} anzeigen >" csrf_token_fail: body: |- Hallo %{name}, @@ -872,8 +872,8 @@ de: body: |- Hallo %{name}, - Es trat ein Fehler beim Verarbeiten deiner Daten auf. - Bitte versuche es noch einmal! + Es trat ein Fehler beim Verarbeiten deiner Daten zum Herunterladen auf. + Falls das Problem weiter besteht, kontaktiere bitte deinen Podmin, um Hilfe zu erhalten. Entschuldige bitte, @@ -894,7 +894,7 @@ de: Hallo %{name}, Beim Verarbeiten deiner Fotos zum Herunterladen ist ein Problem aufgetreten. - Bitte versuche es noch einmal! + Falls das Problem weiter besteht, kontaktiere bitte deinen Podmin, um Hilfe zu erhalten. Entschuldigung, @@ -983,7 +983,7 @@ de: started_sharing: sharing: "hat angefangen mit dir zu teilen!" subject: "%{name} hat angefangen auf diaspora* mit dir zu teilen" - view_profile: "Schau dir %{name}s Profil an" + view_profile: "Schau dir %{name}s Profil an >" thanks: "Danke," to_change_your_notification_settings: "um deine Benachrichtigungs-Einstellungen zu ändern" nsfw: "NSFW (unpassend für den Arbeitsplatz)" diff --git a/config/locales/diaspora/de_formal.yml b/config/locales/diaspora/de_formal.yml index 42082be80..f7f8ed36f 100644 --- a/config/locales/diaspora/de_formal.yml +++ b/config/locales/diaspora/de_formal.yml @@ -830,7 +830,7 @@ de_formal: contacts_birthday: birthday: "%{name} hat heute Geburtstag. Wünschen Sie 'Herzlichen Glückwunsch'!" subject: "%{name} hat heute Geburtstag" - view_profile: "Profil von %{name} anzeigen" + view_profile: "Profil von %{name} anzeigen >" csrf_token_fail: body: |- Hallo %{name}, @@ -868,8 +868,8 @@ de_formal: body: |- Hallo %{name}, - Es trat ein Fehler beim Verarbeiten Ihrer Daten auf. - Bitte versuchen Sie es erneut. + Es trat ein Fehler beim Verarbeiten Ihrer Daten zum Herunterladen auf. + Falls das Problem weiter besteht, kontaktieren Sie bitte Ihren Podmin, um Hilfe zu erhalten. Entschuldigung, @@ -890,7 +890,7 @@ de_formal: Hallo %{name} Bei der Verarbeitung Ihrer Fotos zum Herunterladen ist ein Problem aufgetreten. - Bitte versuchen Sie es noch einmal! + Falls das Problem weiter besteht, kontaktieren Sie bitte Ihren Podmin, um Hilfe zu erhalten. Entschuldigung, @@ -978,7 +978,7 @@ de_formal: started_sharing: sharing: "hat angefangen mit Ihnen zu teilen!" subject: "%{name} hat angefangen mit Ihnen auf diaspora* zu teilen" - view_profile: "Schauen Sie sich %{name}s Profil an" + view_profile: "Schauen Sie sich %{name}s Profil an >" thanks: "Danke," to_change_your_notification_settings: "um Ihre Benachrichtigungs-Einstellungen zu ändern" nsfw: "NSFW (unpassend für den Arbeitsplatz)" diff --git a/config/locales/diaspora/de_moo.yml b/config/locales/diaspora/de_moo.yml index 97883154e..8813c9979 100644 --- a/config/locales/diaspora/de_moo.yml +++ b/config/locales/diaspora/de_moo.yml @@ -850,7 +850,7 @@ de_moo: contacts_birthday: birthday: "%{name} hat heute Geburtstag. Wünsche doch 'Happy Birthday'!" subject: "%{name} hat heute Geburtstag" - view_profile: "Profil von %{name} anzeigen" + view_profile: "Profil von %{name} anzeigen >" csrf_token_fail: body: |- Hallo %{name}, @@ -889,8 +889,8 @@ de_moo: body: |- Hallo %{name}, - Es trat ein Fehler beim Verarbeiten deiner Daten auf. - Bitte versuche es noch einmal! + Es trat ein Fehler beim Verarbeiten deiner Daten zum Herunterladen auf. + Falls das Problem weiter besteht, kontaktiere bitte deine Leitkuh, um Hilfe zu erhalten. Entschuldige bitte, @@ -911,7 +911,7 @@ de_moo: Hallo %{name}, Beim Verarbeiten deiner Fotos zum Herunterladen ist ein Problem aufgetreten. - Bitte versuche es noch einmal! + Falls das Problem weiter besteht, kontaktiere bitte deine Leitkuh, um Hilfe zu erhalten. Entschuldigung, @@ -1000,7 +1000,7 @@ de_moo: started_sharing: sharing: "hat angefangen mit dir zu teilen!" subject: "%{name} hat angefangen mit dir auf diaspora* zu teilen" - view_profile: "Schau dir %{name}s Profil an" + view_profile: "Schau dir %{name}s Profil an >" thanks: "Danke," to_change_your_notification_settings: "um deine Benachrichtigungs-Einstellungen zu ändern" nsfw: "NSFW (unpassend für den Arbeitsplatz)" diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index c9ffd03b3..9d36edbf3 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -724,7 +724,7 @@ en: started_sharing: subject: "%{name} started sharing with you on diaspora*" sharing: "has started sharing with you!" - view_profile: "View %{name}’s profile" + view_profile: "View %{name}’s profile >" comment_on_post: limited_subject: "There's a new comment on one of your posts" reply: "Reply or view %{name}’s post >" @@ -749,7 +749,7 @@ en: contacts_birthday: subject: "%{name} has their birthday today" birthday: "%{name} has their birthday today. Wish them 'Happy Birthday'!" - view_profile: "View %{name}’s profile" + view_profile: "View %{name}’s profile >" confirm_email: subject: "Please activate your new email address %{unconfirmed_email}" click_link: "To activate your new email address %{unconfirmed_email}, please follow this link:" diff --git a/config/locales/diaspora/en_1337.yml b/config/locales/diaspora/en_1337.yml index ae7605555..b855f5a67 100644 --- a/config/locales/diaspora/en_1337.yml +++ b/config/locales/diaspora/en_1337.yml @@ -516,7 +516,13 @@ en_1337: status_messages: new: mentioning: "M3N710N1NG: %{person}" - too_long: "{\"few\"=>\"PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5\", \"many\"=>\"PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5\", \"one\"=>\"PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R\\\"\", \"other\"=>\"PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5\", \"two\"=>\"PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5\", \"zero\"=>\"PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5\"}" + too_long: + few: "PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5" + many: "PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5" + one: "PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R\"" + other: "PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5" + two: "PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5" + zero: "PL3453 M4K3 Y0UR 5P4M5 L355 7H3N %{count} CH4R4C73R5" streams: activity: title: "MY 4C71V17Y" diff --git a/config/locales/diaspora/en_pirate.yml b/config/locales/diaspora/en_pirate.yml index ac63d8060..1f5ac1a28 100644 --- a/config/locales/diaspora/en_pirate.yml +++ b/config/locales/diaspora/en_pirate.yml @@ -493,7 +493,13 @@ en_pirate: status_messages: new: mentioning: "Mentionin': %{person}" - too_long: "{\"few\"=>\"Ye scallywag, make yer status messages less than %{count} characters\", \"many\"=>\"Ye scallywag,make yer status messages less than %{count} characters\", \"one\"=>\"Ye scallywag, make yer status messages less than %{count} character\", \"other\"=>\"Ye scallywag, make yer status messages less than %{count} characters\", \"two\"=>\"Ye scallywag, make yer status messages less than %{count} characters\", \"zero\"=>\"Ye scallywag,make yer status messages less than %{count} characters\"}" + too_long: + few: "Ye scallywag, make yer status messages less than %{count} characters" + many: "Ye scallywag,make yer status messages less than %{count} characters" + one: "Ye scallywag, make yer status messages less than %{count} character" + other: "Ye scallywag, make yer status messages less than %{count} characters" + two: "Ye scallywag, make yer status messages less than %{count} characters" + zero: "Ye scallywag,make yer status messages less than %{count} characters" streams: activity: title: "Me activity" diff --git a/config/locales/diaspora/en_shaw.yml b/config/locales/diaspora/en_shaw.yml index 3088871c8..7d0b0a0d9 100644 --- a/config/locales/diaspora/en_shaw.yml +++ b/config/locales/diaspora/en_shaw.yml @@ -359,7 +359,13 @@ en_shaw: status_messages: new: mentioning: "𐑥𐑧𐑯𐑖𐑩𐑯𐑦𐑙: %{person}" - too_long: "{\"few\"=>\"𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟\", \"many\"=>\"𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟\", \"one\"=>\"𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼\", \"other\"=>\"𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟\", \"two\"=>\"please make your status messages less than %{count} characters\", \"zero\"=>\"𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟\"}" + too_long: + few: "𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟" + many: "𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟" + one: "𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼" + other: "𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟" + two: "please make your status messages less than %{count} characters" + zero: "𐑐𐑤𐑰𐑟 𐑥𐑱𐑒 𐑿𐑼 𐑕𐑑𐑨𐑑𐑩𐑕 𐑥𐑧𐑕𐑩𐑡𐑩𐑟 𐑤𐑧𐑕 𐑞𐑨𐑯 %{count} 𐑒𐑺𐑩𐑒𐑑𐑼𐑟" streams: aspects: title: "Your Aspects" diff --git a/config/locales/diaspora/es.yml b/config/locales/diaspora/es.yml index 182a22bdf..216b9cfe4 100644 --- a/config/locales/diaspora/es.yml +++ b/config/locales/diaspora/es.yml @@ -240,7 +240,7 @@ es: name: "Etiquetas (Escritura)" ? "tags:read" : - description: "Concede permiso de solo-lectura a las etiquetas que sigues y entradas de etiquetas." + description: "Concede permiso de solo lectura a las etiquetas que sigues y entradas de etiquetas." name: "Etiquetas (Solo lectura)" user_applications: index: diff --git a/config/locales/diaspora/ru.yml b/config/locales/diaspora/ru.yml index fdfa0959c..24bdbd555 100644 --- a/config/locales/diaspora/ru.yml +++ b/config/locales/diaspora/ru.yml @@ -1214,6 +1214,19 @@ ru: one: "%{count} человек с меткой %{tag}" other: "%{count} человек с меткой %{tag}" zero: "Нет ни одного человека с меткой %{tag}" + two_factor_auth: + activated: + change_button: "Отключить" + status: "Двухфакторная аутентификация установлена" + confirm: + activate_button: "Подтвердить и установить" + scan_title: "Сканировать QR код" + title: "Подтвердить установку" + deactivated: + change_button: "Включить" + change_label: "Установить двухфакторную аутентификацию" + status: "Двухфакторная аутентификация не установлена" + title: "Двухфакторная аутентификация" username: "Имя пользователя" users: confirm_email: diff --git a/config/locales/diaspora/vi.yml b/config/locales/diaspora/vi.yml index 85ce27fdd..00cd28c38 100644 --- a/config/locales/diaspora/vi.yml +++ b/config/locales/diaspora/vi.yml @@ -175,7 +175,7 @@ vi: description: "Yêu cầu truy cập danh bạ và những thông tin liên quan (như mối quan hệ) dưới hình thức chỉ-đọc." name: "Danh bạ (Chỉ-đọc)" conversations: - description: "Yêu cầu truy cập những tin nhắn riêng tư dưới hình thức đọc lẫn ghi đè." + description: "Yêu cầu truy cập những tin nhắn dưới hình thức đọc lẫn ghi đè." name: "Thảo luận" email: description: "Yêu cầu truy cập địa chỉ email của bạn dưới hình thức chỉ-đọc." @@ -385,7 +385,7 @@ vi: send: "Gửi" sending: "Đang gửi..." subject: "Tiêu đề" - subject_default: "Không tựa đề" + subject_default: "Không tiêu đề" to: "Người nhận" new_conversation: fail: "Tin nhắn không hợp lệ" @@ -463,14 +463,14 @@ vi: foundation_website: "Trang chủ Diaspora" getting_help: get_support_a_discourse: "Tìm những thảo luận có liên quan tới yêu cầu của bạn hoặc tạo một chủ đề mới trên nền tảng %{discourse} của chúng tôi" - get_support_a_faq: "\bĐọc trang %{faq} trên wiki" + get_support_a_faq: "Đọc trang %{faq} trên wiki" get_support_a_hashtag: "Đăng một bài đăng công khai sử dụng hashtag %{question}" get_support_a_irc: "Tham gia kênh chat %{irc}" get_support_a_tutorials: "Đọc kỹ %{tutorials}" get_support_a_website: "Tham khảo %{link}" get_support_a_wiki: "Tra cứu %{link}" get_support_q: "Nếu thắc mắc của tôi không có trong FAQ, tôi nên gửi yêu cầu hỗ trợ ở đâu?" - getting_started_a: "Bạn đọc kỹ nhé. \bTìm hiểu %{tutorial_series} trên trang chủ. Nó sẽ chỉ bạn từng bước quá trình đăng ký và dạy bạn cách sử dụng các tính năng cơ bản của Diaspora." + getting_started_a: "Bạn đọc kỹ nhé. Tìm hiểu %{tutorial_series} trên trang chủ. Nó sẽ chỉ bạn từng bước quá trình đăng ký và dạy bạn cách sử dụng các tính năng cơ bản của Diaspora." getting_started_q: "Giúp tôi với! Tôi cần hướng dẫn sử dụng cơ bản!" title: "Trợ giúp" getting_started_tutorial: "Hướng dẫn cho người mới" @@ -681,8 +681,8 @@ vi: layouts: application: back_to_top: "Trở về đầu trang" - be_excellent: "Tuyệt với với nhau! ♥" - discourse: "Thảo luận và hỗ trợ dự án" + be_excellent: "Cùng tạo điều tuyệt vời! ♥" + discourse: "Hỗ trợ và thảo luận" powered_by: "Powered by Diaspora" public_feed: "Nguồn tin Diaspora công khai cho %{name}" source_package: "Tải về mã nguồn" @@ -892,7 +892,7 @@ vi: reply: "Trả lời hoặc xem thảo luận >" private_message: reply_to_or_view: "Trả lời hoặc xem cuộc thảo luận này >" - subject: "Bạn có một tin nhắn riêng tư mới" + subject: "Bạn có một tin nhắn mới" remove_old_user: body: |- Xin chào, @@ -1120,7 +1120,7 @@ vi: visibility_dropdown: "Dùng menu thả xuống này để thay đổi kiểu bài đăng của bạn. (Chúng tôi đề xuất bài đăng đầu tiên nên để công khai)" publisher: discard_post: "Hủy đăng bài" - formatWithMarkdown: "Bạn có thể sử dụng %{markdown_link} để định dạng bài đăng" + formatWithMarkdown: "Bạn có thể dùng %{markdown_link} để định dạng bài đăng" get_location: "Lấy thông tin vị trí" new_user_prefill: hello: "Chào mọi người, tôi là #%{new_user_tag}. " diff --git a/config/locales/javascript/javascript.vi.yml b/config/locales/javascript/javascript.vi.yml index a70b9df41..4e1396cd5 100644 --- a/config/locales/javascript/javascript.vi.yml +++ b/config/locales/javascript/javascript.vi.yml @@ -253,7 +253,7 @@ vi: more_comments: other: "Hiện thêm <%= count %> bình luận" zero: "Hiện thêm <%= count %> bình luận" - no_posts_yet: "Chưa có bài đăng nào hiển thị ở đây." + no_posts_yet: "Chưa có bài đăng công khai nào." original_post_deleted: "Bài đăng gốc đã bị xoá" permalink: "Liên kết cố định" public: "Công khai" @@ -289,7 +289,7 @@ vi: month: "nửa tháng trước" months: other: "%d tháng" - prefixAgo: "trước" + prefixAgo: "" prefixFromNow: "kể từ lúc này" seconds: "vừa xong" suffixAgo: "trước" diff --git a/config/logging.rb b/config/logging.rb index 06d57f041..38faf0f5c 100644 --- a/config/logging.rb +++ b/config/logging.rb @@ -112,4 +112,4 @@ end # the logging gem is no-op. See: https://github.com/TwP/logging/issues/11 Logging::Logger.send :alias_method, :local_level, :level Logging::Logger.send :alias_method, :local_level=, :level= -Logging::Logger.send :include, LoggerSilence +Logging::Logger.include ActiveSupport::LoggerSilence diff --git a/config/routes.rb b/config/routes.rb index 88c1d5fde..5c0d4f19c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,7 +8,7 @@ require "sidekiq/web" require "sidekiq/cron/web" Rails.application.routes.draw do - # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html resources :report, except: %i(edit new show) diff --git a/config/sidekiq.yml b/config/sidekiq.yml index a99dd69c9..4ad8c3920 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -1,4 +1,4 @@ -<% require_relative 'config/load_config' %> +<% require_relative 'load_config' %> --- :verbose: false <% unless AppConfig.heroku? %> diff --git a/db/migrate/20170813160104_cleanup_aspects_and_add_unique_index.rb b/db/migrate/20170813160104_cleanup_aspects_and_add_unique_index.rb index 1d8c7325a..7741d5b08 100644 --- a/db/migrate/20170813160104_cleanup_aspects_and_add_unique_index.rb +++ b/db/migrate/20170813160104_cleanup_aspects_and_add_unique_index.rb @@ -17,7 +17,7 @@ class CleanupAspectsAndAddUniqueIndex < ActiveRecord::Migration[5.1] Aspect.where(user_id: 0).delete_all Aspect.joins("INNER JOIN aspects as a2 ON aspects.user_id = a2.user_id AND aspects.name = a2.name") .where("aspects.id > a2.id").each do |aspect| - aspect.update_attributes(name: "#{aspect.name}_#{UUID.generate(:compact)}") + aspect.update(name: "#{aspect.name}_#{UUID.generate(:compact)}") end end end diff --git a/docker/develop/Dockerfile b/docker/develop/Dockerfile index a33f8a08c..e0b7067f3 100644 --- a/docker/develop/Dockerfile +++ b/docker/develop/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.6-slim-buster +FROM ruby:2.7-slim-buster RUN DEBIAN_FRONTEND=noninteractive \ apt-get update && \ diff --git a/features/desktop/change_settings.feature b/features/desktop/change_settings.feature index 4655b2a9d..02b199ccf 100644 --- a/features/desktop/change_settings.feature +++ b/features/desktop/change_settings.feature @@ -19,12 +19,12 @@ Feature: Change settings Scenario: Change my email preferences When I uncheck "user_email_preferences_mentioned" - And I scroll a bit + And I scroll to "change_email_preferences" And I press "change_email_preferences" Then I should see "Email notifications changed" And the "user_email_preferences_mentioned" checkbox should not be checked When I uncheck "user_email_preferences_mentioned_in_comment" - And I scroll a bit + And I scroll to "change_email_preferences" And I press "change_email_preferences" Then I should see "Email notifications changed" And the "user_email_preferences_mentioned_in_comment" checkbox should not be checked diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index ac5302e6f..465d3dd48 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -167,14 +167,6 @@ Then /^I should see (\d+) contacts$/ do |n_posts| has_css?("#people-stream .stream-element", count: n_posts.to_i).should be true end -When /^I scroll a bit$/ do - page.execute_script("window.scrollBy(0,200)") -end - -And /^I scroll down$/ do - page.execute_script("window.scrollBy(0,3000000)") -end - Then /^I should have scrolled down$/ do expect(page.evaluate_script("window.pageYOffset")).to be > 0 end diff --git a/features/step_definitions/notifications_steps.rb b/features/step_definitions/notifications_steps.rb index 9088dacc2..9c521a908 100644 --- a/features/step_definitions/notifications_steps.rb +++ b/features/step_definitions/notifications_steps.rb @@ -24,7 +24,7 @@ And "I wait for notifications to load" do end And "I scroll down on the notifications dropdown" do - page.execute_script("$('.notifications').scrollTop(350)") + find(".notifications").scroll_to(0, 350) end Then "the notification dropdown should be visible" do diff --git a/features/step_definitions/publisher_steps.rb b/features/step_definitions/publisher_steps.rb index 5afa5f5fe..56c7917a5 100644 --- a/features/step_definitions/publisher_steps.rb +++ b/features/step_definitions/publisher_steps.rb @@ -13,9 +13,11 @@ Then /^the publisher should be expanded$/ do end When /^I click to delete the first uploaded photo$/ do - page.execute_script("$('#photodropzone .x').css('display', 'block');") image_count = all(".publisher_photo img", wait: false).count - find("#photodropzone .x", match: :first).trigger "click" + within "ul#photodropzone" do + first("img").hover + find(".x", match: :first).trigger "click" + end page.assert_selector(".publisher_photo img", count: image_count - 1) end @@ -68,12 +70,6 @@ When /^I post an extremely long status message$/ do end When /^I select "([^"]*)" on the aspect dropdown$/ do |text| - page.execute_script( - "$('#publisher .dropdown .dropdown_list, #publisher .aspect-dropdown .dropdown-menu') - .find('li').each(function(i,el){ - var elem = $(el); - if ('" + text + "' == $.trim(elem.text()) ) { - elem.click(); - }});" - ) + find("button.dropdown-toggle").click + find(".dropdown-menu li", text: text).click end diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb index 804642cae..a843c1b12 100644 --- a/features/step_definitions/user_steps.rb +++ b/features/step_definitions/user_steps.rb @@ -18,13 +18,13 @@ end Given /^a user named "([^\"]*)" with email "([^\"]*)"$/ do |name, email| first, last = name.split - user = create_user(:email => email, :username => "#{first}_#{last}") - user.profile.update_attributes!(:first_name => first, :last_name => last) if first + user = create_user(email: email, username: "#{first}_#{last}") + user.profile.update!(first_name: first, last_name: last) if first end Given /^a nsfw user with email "([^\"]*)"$/ do |email| - user = create_user(:email => email) - user.profile.update_attributes(:nsfw => true) + user = create_user(email: email) + user.profile.update(nsfw: true) end Given /^a moderator with email "([^\"]*)"$/ do |email| diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 4067ad5f4..2c2ca4400 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -170,8 +170,8 @@ Then /^the "([^"]*)" bootstrap-switch should be (on|off)$/ do |label, state| end end -Then /^I toggle the "([^"]*)" bootstrap-switch$/ do |label| - page.execute_script("return $('#{label}').bootstrapSwitch('toggleState')") +Then /^I toggle the "#([^"]*)" bootstrap-switch$/ do |id| + find(".bootstrap-switch-id-#{id}").click end Then /^(?:|I )should be on (.+)$/ do |page_name| @@ -195,3 +195,8 @@ Then /^I wait until ajax requests finished$/ do loop until page.evaluate_script("jQuery.active") == 0 end end + +When /^I scroll to "([^"]*)"$/ do |element_id| + element = find_by_id(element_id) # rubocop:disable Rails/DynamicFindBy + page.scroll_to(element, align: :bottom) +end diff --git a/features/support/integration_sessions_controller.rb b/features/support/integration_sessions_controller.rb index 1d6bccbe8..357d1cc86 100644 --- a/features/support/integration_sessions_controller.rb +++ b/features/support/integration_sessions_controller.rb @@ -1,10 +1,13 @@ # frozen_string_literal: true class IntegrationSessionsController < ActionController::Base + prepend_view_path(Rails.root.join("features/support")) + def new @user_id = params[:user_id] - render file: 'features/support/integration_sessions_form', layout: false + render template: "integration_sessions_form", layout: false end + def create sign_in_and_redirect User.find(params[:user_id]) end diff --git a/features/support/publishing_cuke_helpers.rb b/features/support/publishing_cuke_helpers.rb index 57997ccc4..73dc02e27 100644 --- a/features/support/publishing_cuke_helpers.rb +++ b/features/support/publishing_cuke_helpers.rb @@ -27,9 +27,9 @@ module PublishingCukeHelpers end def upload_file_with_publisher(path) - page.execute_script(%q{$("input[name='qqfile']").css("opacity", '1');}) with_scope("#publisher-textarea-wrapper") do - attach_file("qqfile", Rails.root.join(path).to_s) + find('input[name="qqfile"]', visible: false) + .attach_file(Rails.root.join(path).to_s, make_visible: true) # wait for the image to be ready page.assert_selector(".publisher_photo.loading", count: 0) end diff --git a/lib/account_deleter.rb b/lib/account_deleter.rb index 302669bc4..d7f976c1a 100644 --- a/lib/account_deleter.rb +++ b/lib/account_deleter.rb @@ -97,6 +97,6 @@ class AccountDeleter end def mark_account_deletion_complete - AccountDeletion.find_by(person: person)&.update_attributes(completed_at: Time.now.utc) + AccountDeletion.find_by(person: person)&.update(completed_at: Time.now.utc) end end diff --git a/lib/bookmarklet_renderer.rb b/lib/bookmarklet_renderer.rb index a8e998a73..d15fb7261 100644 --- a/lib/bookmarklet_renderer.rb +++ b/lib/bookmarklet_renderer.rb @@ -16,7 +16,7 @@ class BookmarkletRenderer end def source - @source ||= Rails.application.assets["bookmarklet.js"].pathname.to_s + @source ||= Rails.application.assets["bookmarklet.js"].filename end def body diff --git a/lib/connection_tester.rb b/lib/connection_tester.rb index 5bc58d75b..d66f418f8 100644 --- a/lib/connection_tester.rb +++ b/lib/connection_tester.rb @@ -1,10 +1,8 @@ - # frozen_string_literal: true class ConnectionTester include Diaspora::Logging - NODEINFO_SCHEMA = "http://nodeinfo.diaspora.software/ns/schema/1.0" NODEINFO_FRAGMENT = "/.well-known/nodeinfo" class << self @@ -97,16 +95,13 @@ class ConnectionTester # * is the SSL certificate valid (only on HTTPS) # * does the server return a successful HTTP status code # * is there a reasonable amount of redirects (3 by default) - # * is there a /.well-known/host-meta (this is needed to work, this can be replaced with a mandatory NodeInfo later) # (can't do a HEAD request, since that's not a defined route in the app) # # @raise [NetFailure, SSLFailure, HTTPFailure] if any of the checks fail # @return [Integer] HTTP status code def request with_http_connection do |http| - capture_response_time { http.get("/") } - response = http.get("/.well-known/host-meta") - handle_http_response(response) + capture_response_time { handle_http_response(http.get("/")) } end rescue HTTPFailure => e raise e @@ -114,8 +109,8 @@ class ConnectionTester raise NetFailure, e.message rescue Faraday::SSLError => e raise SSLFailure, e.message - rescue ArgumentError, FaradayMiddleware::RedirectLimitReached, Faraday::ClientError => e - raise HTTPFailure, e.message + rescue ArgumentError, Faraday::ClientError, Faraday::ServerError => e + raise HTTPFailure, "#{e.class}: #{e.message}" rescue StandardError => e unexpected_error(e) end @@ -123,20 +118,25 @@ class ConnectionTester # Try to find out the version of the other servers software. # Assuming the server speaks nodeinfo # - # @raise [NodeInfoFailure] if the document can't be fetched - # or the attempt to parse it failed + # @raise [HTTPFailure] if the document can't be fetched + # @raise [NodeInfoFailure] if the document can't be parsed or is invalid def nodeinfo with_http_connection do |http| ni_resp = http.get(NODEINFO_FRAGMENT) - nd_resp = http.get(find_nodeinfo_url(ni_resp.body)) - find_software_version(nd_resp.body) + ni_urls = find_nodeinfo_urls(ni_resp.body) + raise NodeInfoFailure, "No supported NodeInfo version found" if ni_urls.empty? + + version, url = ni_urls.max + find_software_version(version, http.get(url).body) end rescue NodeInfoFailure => e raise e - rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError => e + rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError, Faraday::TimeoutError => e raise NodeInfoFailure, "#{e.class}: #{e.message}" - rescue Faraday::ResourceNotFound, JSON::JSONError => e + rescue JSON::JSONError => e raise NodeInfoFailure, e.message[0..255].encode(Encoding.default_external, undef: :replace) + rescue Faraday::ClientError => e + raise HTTPFailure, "#{e.class}: #{e.message}" rescue StandardError => e unexpected_error(e) end @@ -175,30 +175,30 @@ class ConnectionTester def handle_http_response(response) @result.status_code = Integer(response.status) - if response.success? - raise HTTPFailure, "redirected to other hostname: #{response.env.url}" unless @uri.host == response.env.url.host + raise HTTPFailure, "unsuccessful response code: #{response.status}" unless response.success? + raise HTTPFailure, "redirected to other hostname: #{response.env.url}" unless @uri.host == response.env.url.host - @result.reachable = true - @result.ssl = (response.env.url.scheme == "https") - else - raise HTTPFailure, "unsuccessful response code: #{response.status}" - end + @result.reachable = true + @result.ssl = (response.env.url.scheme == "https") end - # walk the JSON document, get the actual document location - def find_nodeinfo_url(body) + # walk the JSON document, get the actual document locations + def find_nodeinfo_urls(body) jrd = JSON.parse(body) links = jrd.fetch("links") raise NodeInfoFailure, "invalid JRD: '#/links' is not an array!" unless links.is_a?(Array) - links.find { |entry| - entry.fetch("rel") == NODEINFO_SCHEMA - }.fetch("href") + + supported_rel_map = NodeInfo::VERSIONS.index_by {|v| "http://nodeinfo.diaspora.software/ns/schema/#{v}" } + links.map {|entry| + version = supported_rel_map[entry.fetch("rel")] + [version, entry.fetch("href")] if version + }.compact.to_h end # walk the JSON document, find the version string - def find_software_version(body) + def find_software_version(version, body) info = JSON.parse(body) - JSON::Validator.validate!(NodeInfo.schema("1.0"), info) + JSON::Validator.validate!(NodeInfo.schema(version), info) sw = info.fetch("software") @result.software_version = "#{sw.fetch('name')} #{sw.fetch('version')}" end diff --git a/lib/diaspora/federated/retraction.rb b/lib/diaspora/federated/retraction.rb index b0ea20dbc..538ba7e9b 100644 --- a/lib/diaspora/federated/retraction.rb +++ b/lib/diaspora/federated/retraction.rb @@ -36,7 +36,8 @@ class Retraction def defer_dispatch(user, include_target_author=true) subscribers = dispatch_subscribers(include_target_author) - Workers::DeferredRetraction.perform_async(user.id, self.class.to_s, data, subscribers.map(&:id), service_opts(user)) + Workers::DeferredRetraction.perform_async(user.id, self.class.to_s, data.deep_stringify_keys, + subscribers.map(&:id), service_opts(user).deep_stringify_keys) end def perform diff --git a/lib/diaspora/federation/dispatcher.rb b/lib/diaspora/federation/dispatcher.rb index 4e03e725f..2ad441715 100644 --- a/lib/diaspora/federation/dispatcher.rb +++ b/lib/diaspora/federation/dispatcher.rb @@ -21,7 +21,7 @@ module Diaspora end def self.defer_dispatch(sender, object, opts={}) - Workers::DeferredDispatch.perform_async(sender.id, object.class.to_s, object.id, opts) + Workers::DeferredDispatch.perform_async(sender.id, object.class.to_s, object.id, opts.deep_stringify_keys) end def dispatch @@ -69,7 +69,7 @@ module Diaspora when StatusMessage each_service {|service| Workers::PostToService.perform_async(service.id, object.id, opts[:url]) } when Retraction - each_service {|service| Workers::DeletePostFromService.perform_async(service.id, opts) } + each_service {|service| Workers::DeletePostFromService.perform_async(service.id, opts.deep_stringify_keys) } end end diff --git a/lib/diaspora/federation/receive.rb b/lib/diaspora/federation/receive.rb index dd136ac42..adc3a9c82 100644 --- a/lib/diaspora/federation/receive.rb +++ b/lib/diaspora/federation/receive.rb @@ -116,7 +116,7 @@ module Diaspora if persisted_photo persisted_photo.tap do |photo| - photo.update_attributes( + photo.update( text: entity.text, public: entity.public, created_at: entity.created_at, @@ -145,7 +145,7 @@ module Diaspora def self.profile(entity) author_of(entity).profile.tap do |profile| - profile.update_attributes( + profile.update( first_name: entity.first_name, last_name: entity.last_name, image_url: entity.image_url, diff --git a/lib/diaspora/mentionable.rb b/lib/diaspora/mentionable.rb index 59f2da8f0..d009ce6a5 100644 --- a/lib/diaspora/mentionable.rb +++ b/lib/diaspora/mentionable.rb @@ -1,4 +1,3 @@ - # frozen_string_literal: true module Diaspora::Mentionable @@ -55,8 +54,9 @@ module Diaspora::Mentionable # # @param [String] message text # @param [Array] allowed_people ids of people that are allowed to stay + # @param [Boolean] absolute_links (false) render mentions with absolute links # @return [String] message text with filtered mentions - def self.filter_people(msg_text, allowed_people) + def self.filter_people(msg_text, allowed_people, absolute_links: false) mentioned_ppl = people_from_string(msg_text) msg_text.to_s.gsub(REGEX) {|match_str| @@ -66,7 +66,7 @@ module Diaspora::Mentionable if person && allowed_people.include?(person.id) match_str else - "@#{MentionsInternal.profile_link(person, name, diaspora_id)}" + "@#{MentionsInternal.profile_link(person, name, diaspora_id, absolute: absolute_links)}" end } end @@ -93,7 +93,7 @@ module Diaspora::Mentionable # inline module for namespacing module MentionsInternal - extend ::PeopleHelper + extend ERB::Util # output a formatted mention link as defined by the given arguments. # if the display name is blank, falls back to the person's name. @@ -105,10 +105,15 @@ module Diaspora::Mentionable def self.mention_link(person, display_name, diaspora_id, opts) return display_name || diaspora_id unless person.present? + display_name ||= person.name if opts[:plain_text] - display_name || person.name + display_name else - person_link(person, class: PERSON_HREF_CLASS, display_name: display_name) + # rubocop:disable Rails/OutputSafety + remote_or_hovercard_link = Rails.application.routes.url_helpers.person_path(person).html_safe + "<a data-hovercard=\"#{remote_or_hovercard_link}\" href=\"#{remote_or_hovercard_link}\" " \ + "class=\"#{PERSON_HREF_CLASS}\">#{html_escape_once(display_name)}</a>".html_safe + # rubocop:enable Rails/OutputSafety end end @@ -117,11 +122,14 @@ module Diaspora::Mentionable # # @param [Person] AR Person # @param [String] display name + # @param [String] diaspora_id + # @param [Boolean] absolute (false) render absolute link # @return [String] markdown person link - def self.profile_link(person, display_name, diaspora_id) + def self.profile_link(person, display_name, diaspora_id, absolute: false) return display_name || diaspora_id unless person.present? - "[#{display_name || person.name}](#{local_or_remote_person_path(person)})" + url_helper = Rails.application.routes.url_helpers + "[#{display_name || person.name}](#{absolute ? url_helper.person_url(person) : url_helper.person_path(person)})" end end end diff --git a/lib/diaspora/message_renderer.rb b/lib/diaspora/message_renderer.rb index d3f0e0232..2f9ef423f 100644 --- a/lib/diaspora/message_renderer.rb +++ b/lib/diaspora/message_renderer.rb @@ -56,8 +56,8 @@ module Diaspora @message = renderer.render(message).strip end - def markdownify - renderer = Diaspora::Markdownify::HTML.new options[:markdown_render_options] + def markdownify(renderer_class=Diaspora::Markdownify::HTML) + renderer = renderer_class.new options[:markdown_render_options] markdown = Redcarpet::Markdown.new renderer, options[:markdown_options] @message = markdown.render message @@ -76,8 +76,8 @@ module Diaspora @message = Diaspora::Mentionable.format message, options[:mentioned_people] end - if options[:disable_hovercards] || options[:link_all_mentions] - @message = Diaspora::Mentionable.filter_people message, [] + if options[:disable_hovercards] + @message = Diaspora::Mentionable.filter_people(message, [], absolute_links: true) else make_mentions_plain_text end @@ -108,7 +108,6 @@ module Diaspora end DEFAULTS = {mentioned_people: [], - link_all_mentions: false, disable_hovercards: false, truncate: false, append: nil, @@ -137,12 +136,8 @@ module Diaspora # @param [Hash] opts Global options affecting output # @option opts [Array<Person>] :mentioned_people ([]) List of people # allowed to mention - # @option opts [Boolean] :link_all_mentions (false) Whether to link - # all mentions. This makes plain links to profiles for people not in - # :mentioned_people # @option opts [Boolean] :disable_hovercards (true) Render all mentions - # as profile links. This implies :link_all_mentions and ignores - # :mentioned_people + # as absolute profile links. This ignores :mentioned_people # @option opts [#to_i, Boolean] :truncate (false) Truncate message to # the specified length # @option opts [String] :append (nil) Append text to the end of @@ -205,7 +200,7 @@ module Diaspora render_tags squish append_and_truncate - }.html_safe + }.html_safe # rubocop:disable Rails/OutputSafety end # @param [Hash] opts Override global output options, see {#initialize} @@ -220,7 +215,20 @@ module Diaspora render_tags squish append_and_truncate - }.html_safe + }.html_safe # rubocop:disable Rails/OutputSafety + end + + def markdownified_for_mail + process(disable_hovercards: true) { + process_newlines + normalize + diaspora_links + camo_urls if AppConfig.privacy.camo.proxy_markdown_images? + render_mentions + markdownify(Diaspora::Markdownify::Email) + squish + append_and_truncate + }.html_safe # rubocop:disable Rails/OutputSafety end # Get a short summary of the message diff --git a/lib/diaspora/taggable.rb b/lib/diaspora/taggable.rb index ec9f9e6d8..6a75a1f38 100644 --- a/lib/diaspora/taggable.rb +++ b/lib/diaspora/taggable.rb @@ -15,8 +15,8 @@ module Diaspora # tag's name is limited to 255 charchters according to ActsAsTaggableOn gem, so we check the length of the name for each tag def tag_name_max_length - self.tag_list.each do |tag| - errors[:tags] << I18n.t('tags.name_too_long', :count => 255, :current_length => tag.length) if tag.length > 255 + tag_list.each do |tag| + errors.add(:tags, I18n.t("tags.name_too_long", count: 255, current_length: tag.length)) if tag.length > 255 end end protected :tag_name_max_length diff --git a/lib/error_page_renderer.rb b/lib/error_page_renderer.rb index 65bd09dbc..4e968f9e0 100644 --- a/lib/error_page_renderer.rb +++ b/lib/error_page_renderer.rb @@ -6,44 +6,14 @@ class ErrorPageRenderer def initialize options={} @codes = options.fetch :codes, [404, 500] @output = options.fetch :output, "public/%s.html" - @vars = options.fetch :vars, {} @template = options.fetch :template, "errors/error_%s" @layout = options.fetch :layout, "layouts/error_page" end def render @codes.each do |code| - view = build_action_view - view.assign @vars.merge(code: code) path = Rails.root.join(@output % code) - File.write path, view.render(template: @template % code, layout: @layout) + File.write path, ApplicationController.render(@template % code, layout: @layout, locals: {code: code}) end end - - def helpers(&block) - @helpers = block - end - - private - - def build_action_view - paths = ::ActionController::Base.view_paths - ::ActionView::Base.new(paths).tap do |view| - view.class_eval do - include Rails.application.helpers - include Rails.application.routes.url_helpers - end - view.assets_manifest = build_manifest(Rails.application) - view.class_eval(&@helpers) if @helpers - end - end - - # Internal API from the sprocket-rails railtie, if somebody finds a way to - # call it, please replace it. Might need to be updated on sprocket-rails - # updates. - def build_manifest(app) - config = app.config - path = File.join(config.paths['public'].first, config.assets.prefix) - Sprockets::Manifest.new(app.assets, path, config.assets.manifest) - end end diff --git a/lib/node_info.rb b/lib/node_info.rb index f2118af26..05c96dcb1 100644 --- a/lib/node_info.rb +++ b/lib/node_info.rb @@ -4,13 +4,13 @@ require "pathname" require "json-schema" module NodeInfo - VERSIONS = %w(1.0 2.0).freeze - SCHEMAS = {} - private_constant :VERSIONS, :SCHEMAS + VERSIONS = %w[1.0 2.0 2.1].freeze + SCHEMAS = {} # rubocop:disable Style/MutableConstant + private_constant :SCHEMAS - # rubocop:disable Metrics/BlockLength Document = Struct.new(:version, :software, :protocols, :services, :open_registrations, :usage, :metadata) do - Software = Struct.new(:name, :version) do + # rubocop:disable Lint/ConstantDefinitionInBlock + Software = Struct.new(:name, :version, :repository, :homepage) do def initialize(name=nil, version=nil) super(name, version) end @@ -21,6 +21,13 @@ module NodeInfo "version" => version } end + + def version_21_hash + version_10_hash.merge( + "repository" => repository, + "homepage" => homepage + ) + end end Protocols = Struct.new(:protocols) do @@ -80,6 +87,7 @@ module NodeInfo } end end + # rubocop:enable Lint/ConstantDefinitionInBlock def self.build new.tap do |doc| @@ -98,6 +106,8 @@ module NodeInfo version_10_hash when "2.0" version_20_hash + when "2.1" + version_21_hash end end @@ -144,6 +154,18 @@ module NodeInfo ) end + def version_21_hash + deep_compact( + "version" => "2.1", + "software" => software.version_21_hash, + "protocols" => protocols.version_20_array, + "services" => services.version_10_hash, + "openRegistrations" => open_registrations, + "usage" => usage.version_10_hash, + "metadata" => metadata + ) + end + def deep_compact(hash) hash.tap do |hash| hash.reject! {|_, value| @@ -153,7 +175,6 @@ module NodeInfo end end end - # rubocop:enable Metrics/BlockLength def self.schema(version) SCHEMAS[version] ||= JSON.parse( diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 38101d7b3..4c65b8500 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -1,35 +1,40 @@ # frozen_string_literal: true namespace :assets do + # create new assets manifest for tasks which run after assets:precompile + def assets_manifest + return @assets_manifest if @assets_manifest + + config = Diaspora::Application.config + path = File.join(config.paths["public"].first, config.assets.prefix) + @assets_manifest = Sprockets::Manifest.new(Diaspora::Application.assets, path, config.assets.manifest) + end + desc "Generate error pages" - task :generate_error_pages => :environment do + task generate_error_pages: :environment do + ApplicationController.view_context_class.assets_manifest = assets_manifest renderer = ErrorPageRenderer.new codes: [404, 422, 500] renderer.render end desc "Create non digest assets" task non_digest_assets: :environment do - logger = ::Logging::Logger["assets:non_digest_assets"] + Diaspora::Application.config.assets.non_digest_assets.each do |asset| + digested_path = assets_manifest.assets[asset] + raise Sprockets::Rails::Helper::AssetNotFound, "Precompiled asset for '#{asset}' not found" unless digested_path - non_digest_assets = Diaspora::Application.config.assets.non_digest_assets - - Rails.application.assets_manifest.assets.each do |logical_path, digested_path| - logical_pathname = Pathname.new(logical_path) - next unless non_digest_assets.any? {|testpath| logical_pathname.fnmatch?(testpath, File::FNM_PATHNAME) } - - full_digested_path = Rails.root.join("public", "assets", digested_path) - full_non_digested_path = Rails.root.join("public", "assets", logical_path) + full_digested_path = File.join(assets_manifest.directory, digested_path) + full_non_digested_path = File.join(assets_manifest.directory, asset) next unless FileUtils.uptodate?(full_digested_path, [full_non_digested_path]) - logger.info "Copying #{full_digested_path} to #{full_non_digested_path}" - + puts "Copying #{full_digested_path} to #{full_non_digested_path}" FileUtils.copy_file(full_digested_path, full_non_digested_path, true) end end # Augment precompile with error page generation - task :precompile do + Rake::Task[:precompile].enhance do Rake::Task["assets:generate_error_pages"].invoke Rake::Task["assets:non_digest_assets"].invoke end diff --git a/spec/controllers/aspects_controller_spec.rb b/spec/controllers/aspects_controller_spec.rb index a243cfaf8..9e35896d6 100644 --- a/spec/controllers/aspects_controller_spec.rb +++ b/spec/controllers/aspects_controller_spec.rb @@ -98,8 +98,8 @@ describe AspectsController, :type => :controller do describe "update_order" do it "updates the aspect order" do - @alices_aspect_1.update_attributes(order_id: 10) - @alices_aspect_2.update_attributes(order_id: 20) + @alices_aspect_1.update(order_id: 10) + @alices_aspect_2.update(order_id: 20) ordered_aspect_ids = [@alices_aspect_2.id, @alices_aspect_1.id] put :update_order, params: {ordered_aspect_ids: ordered_aspect_ids} diff --git a/spec/controllers/contacts_controller_spec.rb b/spec/controllers/contacts_controller_spec.rb index 10cdc3ab5..2e32ec52e 100644 --- a/spec/controllers/contacts_controller_spec.rb +++ b/spec/controllers/contacts_controller_spec.rb @@ -76,7 +76,7 @@ describe ContactsController, :type => :controller do it "returns only contacts which are receiving (the user is sharing with them)" do contact = bob.contacts.first - contact.update_attributes(receiving: false) + contact.update(receiving: false) get :index, params: {params: {page: "1"}}, format: :json contact_ids = JSON.parse(response.body).map {|c| c["id"] } @@ -88,7 +88,7 @@ describe ContactsController, :type => :controller do context "set: all" do before do contact = bob.contacts.first - contact.update_attributes(receiving: false) + contact.update(receiving: false) end it "returns all contacts (sharing and receiving)" do diff --git a/spec/controllers/invitations_controller_spec.rb b/spec/controllers/invitations_controller_spec.rb index 7919b6a8b..87232f401 100644 --- a/spec/controllers/invitations_controller_spec.rb +++ b/spec/controllers/invitations_controller_spec.rb @@ -117,7 +117,7 @@ describe InvitationsController, type: :controller do end it "displays an error when no invitations are left" do - alice.invitation_code.update_attributes(count: 0) + alice.invitation_code.update(count: 0) post :create, params: invite_params @@ -127,7 +127,7 @@ describe InvitationsController, type: :controller do it "does not display an error when registration is open" do AppConfig.settings.invitations.open = false - alice.invitation_code.update_attributes(count: 0) + alice.invitation_code.update(count: 0) post :create, params: invite_params diff --git a/spec/controllers/node_info_controller_spec.rb b/spec/controllers/node_info_controller_spec.rb index ba3c10738..5c2925cbb 100644 --- a/spec/controllers/node_info_controller_spec.rb +++ b/spec/controllers/node_info_controller_spec.rb @@ -20,6 +20,9 @@ describe NodeInfoController do }, { "rel" => "http://nodeinfo.diaspora.software/ns/schema/2.0", "href" => node_info_url("2.0") + }, { + "rel" => "http://nodeinfo.diaspora.software/ns/schema/2.1", + "href" => node_info_url("2.1") }] end end @@ -33,7 +36,7 @@ describe NodeInfoController do end end - %w(1.0 2.0).each do |version| + %w[1.0 2.0 2.1].each do |version| context "version #{version}" do it "responds to JSON" do get :document, params: {version: version}, format: :json @@ -52,7 +55,7 @@ describe NodeInfoController do get :document, params: {version: version}, format: :json expect(response.content_type) - .to eq("application/json; profile=http://nodeinfo.diaspora.software/ns/schema/#{version}#") + .to eq("application/json; profile=http://nodeinfo.diaspora.software/ns/schema/#{version}#; charset=utf-8") end end end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 7bb94bcaa..8c43191a5 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -49,7 +49,7 @@ describe RegistrationsController, type: :controller do it "does redirect if there are no invites available with this code" do code = InvitationCode.create(user: bob) - code.update_attributes(count: 0) + code.update(count: 0) get :new, params: {invite: {token: code.token}} expect(response).to redirect_to registrations_closed_path @@ -67,7 +67,7 @@ describe RegistrationsController, type: :controller do AppConfig.settings.enable_registrations = true code = InvitationCode.create(user: bob) - code.update_attributes(count: 0) + code.update(count: 0) get :new, params: {invite: {token: code.token}} expect(response).not_to be_redirect diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index ac3e79727..9c4e29adf 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -138,22 +138,22 @@ describe UsersController, :type => :controller do before do allow(@controller).to receive(:current_user).and_return(@user) allow(@user).to receive(:update_with_password) - allow(@user).to receive(:update_attributes) + allow(@user).to receive(:update) end it "uses devise's update with password" do put :update, params: params expect(@user).to have_received(:update_with_password).with(hash_including(password_params)) - expect(@user).not_to have_received(:update_attributes).with(hash_including(password_params)) + expect(@user).not_to have_received(:update).with(hash_including(password_params)) end it "does not update the password without the change_password param" do put :update, params: params.except(:change_password).deep_merge(user: {language: "de"}) expect(@user).not_to have_received(:update_with_password).with(hash_including(password_params)) - expect(@user).not_to have_received(:update_attributes).with(hash_including(password_params)) - expect(@user).to have_received(:update_attributes).with(hash_including(language: "de")) + expect(@user).not_to have_received(:update).with(hash_including(password_params)) + expect(@user).to have_received(:update).with(hash_including(language: "de")) end end @@ -163,13 +163,13 @@ describe UsersController, :type => :controller do before do allow(@controller).to receive(:current_user).and_return(@user) - allow(@user).to receive(:update_attributes) + allow(@user).to receive(:update) end it "does not accept the params" do put :update, params: params - expect(@user).not_to have_received(:update_attributes) + expect(@user).not_to have_received(:update) .with(hash_including(:otp_required_for_login, :otp_secret)) end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index feb94673c..bf9f1d10f 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -48,9 +48,9 @@ describe ApplicationHelper, :type => :helper do end it "returns false if the service is already connected" do - @current_user.services << FactoryGirl.build(:service, provider: "service") - expect(AppConfig).to receive(:show_service?).with("service", alice).and_return(true) - expect(service_unconnected?("service")).to be false + @current_user.services << FactoryGirl.build(:service) + expect(AppConfig).to receive(:show_service?).with("twitter", alice).and_return(true) + expect(service_unconnected?("twitter")).to be false end it "returns false if the the service shouldn't be shown" do diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index dea069ef6..bfffc8f1a 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -128,13 +128,13 @@ describe NotificationsHelper, type: :helper do let(:notification) { Notifications::ContactsBirthday.create(recipient: alice, target: bob.person) } it "contains the date" do - bob.profile.update_attributes(birthday: Time.zone.today) + bob.profile.update(birthday: Time.zone.today) link = object_link(notification, notification_people_link(notification)) expect(link).to include(I18n.l(Time.zone.today, format: I18n.t("date.formats.fullmonth_day"))) end it "doesn't break, when the person removes the birthday date" do - bob.profile.update_attributes(birthday: nil) + bob.profile.update(birthday: nil) link = object_link(notification, notification_people_link(notification)) expect(link).to include(I18n.l(Time.zone.today, format: I18n.t("date.formats.fullmonth_day"))) end diff --git a/spec/helpers/notifier_helper_spec.rb b/spec/helpers/notifier_helper_spec.rb index 946753aa8..6f0b6a795 100644 --- a/spec/helpers/notifier_helper_spec.rb +++ b/spec/helpers/notifier_helper_spec.rb @@ -5,18 +5,23 @@ # the COPYRIGHT file. describe NotifierHelper, :type => :helper do - describe '#post_message' do + describe "#post_message" do before do # post for markdown test @markdown_post = FactoryGirl.create(:status_message, - text: "[link](http://diasporafoundation.org) **bold text** *other text*", public: true) - @striped_markdown_post = "link (http://diasporafoundation.org) bold text other text" + text: "[link](https://diasporafoundation.org) **bold text** *other text*", + public: true) + @striped_markdown_post = "link (https://diasporafoundation.org) bold text other text" end - it 'strip markdown in the post' do + it "strip markdown in the post" do expect(post_message(@markdown_post)).to eq(@striped_markdown_post) end + it "renders markdown as html" do + expect(post_message(@markdown_post, html: true)).to include("<a href=\"https://diasporafoundation.org\">link</a>") + end + it "falls back to the title if the post has no text" do photo = FactoryGirl.build(:photo, public: true) photo_post = FactoryGirl.build(:status_message, author: photo.author, text: "", photos: [photo], public: true) @@ -32,13 +37,13 @@ describe NotifierHelper, :type => :helper do end end - describe '#comment_message' do + describe "#comment_message" do before do # comment for markdown test @markdown_comment = FactoryGirl.create(:comment) @markdown_comment.post.public = true - @markdown_comment.text = "[link](http://diasporafoundation.org) **bold text** *other text*" - @striped_markdown_comment = "link (http://diasporafoundation.org) bold text other text" + @markdown_comment.text = "[link](https://diasporafoundation.org) **bold text** *other text*" + @striped_markdown_comment = "link (https://diasporafoundation.org) bold text other text" # comment for limited post @limited_comment = FactoryGirl.create(:comment) @@ -46,11 +51,16 @@ describe NotifierHelper, :type => :helper do @limited_comment.text = "This is top secret comment. Shhhhhhhh!!!" end - it 'strip markdown in the comment' do + it "strip markdown in the comment" do expect(comment_message(@markdown_comment)).to eq(@striped_markdown_comment) end - it 'hides the private content' do + it "renders markdown as html" do + expect(comment_message(@markdown_comment, html: true)) + .to include("<a href=\"https://diasporafoundation.org\">link</a>") + end + + it "hides the private content" do expect(comment_message(@limited_comment)).not_to include("secret comment") end end diff --git a/spec/helpers/people_helper_spec.rb b/spec/helpers/people_helper_spec.rb index 4b4140918..1a7d15f85 100644 --- a/spec/helpers/people_helper_spec.rb +++ b/spec/helpers/people_helper_spec.rb @@ -75,7 +75,7 @@ describe PeopleHelper, :type => :helper do end it 'links by id for a local user' do - expect(person_link(@user.person)).to include "href='#{person_path(@user.person)}'" + expect(person_link(@user.person)).to include "href=\"#{person_path(@user.person)}\"" end it "recognizes the 'display_name' option" do diff --git a/spec/integration/exporter_spec.rb b/spec/integration/exporter_spec.rb index 7794c07de..5a17f98d8 100644 --- a/spec/integration/exporter_spec.rb +++ b/spec/integration/exporter_spec.rb @@ -16,7 +16,8 @@ describe Diaspora::Exporter do %i[generic_user_data activity status_messages_flavours work_aspect] ) - expect(JSON.parse(json)).to match_json_schema(:archive_schema) + errors = JSON::Validator.fully_validate("lib/schemas/archive-format.json", JSON.parse(json)) + expect(errors).to be_empty end it "contains basic user data" do diff --git a/spec/integration/receiving_spec.rb b/spec/integration/receiving_spec.rb index e7a44cfbc..6a16bd8da 100644 --- a/spec/integration/receiving_spec.rb +++ b/spec/integration/receiving_spec.rb @@ -28,7 +28,7 @@ describe 'a user receives a post', :type => :request do bob.aspects.reload bob.add_to_streams(sm, [@bobs_aspect]) queue.drain_all - bob.dispatch_post(sm, :to => @bobs_aspect) + bob.dispatch_post(sm) end expect(alice.visible_shareables(Post).count(:all)).to eq(1) diff --git a/spec/javascripts/app/app_spec.js b/spec/javascripts/app/app_spec.js index 1848f20a7..5690becc2 100644 --- a/spec/javascripts/app/app_spec.js +++ b/spec/javascripts/app/app_spec.js @@ -1,4 +1,8 @@ describe("app", function() { + beforeAll(function() { + Diaspora.I18n.load(spec.defaultLocale, "en"); + }); + afterAll(function() { Backbone.history.stop(); app.initialize(); @@ -33,6 +37,10 @@ describe("app", function() { }); describe("user", function() { + beforeEach(function() { + logout(); + }); + it("returns false if the current_user isn't set", function() { app._user = undefined; expect(app.user()).toEqual(false); diff --git a/spec/javascripts/app/collections/contacts_collection_spec.js b/spec/javascripts/app/collections/contacts_collection_spec.js index 3b64d4bd9..a2342851d 100644 --- a/spec/javascripts/app/collections/contacts_collection_spec.js +++ b/spec/javascripts/app/collections/contacts_collection_spec.js @@ -21,6 +21,7 @@ describe("app.collections.Contacts", function(){ }); it("should compare the username if app.aspect is not present", function() { + delete app.aspect; expect(this.collection.comparator(this.con1, this.con3)).toBeLessThan(0); }); diff --git a/spec/javascripts/app/collections/notifications_collection_spec.js b/spec/javascripts/app/collections/notifications_collection_spec.js index 8a5c2b981..91a79941c 100644 --- a/spec/javascripts/app/collections/notifications_collection_spec.js +++ b/spec/javascripts/app/collections/notifications_collection_spec.js @@ -14,6 +14,12 @@ describe("app.collections.Notifications", function() { it("initializes attributes", function() { var target = new app.collections.Notifications(); + /* I don't know how backbone is working, but if I don't force reset the old values are kept from previous test */ + if (target !== undefined) { + target.unreadCount = 0; + target.unreadCountByType = {}; + } + /* end of force refresh */ expect(target.model).toBe(app.models.Notification); /* eslint-disable camelcase */ expect(target.url).toBe(Routes.notifications({per_page: 10, page: 1})); @@ -174,6 +180,12 @@ describe("app.collections.Notifications", function() { describe("parse", function() { beforeEach(function() { this.target = new app.collections.Notifications(); + /* I don't know how backbone is working, but if I don't force reset the old values are kept from previous test */ + if (this.target !== undefined) { + this.target.unreadCount = 0; + this.target.unreadCountByType = {}; + } + /* end of force refresh */ }); it("sets the unreadCount and unreadCountByType attributes", function() { diff --git a/spec/javascripts/app/models/post/interacations_spec.js b/spec/javascripts/app/models/post/interacations_spec.js index 599929eca..3ca66c9f9 100644 --- a/spec/javascripts/app/models/post/interacations_spec.js +++ b/spec/javascripts/app/models/post/interacations_spec.js @@ -122,9 +122,11 @@ describe("app.models.Post.Interactions", function(){ }); it("adds the reshare to the default, activity and aspects stream", function() { - app.stream = { addNow: $.noop }; + app.stream = new app.models.Stream(_, {basePath: "/aspects/all"}); + spyOn(app.stream, "addNow"); var self = this; + ["/stream", "/activity", "/aspects"].forEach(function(path) { app.stream.basePath = function() { return path; }; self.interactions.reshare(); @@ -132,10 +134,13 @@ describe("app.models.Post.Interactions", function(){ expect(app.stream.addNow).toHaveBeenCalledWith({id: 1}); }); + + app.stream = new app.models.Stream(_, {basePath: "/aspects/all"}); }); it("doesn't add the reshare to any other stream", function() { - app.stream = { addNow: $.noop }; + app.stream = new app.models.Stream(_, {basePath: "/aspects/all"}); + spyOn(app.stream, "addNow"); var self = this; ["/followed_tags", "/mentions/", "/tag/diaspora", "/people/guid/stream"].forEach(function(path) { @@ -144,6 +149,8 @@ describe("app.models.Post.Interactions", function(){ jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess); expect(app.stream.addNow).not.toHaveBeenCalled(); }); + + app.stream = new app.models.Stream(_, {basePath: "/aspects/all"}); }); it("sets the participation flag for the post", function() { diff --git a/spec/javascripts/app/router_spec.js b/spec/javascripts/app/router_spec.js index 14e6dd2df..f635c42ed 100644 --- a/spec/javascripts/app/router_spec.js +++ b/spec/javascripts/app/router_spec.js @@ -1,8 +1,15 @@ describe('app.Router', function () { + beforeEach(function() { + delete app.page; + new app.Router().stream(); + }); + describe('followed_tags', function() { beforeEach(function() { + loginAs({name: "alice"}); factory.preloads({tagFollowings: []}); spec.loadFixture("aspects_index"); + app.publisher = new app.views.Publisher({standalone: true}); }); it('decodes name before passing it into TagFollowingAction', function () { @@ -74,6 +81,8 @@ describe('app.Router', function () { describe("aspects", function() { it("calls _initializeStreamView", function() { + new app.models.Stream(); + app.publisher = new app.views.Publisher({standalone: true}); spyOn(app.router, "_initializeStreamView"); app.router.aspects(); expect(app.router._initializeStreamView).toHaveBeenCalled(); @@ -123,6 +132,7 @@ describe('app.Router', function () { describe("stream", function() { it("calls _initializeStreamView", function() { + app.publisher = new app.views.Publisher({standalone: true}); spyOn(app.router, "_initializeStreamView"); app.router.stream(); expect(app.router._initializeStreamView).toHaveBeenCalled(); @@ -169,6 +179,7 @@ describe('app.Router', function () { app.publisher = { jasmineTestValue: 42 }; app.router._initializeStreamView(); expect(app.publisher.jasmineTestValue).toEqual(42); + delete app.publisher; // don't leave fake publisher around }); it("doesn't set app.publisher if there is no publisher element in page", function() { diff --git a/spec/javascripts/app/views/comment_view_spec.js b/spec/javascripts/app/views/comment_view_spec.js index fc5a633cf..fb73ff190 100644 --- a/spec/javascripts/app/views/comment_view_spec.js +++ b/spec/javascripts/app/views/comment_view_spec.js @@ -1,11 +1,11 @@ describe("app.views.Comment", function(){ - beforeEach(function(){ + beforeEach(function() { this.post = factory.post({author : {diaspora_id : "xxx@xxx.xxx"}}); this.comment = factory.comment({parent : this.post.toJSON()}); this.view = new app.views.Comment({model : this.comment}); }); - describe("render", function(){ + describe("render", function() { it("has a delete link if the author is the current user", function(){ loginAs(this.comment.get("author")); expect(this.view.render().$('.delete').length).toBe(1); @@ -47,6 +47,10 @@ describe("app.views.Comment", function(){ }); describe("canRemove", function(){ + beforeEach(function() { + loginAs({name: "alice"}); + }); + context("is truthy", function(){ it("when ownComment is true", function(){ spyOn(this.view, "ownComment").and.returnValue(true); diff --git a/spec/javascripts/app/views/help_view_spec.js b/spec/javascripts/app/views/help_view_spec.js index e73830267..d23f2cded 100644 --- a/spec/javascripts/app/views/help_view_spec.js +++ b/spec/javascripts/app/views/help_view_spec.js @@ -21,71 +21,6 @@ describe("app.views.Help", function(){ it('should initially show getting help section', function(){ expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_getting_help'); }); - - it('should show account and data management section', function(){ - this.view.$el.find('a[data-section=account_and_data_management]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_account_and_data_management')).toBeTruthy(); - }); - - it('should show aspects section', function(){ - this.view.$el.find('a[data-section=aspects]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_aspects')).toBeTruthy(); - }); - - it('should show mentions section', function(){ - this.view.$el.find('a[data-section=mentions]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_mentions')).toBeTruthy(); - }); - - it('should show pods section', function(){ - this.view.$el.find('a[data-section=pods]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_pods')).toBeTruthy(); - }); - - it('should show posts and posting section', function(){ - this.view.$el.find('a[data-section=posts_and_posting]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_posts_and_posting'); - }); - - it('should show private posts section', function(){ - this.view.$el.find('a[data-section=private_posts]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_private_posts')).toBeTruthy(); - }); - - it('should show public posts section', function(){ - this.view.$el.find('a[data-section=public_posts]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_public_posts')).toBeTruthy(); - }); - - it('should show resharing posts section', function(){ - this.view.$el.find('a[data-section=resharing_posts]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_resharing_posts')).toBeTruthy(); - }); - - it("should show profile section", function() { - this.view.$el.find("a[data-section=profile]").trigger("click"); - expect(this.view.$el.find("#faq").children().first().hasClass("faq_question_profile")).toBeTruthy(); - }); - - it('should show sharing section', function(){ - this.view.$el.find('a[data-section=sharing]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_sharing'); - }); - - it('should show tags section', function(){ - this.view.$el.find('a[data-section=tags]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_tags'); - }); - - it('should show keyboard shortcuts section', function(){ - this.view.$el.find('a[data-section=keyboard_shortcuts]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_keyboard_shortcuts'); - }); - - it('should show miscellaneous section', function(){ - this.view.$el.find('a[data-section=miscellaneous]').trigger('click'); - expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_miscellaneous')).toBeTruthy(); - }); }); describe("findSection", function() { diff --git a/spec/javascripts/app/views/notification_dropdown_view_spec.js b/spec/javascripts/app/views/notification_dropdown_view_spec.js index 725ae0d57..50a9de755 100644 --- a/spec/javascripts/app/views/notification_dropdown_view_spec.js +++ b/spec/javascripts/app/views/notification_dropdown_view_spec.js @@ -5,6 +5,7 @@ describe("app.views.NotificationDropdown", function() { this.header = new app.views.Header(); $("header").prepend(this.header.el); loginAs({guid: "foo"}); + app.notificationsCollection = new app.collections.Notifications(); this.header.render(); this.collection = new app.collections.Notifications(); this.view = new app.views.NotificationDropdown({el: "#notification-dropdown", collection: this.collection}); diff --git a/spec/javascripts/app/views/publisher_view_spec.js b/spec/javascripts/app/views/publisher_view_spec.js index a43d12a76..a5892f77f 100644 --- a/spec/javascripts/app/views/publisher_view_spec.js +++ b/spec/javascripts/app/views/publisher_view_spec.js @@ -25,7 +25,8 @@ describe("app.views.Publisher", function() { describe("createStatusMessage", function(){ it("doesn't add the status message to the stream", function() { - app.stream = { addNow: $.noop }; + app.stream = new app.models.Stream(); + spyOn(app.stream, "addNow"); this.view.createStatusMessage($.Event()); jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, responseText: "{\"id\": 1}" }); @@ -198,7 +199,8 @@ describe("app.views.Publisher", function() { describe("createStatusMessage", function(){ it("adds the status message to the stream", function() { - app.stream = { addNow: $.noop }; + app.stream = new app.models.Stream(); + spyOn(app.stream, "addNow"); this.view.createStatusMessage($.Event()); jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, responseText: "{\"id\": 1}" }); diff --git a/spec/javascripts/app/views/single-post-view/single_post_interactions_spec.js b/spec/javascripts/app/views/single-post-view/single_post_interactions_spec.js index 507317a20..dad2951e7 100644 --- a/spec/javascripts/app/views/single-post-view/single_post_interactions_spec.js +++ b/spec/javascripts/app/views/single-post-view/single_post_interactions_spec.js @@ -1,5 +1,6 @@ describe("app.views.SinglePostInteractions", function() { beforeEach(function() { + loginAs({name: "alice", avatar: {small: "http://avatar.com/photo.jpg"}}); this.post = factory.post(); this.view = new app.views.SinglePostInteractions({model: this.post}); }); diff --git a/spec/javascripts/app/views/stream/shortcuts_spec.js b/spec/javascripts/app/views/stream/shortcuts_spec.js index ba58b54c1..19c1b8d3f 100644 --- a/spec/javascripts/app/views/stream/shortcuts_spec.js +++ b/spec/javascripts/app/views/stream/shortcuts_spec.js @@ -1,6 +1,10 @@ describe("app.views.StreamShortcuts", function () { beforeEach(function() { + // This puts `app.page` into the proper state. + delete app.page; + new app.Router().stream(); + this.post1 = factory.post({author : factory.author({name : "Rebecca Black", id : 1492})}); this.post2 = factory.post({author : factory.author({name : "John Stamos", id : 1987})}); diff --git a/spec/javascripts/app/views/stream_post_spec.js b/spec/javascripts/app/views/stream_post_spec.js index d36a95e4a..2aa9f41fc 100644 --- a/spec/javascripts/app/views/stream_post_spec.js +++ b/spec/javascripts/app/views/stream_post_spec.js @@ -1,5 +1,9 @@ describe("app.views.StreamPost", function(){ beforeEach(function(){ + // This puts `app.page` into the proper state. + delete app.page; + new app.Router().stream(); + this.PostViewClass = app.views.StreamPost; var posts = $.parseJSON(spec.readFixture("stream_json")); diff --git a/spec/javascripts/app/views/stream_view_spec.js b/spec/javascripts/app/views/stream_view_spec.js index c0caee100..a9b602baa 100644 --- a/spec/javascripts/app/views/stream_view_spec.js +++ b/spec/javascripts/app/views/stream_view_spec.js @@ -1,5 +1,9 @@ describe("app.views.Stream", function() { beforeEach(function() { + // This puts `app.page` into the proper state. + delete app.page; + new app.Router().stream(); + loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}}); this.posts = $.parseJSON(spec.readFixture("stream_json")); diff --git a/spec/javascripts/helpers/markdown_editor_spec.js b/spec/javascripts/helpers/markdown_editor_spec.js index 55bc68942..318d44a2c 100644 --- a/spec/javascripts/helpers/markdown_editor_spec.js +++ b/spec/javascripts/helpers/markdown_editor_spec.js @@ -1,5 +1,6 @@ describe("Diaspora.MarkdownEditor", function() { beforeEach(function() { + Diaspora.I18n.load(spec.defaultLocale, "en"); spec.content().html("<textarea id='fake-textarea'></textarea>"); this.$el = $("#fake-textarea"); }); diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml index cac5e7fcb..91b101cbc 100644 --- a/spec/javascripts/support/jasmine.yml +++ b/spec/javascripts/support/jasmine.yml @@ -81,5 +81,4 @@ spec_dir: spec/javascripts rack_options: Host: '0.0.0.0' -# TODO: refactor tests, they shouldn't fail when they are run in a random order! -random: false +random: true diff --git a/spec/lib/connection_tester_spec.rb b/spec/lib/connection_tester_spec.rb index 01acd20f4..d665dd717 100644 --- a/spec/lib/connection_tester_spec.rb +++ b/spec/lib/connection_tester_spec.rb @@ -47,9 +47,8 @@ describe ConnectionTester do end describe "#request" do - it "performs a successful GET request on '/' and '/.well-known/host-meta'" do + it "performs a successful GET request on '/'" do stub_request(:get, url).to_return(status: 200, body: "Hello World!") - stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta") tester.request expect(result.rt).to be > -1 @@ -60,27 +59,22 @@ describe ConnectionTester do it "receives a 'normal' 301 redirect" do stub_request(:get, url).to_return(status: 301, headers: {"Location" => "#{url}/redirect"}) stub_request(:get, "#{url}/redirect").to_return(status: 200, body: "Hello World!") - stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta") tester.request end it "updates ssl after https redirect" do tester = ConnectionTester.new("http://pod.example.com/", result) - stub_request(:get, "http://pod.example.com/").to_return(status: 200, body: "Hello World!") - stub_request(:get, "http://pod.example.com/.well-known/host-meta") - .to_return(status: 301, headers: {"Location" => "#{url}/.well-known/host-meta"}) - stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta") + stub_request(:get, "http://pod.example.com/").to_return(status: 301, headers: {"Location" => url}) + stub_request(:get, url).to_return(status: 200, body: "Hello World!") tester.request expect(result.ssl).to be_truthy end - it "rejects other hostname after redirect redirect" do - stub_request(:get, url).to_return(status: 200, body: "Hello World!") - stub_request(:get, "#{url}/.well-known/host-meta") - .to_return(status: 301, headers: {"Location" => "https://example.com/.well-known/host-meta"}) - stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 200, body: "host-meta") + it "rejects other hostname after redirect" do + stub_request(:get, url).to_return(status: 301, headers: {"Location" => "https://example.com/"}) + stub_request(:get, "https://example.com/").to_return(status: 200, body: "Hello World!") expect { tester.request }.to raise_error(ConnectionTester::HTTPFailure) end @@ -100,6 +94,11 @@ describe ConnectionTester do expect { tester.request }.to raise_error(ConnectionTester::HTTPFailure) end + it "receives a 502 bad gateway" do + stub_request(:get, url).to_return(status: 502, body: "Bad Gateway!") + expect { tester.request }.to raise_error(ConnectionTester::HTTPFailure) + end + it "cannot connect" do stub_request(:get, url).to_raise(Faraday::ConnectionFailed.new("Error!")) expect { tester.request }.to raise_error(ConnectionTester::NetFailure) @@ -112,48 +111,92 @@ describe ConnectionTester do end describe "#nodeinfo" do - let(:ni_wellknown) { {links: [{rel: ConnectionTester::NODEINFO_SCHEMA, href: "/nodeinfo"}]} } - - it "reads the version from the nodeinfo document" do - ni_document = NodeInfo.build do |doc| - doc.version = "1.0" + def build_ni_document(version) + NodeInfo.build do |doc| + doc.version = version doc.open_registrations = true doc.protocols.protocols << "diaspora" doc.software.name = "diaspora" doc.software.version = "a.b.c.d" end + end + + NodeInfo::VERSIONS.each do |version| + context "with version #{version}" do + let(:ni_wellknown) { + {links: [{rel: "http://nodeinfo.diaspora.software/ns/schema/#{version}", href: "/nodeinfo/#{version}"}]} + } + + it "reads the version from the nodeinfo document" do + ni_document = build_ni_document(version) + + stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") + .to_return(status: 200, body: JSON.generate(ni_wellknown)) + stub_request(:get, "#{url}/nodeinfo/#{version}") + .to_return(status: 200, body: JSON.generate(ni_document.as_json)) + + tester.nodeinfo + expect(result.software_version).to eq("diaspora a.b.c.d") + end + end + end + + it "uses the latest commonly supported version" do + ni_wellknown = {links: [ + {rel: "http://nodeinfo.diaspora.software/ns/schema/1.0", href: "/nodeinfo/1.0"}, + {rel: "http://nodeinfo.diaspora.software/ns/schema/1.1", href: "/nodeinfo/1.1"}, + {rel: "http://nodeinfo.diaspora.software/ns/schema/2.0", href: "/nodeinfo/2.0"}, + {rel: "http://nodeinfo.diaspora.software/ns/schema/9.0", href: "/nodeinfo/9.0"} + ]} + + ni_document = build_ni_document("2.0") stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") .to_return(status: 200, body: JSON.generate(ni_wellknown)) - stub_request(:get, "#{url}/nodeinfo").to_return(status: 200, body: JSON.generate(ni_document.as_json)) + stub_request(:get, "#{url}/nodeinfo/2.0").to_return(status: 200, body: JSON.generate(ni_document.as_json)) tester.nodeinfo expect(result.software_version).to eq("diaspora a.b.c.d") end - it "handles a missing nodeinfo document gracefully" do + it "handles no common version gracefully" do + ni_wellknown = {links: [{rel: "http://nodeinfo.diaspora.software/ns/schema/1.1", href: "/nodeinfo/1.1"}]} stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") - .to_return(status: 404, body: "Not Found") + .to_return(status: 200, body: JSON.generate(ni_wellknown)) expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure) end + it "fails the nodeinfo document is missing" do + stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}").to_return(status: 404, body: "Not Found") + expect { tester.nodeinfo }.to raise_error(ConnectionTester::HTTPFailure) + end + it "handles a malformed document gracefully" do stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") .to_return(status: 200, body: '{"json"::::"malformed"}') expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure) end + it "handles timeout gracefully" do + ni_wellknown = {links: [{rel: "http://nodeinfo.diaspora.software/ns/schema/1.0", href: "/nodeinfo/1.0"}]} + stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") + .to_return(status: 200, body: JSON.generate(ni_wellknown)) + stub_request(:get, "#{url}/nodeinfo/1.0").to_raise(Faraday::TimeoutError.new) + expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure) + end + it "handles a invalid jrd document gracefully" do - invalid_wellknown = {links: {rel: ConnectionTester::NODEINFO_SCHEMA, href: "/nodeinfo"}} + invalid_wellknown = {links: {rel: "http://nodeinfo.diaspora.software/ns/schema/1.0", href: "/nodeinfo/1.0"}} stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") .to_return(status: 200, body: JSON.generate(invalid_wellknown)) expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure) end it "handles a invalid nodeinfo document gracefully" do + ni_wellknown = {links: [{rel: "http://nodeinfo.diaspora.software/ns/schema/1.0", href: "/nodeinfo/1.0"}]} stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") .to_return(status: 200, body: JSON.generate(ni_wellknown)) - stub_request(:get, "#{url}/nodeinfo").to_return(status: 200, body: '{"software": "invalid nodeinfo"}') + stub_request(:get, "#{url}/nodeinfo/1.0").to_return(status: 200, body: '{"software": "invalid nodeinfo"}') expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure) end end diff --git a/spec/lib/diaspora/federated/contact_retraction_spec.rb b/spec/lib/diaspora/federated/contact_retraction_spec.rb index 04e19ea1c..efa6e4ec0 100644 --- a/spec/lib/diaspora/federated/contact_retraction_spec.rb +++ b/spec/lib/diaspora/federated/contact_retraction_spec.rb @@ -53,7 +53,7 @@ describe ContactRetraction do federation_retraction_data = Diaspora::Federation::Entities.contact(contact).to_h expect(Workers::DeferredRetraction).to receive(:perform_async).with( - local_luke.id, "ContactRetraction", federation_retraction_data, [remote_raphael.id], {} + local_luke.id, "ContactRetraction", federation_retraction_data.deep_stringify_keys, [remote_raphael.id], {} ) retraction.defer_dispatch(local_luke) diff --git a/spec/lib/diaspora/federated/retraction_spec.rb b/spec/lib/diaspora/federated/retraction_spec.rb index ff1149064..841645ec7 100644 --- a/spec/lib/diaspora/federated/retraction_spec.rb +++ b/spec/lib/diaspora/federated/retraction_spec.rb @@ -70,7 +70,8 @@ describe Retraction do federation_retraction = Diaspora::Federation::Entities.retraction(retraction) expect(Workers::DeferredRetraction).to receive(:perform_async).with( - local_luke.id, "Retraction", federation_retraction.to_h, [remote_raphael.id], service_types: [] + local_luke.id, "Retraction", federation_retraction.to_h.deep_stringify_keys, [remote_raphael.id], + "service_types" => [] ) retraction.defer_dispatch(local_luke) @@ -85,7 +86,8 @@ describe Retraction do federation_retraction = Diaspora::Federation::Entities.retraction(retraction) expect(Workers::DeferredRetraction).to receive(:perform_async).with( - alice.id, "Retraction", federation_retraction.to_h, [], service_types: ["Services::Twitter"], tweet_id: "123" + alice.id, "Retraction", federation_retraction.to_h.deep_stringify_keys, [], + "service_types" => ["Services::Twitter"], "tweet_id" => "123" ) retraction.defer_dispatch(alice) @@ -96,7 +98,7 @@ describe Retraction do federation_retraction = Diaspora::Federation::Entities.retraction(retraction) expect(Workers::DeferredRetraction).to receive(:perform_async).with( - alice.id, "Retraction", federation_retraction.to_h, [], service_types: [] + alice.id, "Retraction", federation_retraction.to_h.deep_stringify_keys, [], "service_types" => [] ) retraction.defer_dispatch(alice) @@ -109,7 +111,7 @@ describe Retraction do federation_retraction = Diaspora::Federation::Entities.retraction(retraction) expect(Workers::DeferredRetraction).to receive(:perform_async).with( - local_luke.id, "Retraction", federation_retraction.to_h, [remote_raphael.id], {} + local_luke.id, "Retraction", federation_retraction.to_h.deep_stringify_keys, [remote_raphael.id], {} ) retraction.defer_dispatch(local_luke) @@ -124,7 +126,7 @@ describe Retraction do federation_retraction = Diaspora::Federation::Entities.retraction(retraction) expect(Workers::DeferredRetraction).to receive(:perform_async).with( - local_luke.id, "Retraction", federation_retraction.to_h, [remote_raphael.id], {} + local_luke.id, "Retraction", federation_retraction.to_h.deep_stringify_keys, [remote_raphael.id], {} ) retraction.defer_dispatch(local_luke) @@ -135,7 +137,7 @@ describe Retraction do federation_retraction = Diaspora::Federation::Entities.retraction(retraction) expect(Workers::DeferredRetraction).to receive(:perform_async).with( - local_luke.id, "Retraction", federation_retraction.to_h, [], {} + local_luke.id, "Retraction", federation_retraction.to_h.deep_stringify_keys, [], {} ) retraction.defer_dispatch(local_luke, false) diff --git a/spec/lib/diaspora/federation/dispatcher_spec.rb b/spec/lib/diaspora/federation/dispatcher_spec.rb index a4faa0ab9..723267e78 100644 --- a/spec/lib/diaspora/federation/dispatcher_spec.rb +++ b/spec/lib/diaspora/federation/dispatcher_spec.rb @@ -57,7 +57,8 @@ describe Diaspora::Federation::Dispatcher do describe ".defer_dispatch" do it "queues a job for dispatch" do - expect(Workers::DeferredDispatch).to receive(:perform_async).with(alice.id, "StatusMessage", post.id, opts) + expect(Workers::DeferredDispatch) + .to receive(:perform_async).with(alice.id, "StatusMessage", post.id, opts.deep_stringify_keys) described_class.defer_dispatch(alice, post, opts) end end diff --git a/spec/lib/diaspora/mentionable_spec.rb b/spec/lib/diaspora/mentionable_spec.rb index 25926d898..78e590b75 100644 --- a/spec/lib/diaspora/mentionable_spec.rb +++ b/spec/lib/diaspora/mentionable_spec.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true describe Diaspora::Mentionable do - include PeopleHelper - let(:people) { [alice, bob, eve].map(&:person) } let(:names) { %w(Alice\ A Bob\ B "Eve>\ E) } @@ -41,7 +39,9 @@ STR end describe ".format" do - context "html output" do + context "html output", type: :helper do + include PeopleHelper + it "adds the links to the formatted message" do fmt_msg = Diaspora::Mentionable.format(test_text_with_names, people) @@ -75,7 +75,7 @@ STR fmt_msg = Diaspora::Mentionable.format(test_txt, people) expect(fmt_msg).not_to include(name) - expect(fmt_msg).to include(">", "<", "'") # ">", "<", "'" + expect(fmt_msg).to include("</a><script>alert('h')</script>") end end @@ -184,7 +184,7 @@ STR user_a.aspects.where(name: "generic").first.contacts.map(&:person_id) ) - expect(txt).to include("@[user C](#{local_or_remote_person_path(user_c.person)}") + expect(txt).to include("@[user C](#{Rails.application.routes.url_helpers.person_path(user_c.person)}") expect(txt).not_to include("href") expect(txt).not_to include(mention) end diff --git a/spec/lib/diaspora/message_renderer_spec.rb b/spec/lib/diaspora/message_renderer_spec.rb index 248563ed8..44dc9e2d8 100644 --- a/spec/lib/diaspora/message_renderer_spec.rb +++ b/spec/lib/diaspora/message_renderer_spec.rb @@ -78,12 +78,6 @@ describe Diaspora::MessageRenderer do end context 'linking all mentions' do - it 'makes plain links for people not in the post aspects' do - message = message("@{Bob; #{bob.person.diaspora_handle}}", link_all_mentions: true).html - expect(message).to_not include 'hovercard' - expect(message).to include '/u/bob' - end - it "makes no hovercards if they're disabled" do message = message( "@{Bob; #{bob.person.diaspora_handle}}", @@ -91,7 +85,7 @@ describe Diaspora::MessageRenderer do disable_hovercards: true ).html expect(message).to_not include 'hovercard' - expect(message).to include '/u/bob' + expect(message).to include AppConfig.url_to("/people/#{bob.person.guid}") end end end diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb index a8abde338..872530e9b 100644 --- a/spec/mailers/notifier_spec.rb +++ b/spec/mailers/notifier_spec.rb @@ -121,10 +121,6 @@ describe Notifier, type: :mailer do it "has the post text in the body" do expect(@mail.body.encoded).to include(@post.text) end - - it "should not include translation fallback" do - expect(@mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end end describe ".mentioned_in_comment" do @@ -180,10 +176,6 @@ describe Notifier, type: :mailer do it "has the post text not in the body" do expect(@mail.body.encoded).not_to include(@post.text) end - - it "should not include translation fallback" do - expect(@mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end end describe ".liked" do @@ -205,10 +197,6 @@ describe Notifier, type: :mailer do expect(@mail.body.encoded).to include(@like.author.name) end - it "should not include translation fallback" do - expect(@mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end - it "can handle a reshare" do reshare = FactoryGirl.create(:reshare) like = reshare.likes.create!(author: bob.person) @@ -247,10 +235,6 @@ describe Notifier, type: :mailer do it "BODY: contains the name of person liking" do expect(@mail.body.encoded).to include(@reshare.author.name) end - - it "should not include translation fallback" do - expect(@mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end end describe ".private_message" do @@ -294,10 +278,6 @@ describe Notifier, type: :mailer do it "BODY: does not contain the message text" do expect(@mail.body.encoded).not_to include(@cnv.messages.first.text) end - - it "should not include translation fallback" do - expect(@mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end end context "comments" do @@ -334,10 +314,6 @@ describe Notifier, type: :mailer do it "contains the original post's link with comment anchor" do expect(comment_mail.body.encoded).to include("#{comment.post.id}##{comment.guid}") end - - it "should not include translation fallback" do - expect(comment_mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end end [:reshare].each do |post_type| @@ -380,10 +356,6 @@ describe Notifier, type: :mailer do it "contains the original post's link with comment anchor" do expect(comment_mail.body.encoded).to include("#{comment.post.id}##{comment.guid}") end - - it "should not include translation fallback" do - expect(comment_mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end end [:reshare].each do |post_type| context post_type.to_s do @@ -490,10 +462,6 @@ describe Notifier, type: :mailer do it "BODY: contains the name of person liking" do expect(mail.body.encoded).to include(bob.name) end - - it "should not include translation fallback" do - expect(mail.body.encoded).not_to include(I18n.translate "notifier.a_post_you_shared") - end end end @@ -548,7 +516,7 @@ describe Notifier, type: :mailer do end it "has the inviter id if the name is nil" do - bob.person.profile.update_attributes(first_name: "", last_name: "") + bob.person.profile.update(first_name: "", last_name: "") mail = Notifier.invite(alice.email, bob, "1234", "en") expect(email.body.encoded).to_not include("#{bob.name} (#{bob.diaspora_handle})") expect(mail.body.encoded).to include(bob.person.diaspora_handle) @@ -580,16 +548,16 @@ describe Notifier, type: :mailer do it "has some informative text in the body" do email.body.parts.each do |part| - expect(part.decoded).to include("https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)") + expect(part.decoded).to include("https://owasp.org/www-community/attacks/csrf") end end end describe "hashtags" do it "escapes hashtags" do - mails = Notifier.admin("#Welcome to bureaucracy!", [bob]) - expect(mails.length).to eq(1) - mail = mails.first + status = FactoryGirl.create(:status_message, author: alice.person, text: "#Welcome to bureaucracy!", public: true) + like = status.likes.create!(author: bob.person) + mail = Notifier.send_notification("liked", alice.id, like.author.id, like.id) expect(mail.body.encoded).to match( "<p><a href=\"#{AppConfig.url_to(tag_path('welcome'))}\">#Welcome</a> to bureaucracy!</p>" ) @@ -605,7 +573,7 @@ describe Notifier, type: :mailer do end it "FROM: header should be 'pod_name (username)' when there is no first and last name" do - bob.person.profile.update_attributes(first_name: "", last_name: "") + bob.person.profile.update(first_name: "", last_name: "") mail = Notifier.send_notification("started_sharing", alice.id, bob.person.id) expect(mail["From"].to_s).to eq("\"#{pod_name} (#{bob.person.username})\" <#{AppConfig.mail.sender_address}>") end diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb index 8087506d8..a40047d0a 100644 --- a/spec/models/person_spec.rb +++ b/spec/models/person_spec.rb @@ -203,7 +203,7 @@ describe Person, :type => :model do describe "delegating" do it "delegates last_name to the profile" do expect(@person.last_name).to eq(@person.profile.last_name) - @person.profile.update_attributes(:last_name => "Heathers") + @person.profile.update(last_name: "Heathers") expect(@person.reload.last_name).to eq("Heathers") end end @@ -370,18 +370,18 @@ describe Person, :type => :model do end describe "#first_name" do - it 'returns username if first_name is not present in profile' do - alice.person.profile.update_attributes(:first_name => "") + it "returns username if first_name is not present in profile" do + alice.person.profile.update(first_name: "") expect(alice.person.first_name).to eq(alice.username) end - it 'returns first words in first_name if first_name is present' do - alice.person.profile.update_attributes(:first_name => "First Mid Last") + it "returns first words in first_name if first_name is present" do + alice.person.profile.update(first_name: "First Mid Last") expect(alice.person.first_name).to eq("First Mid") end - it 'returns first word in first_name if first_name is present' do - alice.person.profile.update_attributes(:first_name => "Alice") + it "returns first word in first_name if first_name is present" do + alice.person.profile.update(first_name: "Alice") expect(alice.person.first_name).to eq("Alice") end end @@ -591,7 +591,7 @@ describe Person, :type => :model do end it "handles broken keys and returns nil" do - @person.update_attributes(serialized_public_key: "broken") + @person.update(serialized_public_key: "broken") expect(@person.public_key).to be_nil end end diff --git a/spec/models/pod_spec.rb b/spec/models/pod_spec.rb index a8001d3a8..6ad265b2f 100644 --- a/spec/models/pod_spec.rb +++ b/spec/models/pod_spec.rb @@ -143,31 +143,28 @@ describe Pod, type: :model do describe "#test_connection!" do before do @pod = FactoryGirl.create(:pod) - @result = double("result") @now = Time.zone.now - allow(@result).to receive(:rt) { 123 } - allow(@result).to receive(:software_version) { "diaspora a.b.c.d" } - allow(@result).to receive(:failure_message) { "hello error!" } + @result = ConnectionTester::Result.new + @result.rt = 123 + @result.software_version = "diaspora a.b.c.d" + @result.error = ConnectionTester::NetFailure.new("hello error!") expect(ConnectionTester).to receive(:check).at_least(:once).and_return(@result) end it "updates the connectivity values" do - allow(@result).to receive(:error) - allow(@result).to receive(:error?) + @result.error = nil @pod.test_connection! expect(@pod.status).to eq("no_errors") - expect(@pod.offline?).to be_falsy + expect(@pod.offline?).to be_falsey expect(@pod.response_time).to eq(123) expect(@pod.checked_at).to be_within(1.second).of @now end it "resets the scheduled_check flag" do - allow(@result).to receive(:error) - allow(@result).to receive(:error?) - @pod.update_column(:scheduled_check, true) + @pod.update(scheduled_check: true) @pod.test_connection! @@ -175,17 +172,22 @@ describe Pod, type: :model do end it "handles a failed check" do - expect(@result).to receive(:error?).at_least(:once) { true } - expect(@result).to receive(:error).at_least(:once) { ConnectionTester::NetFailure.new } @pod.test_connection! expect(@pod.offline?).to be_truthy expect(@pod.offline_since).to be_within(1.second).of @now end + it "removes the error message when there was no error" do + @pod.update(error: "old error message") + + @result.error = nil + @pod.test_connection! + + expect(@pod.error).to be_nil + end + it "preserves the original offline timestamp" do - expect(@result).to receive(:error?).at_least(:once) { true } - expect(@result).to receive(:error).at_least(:once) { ConnectionTester::NetFailure.new } @pod.test_connection! expect(@pod.offline_since).to be_within(1.second).of @now diff --git a/spec/models/reshare_spec.rb b/spec/models/reshare_spec.rb index 39cbbcbf2..97593c115 100644 --- a/spec/models/reshare_spec.rb +++ b/spec/models/reshare_spec.rb @@ -26,7 +26,7 @@ describe Reshare, type: :model do reshare1 = FactoryGirl.create(:reshare, author: alice.person) reshare2 = FactoryGirl.create(:reshare, author: alice.person) - reshare1.update_attributes(root_guid: nil) + reshare1.update(root_guid: nil) reshare2.root_guid = nil expect(reshare2).to be_valid diff --git a/spec/models/user/querying_spec.rb b/spec/models/user/querying_spec.rb index 53843a7bc..27ad42d44 100644 --- a/spec/models/user/querying_spec.rb +++ b/spec/models/user/querying_spec.rb @@ -74,7 +74,7 @@ describe User::Querying, :type => :model do end it "does not pull back hidden posts" do - @status.share_visibilities.where(user_id: alice.id).first.update_attributes(hidden: true) + @status.share_visibilities.where(user_id: alice.id).first.update(hidden: true) expect(alice.visible_shareable_ids(Post).include?(@status.id)).to be false end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 6a41d3472..6b026300b 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -302,8 +302,8 @@ describe User, :type => :model do end it "resets a matching unconfirmed_email and confirm_email_token on save" do - eve.update_attributes(unconfirmed_email: "new@example.com", confirm_email_token: SecureRandom.hex(15)) - alice.update_attribute(:email, "new@example.com") + eve.update(unconfirmed_email: "new@example.com", confirm_email_token: SecureRandom.hex(15)) + alice.update(email: "new@example.com") eve.reload expect(eve.unconfirmed_email).to eql(nil) expect(eve.confirm_email_token).to eql(nil) diff --git a/spec/presenters/node_info_presenter_spec.rb b/spec/presenters/node_info_presenter_spec.rb index 8929213b0..82e9328e8 100644 --- a/spec/presenters/node_info_presenter_spec.rb +++ b/spec/presenters/node_info_presenter_spec.rb @@ -183,5 +183,37 @@ describe NodeInfoPresenter do ) end end + + context "version 2.1" do + it "provides generic pod data in json" do + expect(NodeInfoPresenter.new("2.1").as_json.as_json).to eq( + "version" => "2.1", + "software" => { + "name" => "diaspora", + "version" => AppConfig.version_string, + "repository" => "https://github.com/diaspora/diaspora", + "homepage" => "https://diasporafoundation.org/" + }, + "protocols" => ["diaspora"], + "services" => { + "inbound" => [], + "outbound" => AppConfig.configured_services.map(&:to_s) + }, + "openRegistrations" => AppConfig.settings.enable_registrations?, + "usage" => { + "users" => {} + }, + "metadata" => { + "nodeName" => AppConfig.settings.pod_name, + "xmppChat" => AppConfig.chat.enabled?, + "camo" => { + "markdown" => AppConfig.privacy.camo.proxy_markdown_images?, + "opengraph" => AppConfig.privacy.camo.proxy_opengraph_thumbnails?, + "remotePods" => AppConfig.privacy.camo.proxy_remote_pod_images? + } + } + ) + end + end end end diff --git a/spec/shared_behaviors/dispatcher.rb b/spec/shared_behaviors/dispatcher.rb index 2b42dec00..c99e66228 100644 --- a/spec/shared_behaviors/dispatcher.rb +++ b/spec/shared_behaviors/dispatcher.rb @@ -17,7 +17,7 @@ shared_examples "a dispatcher" do it "delivers a Retraction of a Post to specified services" do opts = {service_types: "Services::Twitter", tweet_id: "123"} - expect(Workers::DeletePostFromService).to receive(:perform_async).with(twitter.id, opts) + expect(Workers::DeletePostFromService).to receive(:perform_async).with(twitter.id, opts.deep_stringify_keys) retraction = Retraction.for(post) Diaspora::Federation::Dispatcher.build(alice, retraction, opts).dispatch diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0fe4e1097..3cbdbaff0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -133,9 +133,6 @@ RSpec.configure do |config| config.include FactoryGirl::Syntax::Methods - config.include JSON::SchemaMatchers - config.json_schemas[:archive_schema] = "lib/schemas/archive-format.json" - JSON::Validator.add_schema( JSON::Schema.new( DiasporaFederation::Schemas.federation_entities, diff --git a/spec/support/user_methods.rb b/spec/support/user_methods.rb index 7e37e1251..01802dcc8 100644 --- a/spec/support/user_methods.rb +++ b/spec/support/user_methods.rb @@ -26,12 +26,7 @@ class User p.aspects = aspects if p.save! self.aspects.reload - - dispatch_opts = { - url: Rails.application.routes.url_helpers.post_url(p, host: AppConfig.pod_uri.to_s), - to: opts[:to] - } - dispatch_post(p, dispatch_opts) + dispatch_post(p, url: Rails.application.routes.url_helpers.post_url(p, host: AppConfig.pod_uri.to_s)) end unless opts[:created_at] p.created_at = Time.now - 1 diff --git a/spec/views/status_messages/_status_message.mobile.haml_spec.rb b/spec/views/status_messages/_status_message.mobile.haml_spec.rb index 5487d6a55..d3bbe06b6 100644 --- a/spec/views/status_messages/_status_message.mobile.haml_spec.rb +++ b/spec/views/status_messages/_status_message.mobile.haml_spec.rb @@ -10,8 +10,9 @@ describe "status_messages/_status_message.mobile.haml" do ) post = FactoryGirl.create(:status_message, public: true, open_graph_cache: open_graph_cache) - render file: "status_messages/_status_message.mobile.haml", locals: {post: post, photos: post.photos} + render template: "status_messages/_status_message", locals: {post: post, photos: post.photos} expect(rendered).to_not include("<script>") + expect(rendered).to include("<script>alert(0);</script>") end end diff --git a/spec/workers/check_birthday_spec.rb b/spec/workers/check_birthday_spec.rb index 594be68f0..1f026ab61 100644 --- a/spec/workers/check_birthday_spec.rb +++ b/spec/workers/check_birthday_spec.rb @@ -7,7 +7,7 @@ describe Workers::CheckBirthday do before do Timecop.freeze(Time.zone.local(1999, 9, 9)) - birthday_profile.update_attributes(birthday: "1990-09-09") + birthday_profile.update(birthday: "1990-09-09") allow(Notifications::ContactsBirthday).to receive(:notify) end @@ -22,13 +22,13 @@ describe Workers::CheckBirthday do end it "does nothing if the birthday does not exist" do - birthday_profile.update_attributes(birthday: nil) + birthday_profile.update(birthday: nil) Workers::CheckBirthday.new.perform expect(Notifications::ContactsBirthday).not_to have_received(:notify) end it "does nothing if the person's birthday is not today" do - birthday_profile.update_attributes(birthday: "1988-04-15") + birthday_profile.update(birthday: "1988-04-15") Workers::CheckBirthday.new.perform expect(Notifications::ContactsBirthday).not_to have_received(:notify) end @@ -41,14 +41,14 @@ describe Workers::CheckBirthday do end it "does not call notify method if a contact user is not :receiving from the birthday person" do - contact2.update_attributes(receiving: false) + contact2.update(receiving: false) Workers::CheckBirthday.new.perform expect(Notifications::ContactsBirthday).to have_received(:notify).with(contact1, []) expect(Notifications::ContactsBirthday).not_to have_received(:notify).with(contact2, []) end it "does not call notify method if a birthday person is not :sharing with the contact user" do - contact2.update_attributes(sharing: false) + contact2.update(sharing: false) Workers::CheckBirthday.new.perform expect(Notifications::ContactsBirthday).to have_received(:notify).with(contact1, []) expect(Notifications::ContactsBirthday).not_to have_received(:notify).with(contact2, []) diff --git a/spec/workers/reset_password_spec.rb b/spec/workers/reset_password_spec.rb index 6d1b7ca72..59c5cca79 100644 --- a/spec/workers/reset_password_spec.rb +++ b/spec/workers/reset_password_spec.rb @@ -12,8 +12,8 @@ describe Workers::ResetPassword do Workers::ResetPassword.new.perform(alice.id) mail = Devise.mailer.deliveries.last expect(mail.to).to eq([alice.email]) - expect(mail.body).to include("change your password") - expect(mail.body).to include(alice.username) + expect(mail.body.encoded).to include("change your password") + expect(mail.body.encoded).to include(alice.username) end end end diff --git a/vendor/assets/entypo/LICENSE_ENTYPO b/vendor/assets/entypo/LICENSE_ENTYPO new file mode 100644 index 000000000..bf6eca68e --- /dev/null +++ b/vendor/assets/entypo/LICENSE_ENTYPO @@ -0,0 +1,95 @@ +Copyright (c) Daniel Bruce (<http://www.entypo.com/>), +with Reserved Font Name <Entypo> and <Entypo Social>. + +This Font Software located at app/assets/fonts is licensed under the +SIL Open Font License, Version 1.1. This license is copied below, and +is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/vendor/assets/entypo/entypo.scss b/vendor/assets/entypo/entypo.scss new file mode 100644 index 000000000..22068e893 --- /dev/null +++ b/vendor/assets/entypo/entypo.scss @@ -0,0 +1,311 @@ +@charset "UTF-8"; + +@font-face { + font-family: 'entypo'; + src: asset-url('entypo.woff') format('woff'); + font-weight: normal; font-style: normal; +} + +[class^="entypo-"], [class*=" entypo-"] { + font-family: entypo; + font-style: normal; + font-weight: normal; + display: inline-block; + width: 1.1em; + margin-right: .1em; + text-align: center; + -webkit-font-smoothing: antialiased; +} + +/* main icon map */ +.entypo-phone:before { content: '\1f4de'; } /* 1f4de */ +.entypo-mobile:before { content: '\1f4f1'; } /* 1f4f1 */ +.entypo-mouse:before { content: '\e789'; } /* e789 */ +.entypo-address:before { content: '\e723'; } /* e723 */ +.entypo-mail:before { content: '\2709'; } /* 2709 */ +.entypo-paper-plane:before { content: '\e79b'; } /* e79b */ +.entypo-pencil:before { content: '\270e'; } /* 270e */ +.entypo-feather:before { content: '\2712'; } /* 2712 */ +.entypo-attach:before { content: '\1f4ce'; } /* 1f4ce */ +.entypo-inbox:before { content: '\e777'; } /* e777 */ +.entypo-reply:before { content: '\e712'; } /* e712 */ +.entypo-reply-all:before { content: '\e713'; } /* e713 */ +.entypo-forward:before { content: '\27a6'; } /* 27a6 */ +.entypo-user:before { content: '\1f464'; } /* 1f464 */ +.entypo-users:before { content: '\1f465'; } /* 1f465 */ +.entypo-add-user:before { content: '\e700'; } /* e700 */ +.entypo-vcard:before { content: '\e722'; } /* e722 */ +.entypo-export:before { content: '\e715'; } /* e715 */ +.entypo-location:before { content: '\e724'; } /* e724 */ +.entypo-map:before { content: '\e727'; } /* e727 */ +.entypo-compass:before { content: '\e728'; } /* e728 */ +.entypo-direction:before { content: '\27a2'; } /* 27a2 */ +.entypo-share:before { content: '\e73c'; } /* e73c */ +.entypo-shareable:before { content: '\e73e'; } /* e73e */ +.entypo-heart:before { content: '\2665'; } /* 2665 */ +.entypo-heart-empty:before { content: '\2661'; } /* 2661 */ +.entypo-star:before { content: '\2605'; } /* 2605 */ +.entypo-star-empty:before { content: '\2606'; } /* 2606 */ +.entypo-thumbs-up:before { content: '\1f44d'; } /* 1f44d */ +.entypo-thumbs-down:before { content: '\1f44e'; } /* 1f44e */ +.entypo-chat:before { content: '\e720'; } /* e720 */ +.entypo-comment:before { content: '\e718'; } /* e718 */ +.entypo-quote:before { content: '\275e'; } /* 275e */ +.entypo-home:before { content: '\2302'; } /* 2302 */ +.entypo-popup:before { content: '\e74c'; } /* e74c */ +.entypo-search:before { content: '\1f50d'; } /* 1f50d */ +.entypo-flashlight:before { content: '\1f526'; } /* 1f526 */ +.entypo-print:before { content: '\e716'; } /* e716 */ +.entypo-bell:before { content: '\1f514'; } /* 1f514 */ +.entypo-link:before { content: '\1f517'; } /* 1f517 */ +.entypo-flag:before { content: '\2691'; } /* 2691 */ +.entypo-cog:before { content: '\2699'; } /* 2699 */ +.entypo-tools:before { content: '\2692'; } /* 2692 */ +.entypo-trophy:before { content: '\1f3c6'; } /* 1f3c6 */ +.entypo-tag:before { content: '\e70c'; } /* e70c */ +.entypo-camera:before { content: '\1f4f7'; } /* 1f4f7 */ +.entypo-megaphone:before { content: '\1f4e3'; } /* 1f4e3 */ +.entypo-moon:before { content: '\263d'; } /* 263d */ +.entypo-palette:before { content: '\1f3a8'; } /* 1f3a8 */ +.entypo-leaf:before { content: '\1f342 '; } /* 1f342 */ +.entypo-note:before { content: '\266a'; } /* 266a */ +.entypo-beamed-note:before { content: '\266b'; } /* 266b */ +.entypo-graduation-cap:before { content: '\1f393 '; } /* 1f393 */ +.entypo-book:before { content: '\1f4d5 '; } /* 1f4d5 */ +.entypo-newspaper:before { content: '\1f4f0'; } /* 1f4f0 */ +.entypo-bag:before { content: '\1f45c'; } /* 1f45c */ +.entypo-lifebuoy:before { content: '\e788'; } /* e788 */ +.entypo-eye:before { content: '\e70a'; } /* e70a */ +.entypo-clock:before { content: '\1f554'; } /* 1f554 */ +.entypo-mic:before { content: '\1f3a4'; } /* 1f3a4 */ +.entypo-calendar:before { content: '\1f4c5'; } /* 1f4c5 */ +.entypo-flash:before { content: '\26a1'; } /* 26a1 */ +.entypo-thunder-cloud:before { content: '\26c8'; } /* 26c8 */ +.entypo-droplet:before { content: '\1f4a7'; } /* 1f4a7 */ +.entypo-cd:before { content: '\1f4bf'; } /* 1f4bf */ +.entypo-briefcase:before { content: '\1f4bc'; } /* 1f4bc */ +.entypo-air:before { content: '\e753'; } /* e753 */ +.entypo-hourglass:before { content: '\23f3'; } /* 23f3 */ +.entypo-gauge:before { content: '\e7a2'; } /* e7a2 */ +.entypo-language:before { content: '\e752'; } /* e752 */ +.entypo-network:before { content: '\e776'; } /* e776 */ +.entypo-key:before { content: '\1f511'; } /* 1f511 */ +.entypo-battery:before { content: '\1f50b'; } /* 1f50b */ +.entypo-bucket:before { content: '\e756'; } /* e756 */ +.entypo-magnet:before { content: '\e7a1'; } /* e7a1 */ +.entypo-drive:before { content: '\e755'; } /* e755 */ +.entypo-cup:before { content: '\2615'; } /* 2615 */ +.entypo-rocket:before { content: '\1f680'; } /* 1f680 */ +.entypo-brush:before { content: '\e79a'; } /* e79a */ +.entypo-suitcase:before { content: '\e78e'; } /* e78e */ +.entypo-traffic-cone:before { content: '\e7a3'; } /* e7a3 */ +.entypo-globe:before { content: '\1f30e'; } /* 1f30e */ +.entypo-keyboard:before { content: '\2328'; } /* 2328 */ +.entypo-publish:before { content: '\e74d'; } /* e74d */ +.entypo-progress-3:before { content: '\e76b'; } /* e76b */ +.entypo-progress-2:before { content: '\e76a'; } /* e76a */ +.entypo-progress-1:before { content: '\e769'; } /* e769 */ +.entypo-progress-0:before { content: '\e768'; } /* e768 */ +.entypo-light-down:before { content: '\1f505'; } /* 1f505' */ +.entypo-light-up:before { content: '\1f506'; } /* 1f506 */ +.entypo-adjust:before { content: '\25d1'; } /* 25d1 */ +.entypo-code:before { content: '\e714'; } /* e714 */ +.entypo-monitor:before { content: '\1f4bb'; } /* 1f4bb */ +.entypo-infinity:before { content: '\221e'; } /* 221e */ +.entypo-credit-card:before { content: '\1f4b3'; } /* 1f4b3 */ +.entypo-database:before { content: '\e754'; } /* e754 */ +.entypo-clipboard:before { content: '\1f4cb'; } /* 1f4cb */ +.entypo-box:before { content: '\1f4e6'; } /* 1f4e6 */ +.entypo-ticket:before { content: '\1f3ab'; } /* 1f3ab */ +.entypo-rss:before { content: '\e73a'; } /* e73a */ +.entypo-signal:before { content: '\1f4f6'; } /* 1f4f6 */ +.entypo-thermometer:before { content: '\e757'; } /* e757 */ +.entypo-water:before { content: '\1f4a6'; } /* 1f4a6 */ +.entypo-sweden:before { content: '\f601'; } /* f601 */ +.entypo-lock:before { content: '\1f512'; } /* 1f512 */ +.entypo-lock-open:before { content: '\1f513'; } /* 1f513 */ +.entypo-logout:before { content: '\e741'; } /* e741 */ +.entypo-login:before { content: '\e740'; } /* e740 */ +.entypo-check:before { content: '\2713'; } /* 2713 */ +.entypo-squared-plus:before { content: '\229e'; } /* 229e */ +.entypo-squared-minus:before { content: '\229f'; } /* 229f */ +.entypo-circled-plus:before { content: '\2795'; } /* 2795 */ +.entypo-circled-minus:before { content: '\2796'; } /* 2796 */ +.entypo-plus:before { content: '\2b'; } /* 2b */ +.entypo-minus:before { content: '\2d'; } /* 2d */ +.entypo-erase:before { content: '\232b'; } /* 232b */ +.entypo-block:before { content: '\1f6ab'; } /* 1f6ab */ +.entypo-info:before { content: '\2139'; } /* 2139 */ +.entypo-circled-info:before { content: '\e705'; } /* e705 */ +.entypo-help:before { content: '\2753'; } /* 2753 */ +.entypo-circled-help:before { content: '\e704'; } /* e704 */ +.entypo-ccw:before { content: '\27f2'; } /* 27f2 */ +.entypo-cw:before { content: '\27f3'; } /* 27f3 */ +.entypo-shuffle:before { content: '\1f500'; } /* 1f500 */ +.entypo-back:before { content: '\1f519'; } /* 1f519 */ +.entypo-level-up:before { content: '\21b0'; } /* 21b0 */ +.entypo-level-down:before { content: '\21b3'; } /* 21b3 */ +.entypo-retweet:before { content: '\e717'; } /* e717 */ +.entypo-reshare:before { content: '\e717'; } /* e717 */ +.entypo-loop:before { content: '\1f501'; } /* 1f501 */ +.entypo-back-in-time:before { content: '\e771'; } /* e771 */ +.entypo-switch:before { content: '\21c6'; } /* 21c6 */ +.entypo-layout:before { content: '\268f'; } /* 268f */ +.entypo-list:before { content: '\2630'; } /* 2630 */ +.entypo-doc:before { content: '\e730'; } /* e730 */ +.entypo-docs:before { content: '\e736'; } /* e736 */ +.entypo-text-doc-inverted:before { content: '\e731'; } /* e731 */ +.entypo-landscape-doc:before { content: '\e737'; } /* e737 */ +.entypo-picture:before { content: '\1f304'; } /* 1f304 */ +.entypo-video:before { content: '\1f3ac'; } /* 1f3ac */ +.entypo-music:before { content: '\1f3b5'; } /* 1f3b5 */ +.entypo-folder:before { content: '\1f4c1 '; } /* 1f4c1 */ +.entypo-archive:before { content: '\e738'; } /* e738 */ +.entypo-trash:before { content: '\e729'; } /* e729 */ +.entypo-upload:before { content: '\1f4e4'; } /* 1f4e4 */ +.entypo-download:before { content: '\1f4e5'; } /* 1f4e5 */ +.entypo-install:before { content: '\e778'; } /* e778 */ +.entypo-cloud:before { content: '\2601'; } /* 2601 */ +.entypo-upload-cloud:before { content: '\e711'; } /* e711 */ +.entypo-bookmark:before { content: '\1f516'; } /* 1f516 */ +.entypo-bookmarks:before { content: '\1f4d1'; } /* 1f4d1 */ +.entypo-play:before { content: '\25b6'; } /* 25b6 */ +.entypo-paus:before { content: '\2389'; } /* 2389 */ +.entypo-record:before { content: '\26ab'; } /* 26ab */ +.entypo-stop:before { content: '\25a0'; } /* 25a0 */ +.entypo-to-end:before { content: '\23ed'; } /* 23ed */ +.entypo-to-start:before { content: '\23ee'; } /* 23ee */ +.entypo-resize-full:before { content: '\e744'; } /* e744 */ +.entypo-resize-small:before { content: '\e746'; } /* e746 */ +.entypo-volume:before { content: '\e742'; } /* e742 */ +.entypo-sound:before { content: '\1f50a'; } /* 1f50a */ +.entypo-mute:before { content: '\1f507'; } /* 1f507 */ +.entypo-flow-cascade:before { content: '\e790'; } /* e790 */ +.entypo-flow-branch:before { content: '\e791'; } /* e791 */ +.entypo-flow-tree:before { content: '\e792'; } /* e792 */ +.entypo-flow-line:before { content: '\e793'; } /* e793 */ +.entypo-flow-parallel:before { content: '\e794'; } /* e794 */ +.entypo-left-bold:before { content: '\e4ad'; } /* e4ad */ +.entypo-right-bold:before { content: '\e4ae'; } /* e4ae */ +.entypo-up-bold:before { content: '\e4af'; } /* e4af */ +.entypo-down-bold:before { content: '\e4b0'; } /* e4b0 */ +.entypo-left:before { content: '\261c'; } /* 261c */ +.entypo-up:before { content: '\261d'; } /* 261d */ +.entypo-right:before { content: '\261e'; } /* 261e */ +.entypo-down:before { content: '\261f'; } /* 261f */ +.entypo-circled-down:before { content: '\e758'; } /* e758 */ +.entypo-circled-left:before { content: '\e759'; } /* e759 */ +.entypo-circled-right:before { content: '\e75a'; } /* e75a */ +.entypo-circled-up:before { content: '\e75b'; } /* e75b */ +.entypo-left-thin:before { content: '\2190'; } /* 2190 */ +.entypo-up-thin:before { content: '\2191'; } /* 2191 */ +.entypo-right-thin:before { content: '\2192'; } /* 2192 */ +.entypo-down-thin:before { content: '\2193'; } /* 2193 */ +.entypo-arrow-combo:before { content: '\e74f'; } /* e74f */ +.entypo-dot:before { content: '\e78b'; } /* e78b */ +.entypo-two-dots:before { content: '\e78c'; } /* e78c */ +.entypo-three-dots:before { content: '\e78d'; } /* e78d */ +.entypo-cc:before { content: '\e7a5'; } /* e7a5 */ +.entypo-cc-by:before { content: '\e7a6'; } /* e7a6 */ +.entypo-cc-nc:before { content: '\e7a7'; } /* e7a7 */ +.entypo-cc-nc-eu:before { content: '\e7a8'; } /* e7a8 */ +.entypo-cc-nc-jp:before { content: '\e7a9'; } /* e7a9 */ +.entypo-cc-sa:before { content: '\e7aa'; } /* e7aa */ +.entypo-cc-nd:before { content: '\e7ab'; } /* e7ab */ +.entypo-cc-pd:before { content: '\e7ac'; } /* e7ac */ +.entypo-cc-zero:before { content: '\e7ad'; } /* e7ad */ +.entypo-cc-share:before { content: '\e7ae'; } /* e7ae */ +.entypo-cc-remix:before { content: '\e7af'; } /* e7af */ +.entypo-db-logo:before { content: '\f603'; } /* f603 */ +.entypo-db-shape:before { content: '\f600'; } /* f600 */ +.entypo-save:before { content: '\1f4be'; } /* 1f4be */ +.entypo-ff:before { content: '\23e9'; } /* 23e9 */ +.entypo-fb:before { content: '\23ea'; } /* 23ea */ +.entypo-pie-chart:before { content: '\e751'; } /* e751 */ +.entypo-line-graph:before { content: '\1f4c8'; } /* 1f4c8 */ +.entypo-bar-graph:before { content: '\1f4ca '; } /* 1f4ca */ +.entypo-area-graph:before { content: '\1f53e'; } /* 1f53e */ +.entypo-chevron-down:before { content: '\e75c'; } /* e75c */ +.entypo-chevron-left:before { content: '\e75d'; } /* e75d */ +.entypo-chevron-right:before { content: '\e75e'; } /* e75e */ +.entypo-chevron-up:before { content: '\e75f'; } /* e75f */ +.entypo-chevron-small-down:before { content: '\e760'; } /* e760 */ +.entypo-chevron-small-left:before { content: '\e761'; } /* e761 */ +.entypo-chevron-small-right:before { content: '\e762'; } /* e762 */ +.entypo-chevron-small-up:before { content: '\e763'; } /* e763 */ +.entypo-chevron-thin-down:before { content: '\e764'; } /* e764 */ +.entypo-chevron-thin-left:before { content: '\e765'; } /* e765 */ +.entypo-chevron-thin-right:before { content: '\e766'; } /* e766 */ +.entypo-chevron-thin-up:before { content: '\e767'; } /* e767 */ +.entypo-text-doc:before { content: '\1f4c4'; } /* 1f4c4 */ +.entypo-open-book:before { content: '\1f4d6'; } /* 1f4d6 */ +.entypo-voicemail:before { content: '\2707'; } /* 2707 */ +.entypo-triangle-right:before { content: '\25b8'; } /* 25b8 */ +.entypo-triangle-up:before { content: '\25b4'; } /* 25b4 */ +.entypo-triangle-down:before { content: '\25be'; } /* 25be */ +.entypo-triangle-left:before { content: '\25c2'; } /* 25c2 */ +.entypo-airplane:before { content: '\2708'; } /* 2708 */ +.entypo-light-bulb:before { content: '\1f4a1'; } /* 1f4a1 */ +.entypo-add-to-list:before { content: '\e003'; } /* e003 */ +.entypo-browser:before { content: '\e74e'; } /* e74e */ +.entypo-cart:before { content: '\e73d'; } /* e73d */ +.entypo-cross-hair:before { content: '\1f3af'; } /* 1f3af */ +.entypo-squared-cross:before { content: '\274e'; } /* 274e */ +.entypo-circled-cross:before { content: '\2716'; } /* 2716 */ +.entypo-warning:before { content: '\26a0'; } /* 26a0 */ +.entypo-cross:before { content: '\2715'; } /* 2715 */ +.entypo-new:before { content: '\1f4a5'; } /* 1f4a5 */ +.entypo-cycle:before { content: '\1f504'; } /* 1f504 */ +.entypo-numbered-list:before { content: '\e005'; } /* e005 */ +.entypo-right-1:before { content: '\27a1'; } /* 27a1 */ +.entypo-left-1:before { content: '\2b05'; } /* 2b05 */ +.entypo-up-1:before { content: '\2b06'; } /* 2b06 */ +.entypo-down-1:before { content: '\2b07'; } /* 2b07 */ + +/* social extension map */ +.entypo-social-github:before { content: '\f300'; } /* f300 */ +.entypo-social-social-c-github:before { content: '\f301'; } /* f301 */ +.entypo-social-flickr:before { content: '\f303'; } /* f303 */ +.entypo-social-c-flickr:before { content: '\f304'; } /* f304 */ +.entypo-social-vimeo:before { content: '\f306'; } /* f306 */ +.entypo-social-c-vimeo:before { content: '\f307'; } /* f307 */ +.entypo-social-twitter:before { content: '\f309'; } /* f309 */ +.entypo-social-c-twitter:before { content: '\f30a'; } /* f30a */ +.entypo-social-facebook:before { content: '\f30c'; } /* f30c */ +.entypo-social-c-facebook:before { content: '\f30d'; } /* f30d */ +.entypo-social-s-facebook:before { content: '\f30e'; } /* f30e */ +.entypo-social-google-plus:before { content: '\f30f'; } /* f30f */ +.entypo-social-c-google-plus:before { content: '\f310'; } /* f310 */ +.entypo-social-pinterest:before { content: '\f312'; } /* f312 */ +.entypo-social-c-pinterest:before { content: '\f313'; } /* f313 */ +.entypo-social-tumblr:before { content: '\f315'; } /* f315 */ +.entypo-social-c-tumblr:before { content: '\f316'; } /* f316 */ +.entypo-social-linkedin:before { content: '\f318'; } /* f318 */ +.entypo-social-c-linkedin:before { content: '\f319'; } /* f319 */ +.entypo-social-dribbble:before { content: '\f31b'; } /* f31b */ +.entypo-social-c-dribbble:before { content: '\f31c'; } /* f31c */ +.entypo-social-stumbleupon:before { content: '\f31e'; } /* f31e */ +.entypo-social-c-stumbleupon:before { content: '\f31f'; } /* f31f */ +.entypo-social-lastfm:before { content: '\f321'; } /* f321 */ +.entypo-social-c-lastfm:before { content: '\f322'; } /* f322 */ +.entypo-social-rdio:before { content: '\f324'; } /* f324 */ +.entypo-social-c-rdio:before { content: '\f325'; } /* f325 */ +.entypo-social-spotify:before { content: '\f327'; } /* f327 */ +.entypo-social-c-spotify:before { content: '\f328'; } /* f328 */ +.entypo-social-qq:before { content: '\f32a'; } /* f32a */ +.entypo-social-instagram:before { content: '\f32d'; } /* f32d */ +.entypo-social-dropbox:before { content: '\f330'; } /* f330 */ +.entypo-social-evernote:before { content: '\f333'; } /* f333 */ +.entypo-social-flattr:before { content: '\f336'; } /* f336 */ +.entypo-social-skype:before { content: '\f339'; } /* f339 */ +.entypo-social-c-skype:before { content: '\f33a'; } /* f33a */ +.entypo-social-renren:before { content: '\f33c'; } /* f33c */ +.entypo-social-sina-weibo:before { content: '\f33f'; } /* f33f */ +.entypo-social-paypal:before { content: '\f342'; } /* f342 */ +.entypo-social-picasa:before { content: '\f345'; } /* f345 */ +.entypo-social-soundcloud:before { content: '\f348'; } /* f348 */ +.entypo-social-mixi:before { content: '\f34b'; } /* f34b */ +.entypo-social-behance:before { content: '\f34e'; } /* f34e */ +.entypo-social-google-circles:before { content: '\f351'; } /* f351 */ +.entypo-social-vk:before { content: '\f354'; } /* f354 */ +.entypo-social-smashing:before { content: '\f357'; } /* f357 */ diff --git a/vendor/assets/entypo/entypo.woff b/vendor/assets/entypo/entypo.woff Binary files differnew file mode 100644 index 000000000..06f663814 --- /dev/null +++ b/vendor/assets/entypo/entypo.woff diff --git a/vendor/nodeinfo/schemas/2.0.json b/vendor/nodeinfo/schemas/2.0.json index ddaca625e..da56bed13 100644 --- a/vendor/nodeinfo/schemas/2.0.json +++ b/vendor/nodeinfo/schemas/2.0.json @@ -1,5 +1,3 @@ - - { "$schema": "http://json-schema.org/draft-04/schema#", "id": "http://nodeinfo.diaspora.software/ns/schema/2.0#", diff --git a/vendor/nodeinfo/schemas/2.1.json b/vendor/nodeinfo/schemas/2.1.json new file mode 100644 index 000000000..561e64479 --- /dev/null +++ b/vendor/nodeinfo/schemas/2.1.json @@ -0,0 +1,188 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "http://nodeinfo.diaspora.software/ns/schema/2.1#", + "description": "NodeInfo schema version 2.1.", + "type": "object", + "additionalProperties": false, + "required": [ + "version", + "software", + "protocols", + "services", + "openRegistrations", + "usage", + "metadata" + ], + "properties": { + "version": { + "description": "The schema version, must be 2.1.", + "enum": [ + "2.1" + ] + }, + "software": { + "description": "Metadata about server software in use.", + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "description": "The canonical name of this server software.", + "type": "string", + "pattern": "^[a-z0-9-]+$" + }, + "version": { + "description": "The version of this server software.", + "type": "string" + }, + "repository": { + "description": "The url of the source code repository of this server software.", + "type": "string" + }, + "homepage": { + "description": "The url of the homepage of this server software.", + "type": "string" + } + } + }, + "protocols": { + "description": "The protocols supported on this server.", + "type": "array", + "minItems": 1, + "items": { + "enum": [ + "activitypub", + "buddycloud", + "dfrn", + "diaspora", + "libertree", + "ostatus", + "pumpio", + "tent", + "xmpp", + "zot" + ] + } + }, + "services": { + "description": "The third party sites this server can connect to via their application API.", + "type": "object", + "additionalProperties": false, + "required": [ + "inbound", + "outbound" + ], + "properties": { + "inbound": { + "description": "The third party sites this server can retrieve messages from for combined display with regular traffic.", + "type": "array", + "minItems": 0, + "items": { + "enum": [ + "atom1.0", + "gnusocial", + "imap", + "pnut", + "pop3", + "pumpio", + "rss2.0", + "twitter" + ] + } + }, + "outbound": { + "description": "The third party sites this server can publish messages to on the behalf of a user.", + "type": "array", + "minItems": 0, + "items": { + "enum": [ + "atom1.0", + "blogger", + "buddycloud", + "diaspora", + "dreamwidth", + "drupal", + "facebook", + "friendica", + "gnusocial", + "google", + "insanejournal", + "libertree", + "linkedin", + "livejournal", + "mediagoblin", + "myspace", + "pinterest", + "pnut", + "posterous", + "pumpio", + "redmatrix", + "rss2.0", + "smtp", + "tent", + "tumblr", + "twitter", + "wordpress", + "xmpp" + ] + } + } + } + }, + "openRegistrations": { + "description": "Whether this server allows open self-registration.", + "type": "boolean" + }, + "usage": { + "description": "Usage statistics for this server.", + "type": "object", + "additionalProperties": false, + "required": [ + "users" + ], + "properties": { + "users": { + "description": "statistics about the users of this server.", + "type": "object", + "additionalProperties": false, + "properties": { + "total": { + "description": "The total amount of on this server registered users.", + "type": "integer", + "minimum": 0 + }, + "activeHalfyear": { + "description": "The amount of users that signed in at least once in the last 180 days.", + "type": "integer", + "minimum": 0 + }, + "activeMonth": { + "description": "The amount of users that signed in at least once in the last 30 days.", + "type": "integer", + "minimum": 0 + } + } + }, + "localPosts": { + "description": "The amount of posts that were made by users that are registered on this server.", + "type": "integer", + "minimum": 0 + }, + "localComments": { + "description": "The amount of comments that were made by users that are registered on this server.", + "type": "integer", + "minimum": 0 + } + } + }, + "metadata": { + "description": "Free form key value pairs for software specific values. Clients should not rely on any specific key present.", + "type": "object", + "minProperties": 0, + "additionalProperties": true + } + } +} |