Merge branch 'release/0.5.6.0'

This commit is contained in:
Dennis Schubert 2016-01-13 23:09:27 +01:00
commit 5aef0441e8
46 changed files with 2237 additions and 966 deletions

View file

@ -1,8 +1,14 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all people who
contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
@ -10,13 +16,35 @@ Examples of unacceptable behavior by participants include:
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
* Other unethical or unprofessional conduct.
* Publishing other's private information, such as physical or electronic
addresses, without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
By adopting this Code of Conduct, project maintainers commit themselves to
fairly and consistently applying these principles to every aspect of managing
this project. Project maintainers who do not follow or enforce the Code of
Conduct may be permanently removed from the project team.
Instances of abusive, harassing, or otherwise unacceptable behavior should be reported by sending an email to [team@diasporafoundation.org](mailto:team@diasporafoundation.org).
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting a project maintainer at [team@diasporafoundation.org](mailto:team@diasporafoundation.org). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. Maintainers are
obligated to maintain confidentiality with regard to the reporter of an
incident.
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.3.0, available at
[http://contributor-covenant.org/version/1/3/0/][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/3/0/

View file

@ -1,3 +1,19 @@
# 0.5.6.0
## Refactor
* Add more integration tests with the help of the new diaspora-federation gem [#6539](https://github.com/diaspora/diaspora/pull/6539)
## Bug fixes
* Fix mention autocomplete when pasting the username [#6510](https://github.com/diaspora/diaspora/pull/6510)
* Use and update updated\_at for notifications [#6573](https://github.com/diaspora/diaspora/pull/6573)
* Ensure the author signature is checked when receiving a relayable [#6539](https://github.com/diaspora/diaspora/pull/6539)
* Do not try to display hovercards when logged out [#6587](https://github.com/diaspora/diaspora/pull/6587)
## Features
* Display hovercards without aspect dropdown when logged out [#6603](https://github.com/diaspora/diaspora/pull/6603)
* Add media.ccc.de as a trusted oEmbed endpoint
# 0.5.5.1
* Fix XSS on profile pages

58
Gemfile
View file

@ -4,25 +4,25 @@ gem "rails", "4.2.5"
# Legacy Rails features, remove me!
# responders (class level)
gem "responders", "2.1.0"
gem "responders", "2.1.1"
# Appserver
gem "unicorn", "4.9.0", require: false
gem "unicorn", "5.0.1", require: false
# Federation
gem "diaspora_federation-rails", "0.0.8"
gem "diaspora_federation-rails", "0.0.11"
# API and JSON
gem "acts_as_api", "0.4.2"
gem "json", "1.8.3"
gem "json-schema", "2.5.1"
gem "json-schema", "2.5.2"
# Authentication
gem "devise", "3.5.2"
gem "devise", "3.5.3"
gem "devise_lastseenable", "0.0.6"
gem "devise-token_authenticatable", "~> 0.4.0"
@ -56,21 +56,21 @@ gem "rack-cors", "0.4.0", require: "rack/cors"
gem "bootstrap-sass", "2.3.2.2"
gem "compass-rails", "2.0.5"
gem "sass-rails", "5.0.4"
gem "autoprefixer-rails", "6.0.3"
gem "autoprefixer-rails", "6.2.2"
# Database
ENV["DB"] ||= "mysql"
gem "mysql2", "0.3.20" if ENV["DB"] == "all" || ENV["DB"] == "mysql"
gem "pg", "0.18.3" if ENV["DB"] == "all" || ENV["DB"] == "postgres"
gem "pg", "0.18.4" if ENV["DB"] == "all" || ENV["DB"] == "postgres"
gem "activerecord-import", "0.10.0"
# File uploading
gem "carrierwave", "0.10.0"
gem "fog", "1.34.0"
gem "fog", "1.37.0"
gem "mini_magick", "4.3.6"
gem "remotipart", "1.2.1"
@ -84,11 +84,11 @@ gem "entypo-rails", "2.2.3"
# JavaScript
gem "backbone-on-rails", "1.2.0.0"
gem "handlebars_assets", "0.21.0"
gem "handlebars_assets", "0.22.0"
gem "jquery-rails", "4.0.5"
gem "jquery-ui-rails", "5.0.5"
gem "js_image_paths", "0.0.2"
gem "js-routes", "1.1.2"
gem "js-routes", "1.2.0"
source "https://rails-assets.org" do
gem "rails-assets-jquery", "1.11.2" # Should be kept in sync with jquery-rails
@ -100,14 +100,14 @@ source "https://rails-assets.org" do
gem "rails-assets-markdown-it--markdown-it-for-inline", "0.1.1"
gem "rails-assets-markdown-it-sub", "1.0.0"
gem "rails-assets-markdown-it-sup", "1.0.0"
gem "rails-assets-highlightjs", "8.9.1"
gem "rails-assets-highlightjs", "9.0.0"
# jQuery plugins
gem "rails-assets-jeresig--jquery.hotkeys", "0.2.0"
gem "rails-assets-jquery-placeholder", "2.1.3"
gem "rails-assets-jquery-placeholder", "2.3.1"
gem "rails-assets-jquery-textchange", "0.2.3"
gem "rails-assets-perfect-scrollbar", "0.6.7"
gem "rails-assets-perfect-scrollbar", "0.6.8"
gem "rails-assets-jakobmattsson--jquery-elastic", "1.6.11"
end
@ -117,7 +117,7 @@ gem "facebox-rails", "0.2.0"
gem "http_accept_language", "2.0.5"
gem "i18n-inflector-rails", "1.0.7"
gem "rails-i18n", "4.0.5"
gem "rails-i18n", "4.0.8"
# Mail
@ -127,17 +127,17 @@ gem "messagebus_ruby_api", "1.0.3"
# Parsing
gem "nokogiri", "1.6.7.1"
gem "redcarpet", "3.3.3"
gem "redcarpet", "3.3.4"
gem "twitter-text", "1.13.0"
gem "roxml", "3.1.6"
gem "ruby-oembed", "0.8.14"
gem "ruby-oembed", "0.9.0"
gem "open_graph_reader", "0.6.1"
# Services
gem "omniauth", "1.2.2"
gem "omniauth-facebook", "2.0.1"
gem "omniauth-tumblr", "1.1"
gem "omniauth", "1.3.1"
gem "omniauth-facebook", "3.0.0"
gem "omniauth-tumblr", "1.2"
gem "omniauth-twitter", "1.2.1"
gem "twitter", "5.15.0"
gem "omniauth-wordpress", "0.2.2"
@ -148,7 +148,7 @@ gem "active_model_serializers", "0.9.3"
# XMPP chat dependencies
gem "diaspora-vines", "~> 0.2.0.develop"
gem "rails-assets-diaspora_jsxc", "~> 0.1.4.alpha", "< 0.1.4.develop", source: "https://rails-assets.org"
gem "rails-assets-diaspora_jsxc", "~> 0.1.4", source: "https://rails-assets.org"
# Tags
@ -195,7 +195,7 @@ gem "minitest"
group :production do # we don"t install these on travis to speed up test runs
# Administration
gem "rails_admin", "0.7.0"
gem "rails_admin", "0.8.1"
# Analytics
@ -232,11 +232,11 @@ group :development do
# Linters
gem "jshintrb", "0.3.0"
gem "rubocop", "0.34.2"
gem "rubocop", "0.35.1"
# Preloading environment
gem "spring", "1.4.0"
gem "spring", "1.6.1"
gem "spring-commands-rspec", "1.0.4"
gem "spring-commands-cucumber", "1.0.1"
@ -246,7 +246,7 @@ group :development do
gem "pry-byebug"
# test coverage
gem "simplecov", "0.10.0", require: false
gem "simplecov", "0.11.1", require: false
end
group :test do
@ -255,7 +255,7 @@ group :test do
gem "fixture_builder", "0.4.1"
gem "fuubar", "2.0.0"
gem "rspec-instafail", "0.4.0", require: false
gem "test_after_commit", "0.4.1"
gem "test_after_commit", "0.4.2"
# Cucumber (integration tests)
@ -267,8 +267,10 @@ group :test do
gem "factory_girl_rails", "4.5.0"
gem "timecop", "0.8.0"
gem "webmock", "1.22.1", require: false
gem "shoulda-matchers", "3.0.0"
gem "webmock", "1.22.3", require: false
gem "shoulda-matchers", "3.0.1"
gem "diaspora_federation-test", "0.0.11"
end
group :development, :test do
@ -279,7 +281,7 @@ group :development, :test do
gem "cucumber-rails", "1.4.2", require: false
# Jasmine (client side application tests (JS))
gem "jasmine", "2.3.1"
gem "jasmine", "2.4.0"
gem "jasmine-jquery-rails", "2.0.3"
gem "rails-assets-jasmine-ajax", "3.2.0", source: "https://rails-assets.org"
gem "sinon-rails", "1.15.0"

View file

@ -54,10 +54,10 @@ GEM
activemodel
fog (>= 1.8.0)
unf
ast (2.0.0)
ast (2.2.0)
astrolabe (1.3.1)
parser (~> 2.2)
autoprefixer-rails (6.0.3)
autoprefixer-rails (6.2.2)
execjs
json
backbone-on-rails (1.2.0.0)
@ -70,8 +70,7 @@ GEM
sass (~> 3.2)
buftok (0.2.0)
builder (3.2.2)
byebug (4.0.5)
columnize (= 0.9.0)
byebug (8.2.1)
capybara (2.5.0)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
@ -88,18 +87,17 @@ GEM
celluloid-io (0.16.2)
celluloid (>= 0.16.0)
nio4r (>= 1.1.0)
childprocess (0.5.6)
childprocess (0.5.8)
ffi (~> 1.0, >= 1.0.11)
chunky_png (1.3.4)
chunky_png (1.3.5)
coderay (1.1.0)
coffee-rails (4.1.0)
coffee-rails (4.1.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
railties (>= 4.0.0, < 5.1.x)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.9.1.1)
columnize (0.9.0)
coffee-script-source (1.10.0)
compass (1.0.3)
chunky_png (~> 1.2)
compass-core (~> 1.0.2)
@ -118,7 +116,7 @@ GEM
sprockets (< 2.13)
configurate (0.3.1)
connection_pool (2.2.0)
crack (0.4.2)
crack (0.4.3)
safe_yaml (~> 1.0.0)
cucumber (1.3.20)
builder (>= 2.1.2)
@ -133,7 +131,7 @@ GEM
nokogiri (~> 1.5)
rails (>= 3, < 5)
database_cleaner (1.5.1)
devise (3.5.2)
devise (3.5.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@ -152,15 +150,18 @@ GEM
eventmachine (~> 1.0.8)
http_parser.rb (~> 0.6)
nokogiri (~> 1.6)
diaspora_federation (0.0.8)
faraday (~> 0.9.2)
diaspora_federation (0.0.11)
faraday (~> 0.9.0)
faraday_middleware (~> 0.10.0)
nokogiri (~> 1.6, >= 1.6.6)
nokogiri (~> 1.6, >= 1.6.7.1)
typhoeus (~> 0.7)
valid (~> 1.0)
diaspora_federation-rails (0.0.8)
diaspora_federation (= 0.0.8)
diaspora_federation-rails (0.0.11)
diaspora_federation (= 0.0.11)
rails (~> 4.2)
diaspora_federation-test (0.0.11)
diaspora_federation (= 0.0.11)
factory_girl (~> 4.5, >= 4.5.0)
diff-lcs (1.2.5)
docile (1.1.5)
domain_name (0.5.25)
@ -210,14 +211,15 @@ GEM
fixture_builder (0.4.1)
activerecord (>= 2)
activesupport (>= 2)
fog (1.34.0)
fog (1.37.0)
fog-aliyun (>= 0.1.0)
fog-atmos
fog-aws (>= 0.6.0)
fog-brightbox (~> 0.4)
fog-core (~> 1.32)
fog-dynect (~> 0.0.2)
fog-ecloud (~> 0.1)
fog-google (>= 0.0.2)
fog-google (<= 0.1.0)
fog-json
fog-local
fog-powerdns (>= 0.1.1)
@ -231,9 +233,15 @@ GEM
fog-terremark
fog-vmfusion
fog-voxel
fog-vsphere (>= 0.4.0)
fog-xenserver
fog-xml (~> 0.1.1)
ipaddress (~> 0.5)
nokogiri (~> 1.5, >= 1.5.11)
fog-aliyun (0.1.0)
fog-core (~> 1.27)
fog-json (~> 1.0)
ipaddress (~> 0.8)
xml-simple (~> 1.1)
fog-atmos (0.1.0)
fog-core
fog-xml
@ -242,17 +250,14 @@ GEM
fog-json (~> 1.0)
fog-xml (~> 0.1)
ipaddress (~> 0.8)
fog-brightbox (0.9.0)
fog-brightbox (0.10.1)
fog-core (~> 1.22)
fog-json
inflecto (~> 0.0.2)
fog-core (1.32.1)
fog-core (1.35.0)
builder
excon (~> 0.45)
formatador (~> 0.2)
mime-types
net-scp (~> 1.1)
net-ssh (>= 2.1.3)
fog-dynect (0.0.2)
fog-core
fog-json
@ -260,7 +265,7 @@ GEM
fog-ecloud (0.3.0)
fog-core
fog-xml
fog-google (0.1.1)
fog-google (0.1.0)
fog-core
fog-json
fog-xml
@ -285,13 +290,13 @@ GEM
fog-core
fog-json
fog-xml
fog-sakuracloud (1.3.3)
fog-sakuracloud (1.7.5)
fog-core
fog-json
fog-serverlove (0.1.2)
fog-core
fog-json
fog-softlayer (1.0.0)
fog-softlayer (1.0.2)
fog-core
fog-json
fog-storm_on_demand (0.1.1)
@ -306,10 +311,16 @@ GEM
fog-voxel (0.1.0)
fog-core
fog-xml
fog-vsphere (0.4.0)
fog-core
rbvmomi (~> 1.8)
fog-xenserver (0.2.2)
fog-core
fog-xml
fog-xml (0.1.2)
fog-core
nokogiri (~> 1.5, >= 1.5.11)
font-awesome-rails (4.4.0.0)
font-awesome-rails (4.5.0.0)
railties (>= 3.2, < 5.0)
formatador (0.2.5)
fuubar (2.0.0)
@ -350,13 +361,13 @@ GEM
rubocop (~> 0.20)
haml (4.0.7)
tilt
handlebars_assets (0.21.0)
handlebars_assets (0.22.0)
execjs (~> 2.0)
multi_json (~> 1.0)
sprockets (>= 2.0.0, < 4.0)
tilt (~> 1.2)
hashdiff (0.2.2)
hashie (3.4.2)
hashdiff (0.2.3)
hashie (3.4.3)
hike (1.2.3)
hiredis (0.5.2)
hitimes (1.2.3)
@ -380,12 +391,12 @@ GEM
ice_cube (0.11.1)
inflecto (0.0.2)
ipaddress (0.8.0)
jasmine (2.3.1)
jasmine-core (~> 2.3)
jasmine (2.4.0)
jasmine-core (~> 2.4)
phantomjs
rack (>= 1.2.1)
rake
jasmine-core (2.3.4)
jasmine-core (2.4.1)
jasmine-jquery-rails (2.0.3)
jquery-rails (4.0.5)
rails-dom-testing (~> 1.0)
@ -393,7 +404,7 @@ GEM
thor (>= 0.14, < 2.0)
jquery-ui-rails (5.0.5)
railties (>= 3.2.16)
js-routes (1.1.2)
js-routes (1.2.0)
railties (>= 3.2)
sprockets-rails
js_image_paths (0.0.2)
@ -403,14 +414,14 @@ GEM
multi_json (>= 1.3)
rake
json (1.8.3)
json-schema (2.5.1)
addressable (~> 2.3.7)
jwt (1.5.1)
json-schema (2.5.2)
addressable (~> 2.3.8)
jwt (1.5.2)
kaminari (0.16.3)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.10.0)
listen (3.0.3)
listen (3.0.5)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
little-plugger (1.1.4)
@ -431,10 +442,10 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
messagebus_ruby_api (1.0.3)
method_source (0.8.2)
mime-types (2.6.2)
mime-types (2.99)
mini_magick (4.3.6)
mini_portile2 (2.0.0)
minitest (5.8.2)
minitest (5.8.3)
mobile-fu (1.3.1)
rack-mobile-detect
rails
@ -446,10 +457,7 @@ GEM
naught (1.1.0)
nenv (0.2.0)
nested_form (0.3.2)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (3.0.1)
nio4r (1.1.1)
nio4r (1.2.0)
nokogiri (1.6.7.1)
mini_portile2 (~> 2.0.0.rc2)
notiffany (0.0.8)
@ -462,18 +470,19 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (~> 1.2)
omniauth (1.2.2)
omniauth (1.3.1)
hashie (>= 1.2, < 4)
rack (~> 1.0)
omniauth-facebook (2.0.1)
rack (>= 1.0, < 3)
omniauth-facebook (3.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-oauth (1.1.0)
oauth
omniauth (~> 1.0)
omniauth-oauth2 (1.3.1)
omniauth-oauth2 (1.4.0)
oauth2 (~> 1.0)
omniauth (~> 1.2)
omniauth-tumblr (1.1)
omniauth-tumblr (1.2)
multi_json
omniauth-oauth (~> 1.0)
omniauth-twitter (1.2.1)
json (~> 1.3)
@ -484,7 +493,7 @@ GEM
faraday (~> 0.9.0)
nokogiri (~> 1.6)
orm_adapter (0.5.0)
parser (2.2.2.6)
parser (2.2.3.0)
ast (>= 1.1, < 3.0)
phantomjs (1.9.8.0)
powerpack (0.1.1)
@ -492,8 +501,8 @@ GEM
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
pry-byebug (3.1.0)
byebug (~> 4.0)
pry-byebug (3.3.0)
byebug (~> 8.0)
pry (~> 0.10)
pry-debundle (0.8)
pry
@ -528,32 +537,31 @@ GEM
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.5)
sprockets-rails
rails-assets-colorbox (1.6.3)
rails-assets-jquery (>= 1.3.2)
rails-assets-diaspora_jsxc (0.1.4.alpha.1)
rails-assets-colorbox (= 1.6.3)
rails-assets-favico.js (= 0.3.9)
rails-assets-jquery (= 1.11.2)
rails-assets-jquery-fullscreen-plugin (= 0.5.0)
rails-assets-jquery.slimscroll (= 1.3.6)
rails-assets-jquery.ui (= 1.11.4)
rails-assets-favico.js (0.3.9)
rails-assets-highlightjs (8.9.1)
rails-assets-diaspora_jsxc (0.1.4)
rails-assets-favico.js (~> 0.3.9)
rails-assets-jquery (>= 1.11)
rails-assets-jquery-colorbox (~> 1.6.3)
rails-assets-jquery-fullscreen-plugin (~> 0.5.0)
rails-assets-jquery.slimscroll (~> 1.3.6)
rails-assets-jquery.ui (~> 1.11.4)
rails-assets-favico.js (0.3.10)
rails-assets-highlightjs (9.0.0)
rails-assets-jakobmattsson--jquery-elastic (1.6.11)
rails-assets-jquery (>= 1.2.6)
rails-assets-jasmine (2.3.4)
rails-assets-jasmine (2.4.1)
rails-assets-jasmine-ajax (3.2.0)
rails-assets-jasmine (~> 2)
rails-assets-jeresig--jquery.hotkeys (0.2.0)
rails-assets-jquery (>= 1.4.2)
rails-assets-jquery (1.11.2)
rails-assets-jquery-colorbox (1.6.3)
rails-assets-jquery (>= 1.3.2)
rails-assets-jquery-fullscreen-plugin (0.5.0)
rails-assets-jquery-placeholder (2.1.3)
rails-assets-jquery-placeholder (2.3.1)
rails-assets-jquery (>= 1.6)
rails-assets-jquery-textchange (0.2.3)
rails-assets-jquery
rails-assets-jquery.slimscroll (1.3.6)
rails-assets-jquery (>= 1.7)
rails-assets-jquery.slimscroll (1.3.7)
rails-assets-jquery.ui (1.11.4)
rails-assets-jquery (>= 1.6)
rails-assets-markdown-it--markdown-it-for-inline (0.1.1)
@ -563,7 +571,7 @@ GEM
rails-assets-markdown-it-sanitizer (0.4.1)
rails-assets-markdown-it-sub (1.0.0)
rails-assets-markdown-it-sup (1.0.0)
rails-assets-perfect-scrollbar (0.6.7)
rails-assets-perfect-scrollbar (0.6.8)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.7)
@ -572,13 +580,13 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.2)
loofah (~> 2.0)
rails-i18n (4.0.5)
i18n (~> 0.6)
rails-i18n (4.0.8)
i18n (~> 0.7)
railties (~> 4.0)
rails-timeago (2.11.0)
actionpack (>= 3.1)
activesupport (>= 3.1)
rails_admin (0.7.0)
rails_admin (0.8.1)
builder (~> 3.1)
coffee-rails (~> 4.0)
font-awesome-rails (>= 3.0, < 5)
@ -603,14 +611,18 @@ GEM
rb-fsevent (0.9.6)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
redcarpet (3.3.3)
redis (3.2.1)
rbvmomi (1.8.2)
builder
nokogiri (>= 1.4.1)
trollop
redcarpet (3.3.4)
redis (3.2.2)
redis-namespace (1.5.2)
redis (~> 3.0, >= 3.0.4)
remotipart (1.2.1)
request_store (1.2.0)
responders (2.1.0)
railties (>= 4.2.0, < 5)
request_store (1.2.1)
responders (2.1.1)
railties (>= 4.2.0, < 5.1)
roxml (3.1.6)
activesupport (>= 2.3.0)
nokogiri (>= 1.3.3)
@ -637,17 +649,18 @@ GEM
rspec-mocks (~> 3.3.0)
rspec-support (~> 3.3.0)
rspec-support (3.3.0)
rubocop (0.34.2)
rubocop (0.35.1)
astrolabe (~> 1.3)
parser (>= 2.2.2.5, < 3.0)
parser (>= 2.2.3.0, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.4)
ruby-oembed (0.8.14)
ruby-progressbar (~> 1.7)
tins (<= 1.6.0)
ruby-oembed (0.9.0)
ruby-progressbar (1.7.5)
rubyzip (1.1.7)
safe_yaml (1.0.4)
sass (3.4.19)
sass (3.4.20)
sass-rails (5.0.4)
railties (>= 4.0.0, < 5.0)
sass (~> 3.1)
@ -660,7 +673,7 @@ GEM
rubyzip (~> 1.0)
websocket (~> 1.0)
shellany (0.0.1)
shoulda-matchers (3.0.0)
shoulda-matchers (3.0.1)
activesupport (>= 4.0.0)
sidekiq (3.4.2)
celluloid (~> 0.16.0)
@ -676,7 +689,7 @@ GEM
simple_captcha2 (0.3.4)
rails (>= 4.1)
simple_oauth (0.3.1)
simplecov (0.10.0)
simplecov (0.11.1)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
@ -688,7 +701,7 @@ GEM
sinon-rails (1.15.0)
railties (>= 3.1)
slop (3.6.0)
spring (1.4.0)
spring (1.6.1)
spring-commands-cucumber (1.0.1)
spring (>= 0.9.1)
spring-commands-rspec (1.0.4)
@ -704,7 +717,7 @@ GEM
sprockets (>= 2.8, < 4.0)
state_machine (1.2.0)
systemu (2.6.5)
test_after_commit (0.4.1)
test_after_commit (0.4.2)
activerecord (>= 3.2)
thor (0.19.1)
thread_safe (0.3.5)
@ -712,6 +725,8 @@ GEM
timecop (0.8.0)
timers (4.0.4)
hitimes
tins (1.6.0)
trollop (2.1.2)
twitter (5.15.0)
addressable (~> 2.3)
buftok (~> 0.2.0)
@ -735,21 +750,22 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.7.1)
unicorn (4.9.0)
unicorn (5.0.1)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
uuid (2.3.8)
macaddr (~> 1.0)
valid (1.1.0)
warden (1.2.3)
warden (1.2.4)
rack (>= 1.0)
webmock (1.22.1)
webmock (1.22.3)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
websocket (1.2.2)
will_paginate (3.0.7)
xml-simple (1.1.5)
xpath (2.0.0)
nokogiri (~> 1.3)
@ -763,7 +779,7 @@ DEPENDENCIES
acts_as_api (= 0.4.2)
addressable (= 2.3.8)
asset_sync (= 1.1.0)
autoprefixer-rails (= 6.0.3)
autoprefixer-rails (= 6.2.2)
backbone-on-rails (= 1.2.0.0)
bootstrap-sass (= 2.3.2.2)
capybara (= 2.5.0)
@ -772,11 +788,12 @@ DEPENDENCIES
configurate (= 0.3.1)
cucumber-rails (= 1.4.2)
database_cleaner (= 1.5.1)
devise (= 3.5.2)
devise (= 3.5.3)
devise-token_authenticatable (~> 0.4.0)
devise_lastseenable (= 0.0.6)
diaspora-vines (~> 0.2.0.develop)
diaspora_federation-rails (= 0.0.8)
diaspora_federation-rails (= 0.0.11)
diaspora_federation-test (= 0.0.11)
entypo-rails (= 2.2.3)
eye (= 0.7)
facebox-rails (= 0.2.0)
@ -785,7 +802,7 @@ DEPENDENCIES
faraday-cookie_jar (= 0.0.6)
faraday_middleware (= 0.10.0)
fixture_builder (= 0.4.1)
fog (= 1.34.0)
fog (= 1.37.0)
fuubar (= 2.0.0)
gon (= 6.0.1)
guard (= 2.13.0)
@ -794,18 +811,18 @@ DEPENDENCIES
guard-rspec (= 4.6.4)
guard-rubocop (= 1.2.0)
haml (= 4.0.7)
handlebars_assets (= 0.21.0)
handlebars_assets (= 0.22.0)
http_accept_language (= 2.0.5)
i18n-inflector-rails (= 1.0.7)
jasmine (= 2.3.1)
jasmine (= 2.4.0)
jasmine-jquery-rails (= 2.0.3)
jquery-rails (= 4.0.5)
jquery-ui-rails (= 5.0.5)
js-routes (= 1.1.2)
js-routes (= 1.2.0)
js_image_paths (= 0.0.2)
jshintrb (= 0.3.0)
json (= 1.8.3)
json-schema (= 2.5.1)
json-schema (= 2.5.2)
logging-rails (= 0.5.0)
markerb (= 1.1.0)
messagebus_ruby_api (= 1.0.3)
@ -814,9 +831,9 @@ DEPENDENCIES
mobile-fu (= 1.3.1)
mysql2 (= 0.3.20)
nokogiri (= 1.6.7.1)
omniauth (= 1.2.2)
omniauth-facebook (= 2.0.1)
omniauth-tumblr (= 1.1)
omniauth (= 1.3.1)
omniauth-facebook (= 3.0.0)
omniauth-tumblr (= 1.2)
omniauth-twitter (= 1.2.1)
omniauth-wordpress (= 0.2.2)
open_graph_reader (= 0.6.1)
@ -831,13 +848,13 @@ DEPENDENCIES
rack-rewrite (= 1.5.1)
rack-ssl (= 1.4.1)
rails (= 4.2.5)
rails-assets-diaspora_jsxc (~> 0.1.4.alpha, < 0.1.4.develop)!
rails-assets-highlightjs (= 8.9.1)!
rails-assets-diaspora_jsxc (~> 0.1.4)!
rails-assets-highlightjs (= 9.0.0)!
rails-assets-jakobmattsson--jquery-elastic (= 1.6.11)!
rails-assets-jasmine-ajax (= 3.2.0)!
rails-assets-jeresig--jquery.hotkeys (= 0.2.0)!
rails-assets-jquery (= 1.11.2)!
rails-assets-jquery-placeholder (= 2.1.3)!
rails-assets-jquery-placeholder (= 2.3.1)!
rails-assets-jquery-textchange (= 0.2.3)!
rails-assets-markdown-it (= 5.0.2)!
rails-assets-markdown-it--markdown-it-for-inline (= 0.1.1)!
@ -846,43 +863,43 @@ DEPENDENCIES
rails-assets-markdown-it-sanitizer (= 0.4.1)!
rails-assets-markdown-it-sub (= 1.0.0)!
rails-assets-markdown-it-sup (= 1.0.0)!
rails-assets-perfect-scrollbar (= 0.6.7)!
rails-i18n (= 4.0.5)
rails-assets-perfect-scrollbar (= 0.6.8)!
rails-i18n (= 4.0.8)
rails-timeago (= 2.11.0)
rails_admin (= 0.7.0)
rails_admin (= 0.8.1)
rb-fsevent (= 0.9.6)
rb-inotify (= 0.9.5)
redcarpet (= 3.3.3)
redcarpet (= 3.3.4)
remotipart (= 1.2.1)
responders (= 2.1.0)
responders (= 2.1.1)
roxml (= 3.1.6)
rspec-instafail (= 0.4.0)
rspec-rails (= 3.3.3)
rubocop (= 0.34.2)
ruby-oembed (= 0.8.14)
rubocop (= 0.35.1)
ruby-oembed (= 0.9.0)
rubyzip (= 1.1.7)
sass-rails (= 5.0.4)
selenium-webdriver (= 2.47.1)
shoulda-matchers (= 3.0.0)
shoulda-matchers (= 3.0.1)
sidekiq (= 3.4.2)
sidetiq (= 0.6.3)
simple_captcha2 (= 0.3.4)
simplecov (= 0.10.0)
simplecov (= 0.11.1)
sinatra (= 1.4.6)
sinon-rails (= 1.15.0)
spring (= 1.4.0)
spring (= 1.6.1)
spring-commands-cucumber (= 1.0.1)
spring-commands-rspec (= 1.0.4)
test_after_commit (= 0.4.1)
test_after_commit (= 0.4.2)
timecop (= 0.8.0)
twitter (= 5.15.0)
twitter-text (= 1.13.0)
typhoeus (= 0.8.0)
uglifier (= 2.7.2)
unicorn (= 4.9.0)
unicorn (= 5.0.1)
uuid (= 2.3.8)
webmock (= 1.22.1)
webmock (= 1.22.3)
will_paginate (= 3.0.7)
BUNDLED WITH
1.10.6
1.11.2

View file

@ -97,7 +97,7 @@ app.views.Hovercard = app.views.Base.extend({
href += "/hovercard.json";
var self = this;
$.get(href, function(person){
$.ajax(href, {preventGlobalErrorHandling: true}).done(function(person){
if( !person || person.length === 0 ) {
throw new Error("received data is not a person object");
}
@ -126,11 +126,12 @@ app.views.Hovercard = app.views.Base.extend({
return $('<a/>',{href: "/tags/"+tag.substring(1)}).text(tag)[0] ;
})) );
if(!app.currentUser.authenticated()){ return; }
// set aspect dropdown
// TODO render me client side!!!
var href = this.href();
href += "/aspect_membership_button";
$.get(href, function(response) {
$.ajax(href, {preventGlobalErrorHandling: true}).done(function(response){
self.dropdown_container.html(response);
});
new app.views.AspectMembership({el: self.dropdown_container});

View file

@ -1,5 +1,5 @@
//= require jquery.slimscroll
//= require colorbox
//= require jquery.slimscroll/jquery.slimscroll
//= require jquery-colorbox
//= require favico.js
//= require jquery-fullscreen-plugin
//= require diaspora_jsxc
@ -25,7 +25,7 @@ $(document).ready(function() {
chat: 1
},
displayRosterMinimized: function() {
return true;
return false;
},
xmpp: {
url: $('script#jsxc').data('endpoint'),

View file

@ -77,7 +77,6 @@
@import 'stream';
@import 'stream_element';
@import 'comments';
@import 'colorbox';
@import 'diaspora_jsxc';
@import 'chat';
@import 'markdown-content';

View file

@ -3,8 +3,8 @@
# the COPYRIGHT file.
class PeopleController < ApplicationController
before_action :authenticate_user!, except: [:show, :stream]
before_action :find_person, only: [:show, :stream, :hovercard]
before_action :authenticate_user!, except: %i(show stream hovercard)
before_action :find_person, only: %i(show stream hovercard)
respond_to :html, :except => [:tag_index]
respond_to :json, :only => [:index, :show]

View file

@ -1,53 +0,0 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
class PublicsController < ApplicationController
include Diaspora::Parser
skip_before_action :set_header_data
skip_before_action :set_grammatical_gender
before_action :check_for_xml, :only => [:receive, :receive_public]
before_action :authenticate_user!, :only => [:index]
respond_to :html
respond_to :xml, :only => :post
layout false
def hub
render :text => params['hub.challenge'], :status => 202, :layout => false
end
def receive_public
logger.info "received a public message"
Workers::ReceiveUnencryptedSalmon.perform_async(CGI::unescape(params[:xml]))
render :nothing => true, :status => :ok
end
def receive
person = Person.find_by_guid(params[:guid])
if person.nil? || person.owner_id.nil?
logger.error "Received post for nonexistent person #{params[:guid]}"
render :nothing => true, :status => 404
return
end
@user = person.owner
logger.info "received a private message for user: #{@user.id}"
Workers::ReceiveEncryptedSalmon.perform_async(@user.id, CGI::unescape(params[:xml]))
render :nothing => true, :status => 202
end
private
def check_for_xml
if params[:xml].nil?
render :nothing => true, :status => 422
return
end
end
end

View file

@ -64,6 +64,8 @@ private
begin
n.actors = n.actors | [actor]
n.unread = true
# Explicitly touch the notification to update updated_at whenever new actor is inserted in notification.
n.touch
n.save!
rescue ActiveRecord::RecordNotUnique
nil

View file

@ -10,4 +10,4 @@
.media-body
= notification_message_for(note)
%div
= timeago(note.created_at)
= timeago(note.updated_at)

View file

@ -1,7 +1,8 @@
#!/usr/bin/env ruby
begin
load File.expand_path("../spring", __FILE__)
rescue LoadError
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
require 'bundler/setup'
load Gem.bin_path('cucumber', 'cucumber')

View file

@ -1,8 +1,11 @@
#!/usr/bin/env ruby
begin
load File.expand_path("../spring", __FILE__)
rescue LoadError
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'

View file

@ -1,7 +1,8 @@
#!/usr/bin/env ruby
begin
load File.expand_path("../spring", __FILE__)
rescue LoadError
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
require_relative '../config/boot'
require 'rake'

View file

@ -1,7 +1,8 @@
#!/usr/bin/env ruby
begin
load File.expand_path("../spring", __FILE__)
rescue LoadError
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
require 'bundler/setup'
load Gem.bin_path('rspec-core', 'rspec')

View file

@ -1,18 +1,15 @@
#!/usr/bin/env ruby
# This file loads spring without using Bundler, in order to be fast
# It gets overwritten when you run the `spring binstub` command
# This file loads spring without using Bundler, in order to be fast.
# It gets overwritten when you run the `spring binstub` command.
unless defined?(Spring)
require "rubygems"
require "bundler"
require 'rubygems'
require 'bundler'
if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)
ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR)
ENV["GEM_HOME"] = nil
Gem.paths = ENV
gem "spring", match[1]
require "spring/binstub"
if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m))
Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq }
gem 'spring', match[1]
require 'spring/binstub'
end
end

View file

@ -4,7 +4,7 @@
defaults:
version:
number: "0.5.5.1" # Do not touch unless doing a release, do not backport the version number that's in master
number: "0.5.6.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/"

View file

@ -10,15 +10,16 @@ DiasporaFederation.configure do |config|
person = Person.find_local_by_diaspora_handle(handle)
if person
DiasporaFederation::Discovery::WebFinger.new(
acct_uri: "acct:#{person.diaspora_handle}",
alias_url: AppConfig.url_to("/people/#{person.guid}"),
hcard_url: AppConfig.url_to(DiasporaFederation::Engine.routes.url_helpers.hcard_path(person.guid)),
seed_url: AppConfig.pod_uri,
profile_url: person.profile_url,
atom_url: person.atom_url,
salmon_url: person.receive_url,
guid: person.guid,
public_key: person.serialized_public_key
acct_uri: "acct:#{person.diaspora_handle}",
alias_url: AppConfig.url_to("/people/#{person.guid}"),
hcard_url: AppConfig.url_to(DiasporaFederation::Engine.routes.url_helpers.hcard_path(person.guid)),
seed_url: AppConfig.pod_uri,
profile_url: person.profile_url,
atom_url: person.atom_url,
salmon_url: person.receive_url,
subscribe_url: AppConfig.url_to("/people?q={uri}"),
guid: person.guid,
public_key: person.serialized_public_key
)
end
end
@ -61,5 +62,52 @@ DiasporaFederation.configure do |config|
person_entity.save!
end
on :fetch_private_key_by_diaspora_id do |diaspora_id|
key = Person.where(diaspora_handle: diaspora_id).joins(:owner).pluck(:serialized_private_key).first
OpenSSL::PKey::RSA.new key unless key.nil?
end
on :fetch_author_private_key_by_entity_guid do |entity_type, guid|
key = entity_type.constantize.where(guid: guid).joins(author: :owner).pluck(:serialized_private_key).first
OpenSSL::PKey::RSA.new key unless key.nil?
end
on :fetch_public_key_by_diaspora_id do |diaspora_id|
key = Person.where(diaspora_handle: diaspora_id).pluck(:serialized_public_key).first
OpenSSL::PKey::RSA.new key unless key.nil?
end
on :fetch_author_public_key_by_entity_guid do |entity_type, guid|
key = entity_type.constantize.where(guid: guid).joins(:author).pluck(:serialized_public_key).first
OpenSSL::PKey::RSA.new key unless key.nil?
end
on :entity_author_is_local? do |entity_type, guid|
entity_type.constantize.where(guid: guid).joins(author: :owner).exists?
end
on :fetch_entity_author_id_by_guid do |entity_type, guid|
entity_type.constantize.where(guid: guid).joins(:author).pluck(:diaspora_handle).first
end
on :queue_public_receive do |xml|
Workers::ReceiveUnencryptedSalmon.perform_async(xml)
end
on :queue_private_receive do |guid, xml|
person = Person.find_by_guid(guid)
if person.nil? || person.owner_id.nil?
false
else
Workers::ReceiveEncryptedSalmon.perform_async(person.owner.id, xml)
true
end
end
on :save_entity_after_receive do
# TODO
end
end
end

View file

@ -58,7 +58,7 @@ available:
si: "සිංහල"
sk: "Slovenčina"
sl: "Slovenščina"
sq: "gjuha shqipe"
sq: "Shqip"
sr: "српски језик"
sv: "Svenska"
te: "తెలుగు"

View file

@ -1,121 +1,88 @@
# Copyright (c) 2010-2012, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
sq:
errors:
messages:
not_found: "nuk u gjet"
not_found: "su gjet"
already_confirmed: "është ripohuar tashmë"
not_locked: "nuk qe kyçur"
not_locked: "sqe kyçur"
devise:
failure:
unauthenticated: 'Duhet të bëni hyrjen ose të regjistroheni, përpara se të vazhdohet.'
unconfirmed: 'Duhet të ripohoni llogarinë tuaj, përpara se të vazhdohet.'
locked: 'Llogaria juaj është e kyçur.'
invalid: 'Emër përdoruesi ose fjalëkalim i gabuar.'
invalid_token: 'Mekanizëm ose të dhëna të pavlefshme mirëfilltësimi.'
timeout: 'Sesionit tuaj i mbaroi koha, ju lutem, hyni sërish që të vazhdoni.'
inactive: 'Llogaria juaj ende nuk është aktive.'
unauthenticated: "Duhet të bëni hyrjen ose të regjistroheni, përpara se të vazhdohet."
unconfirmed: "Duhet të ripohoni llogarinë tuaj, përpara se të vazhdohet."
locked: "Llogaria juaj është e kyçur."
not_found_in_database: 'Email ose fjalëkalim i pavlefshëm.'
invalid: 'Emër përdoruesi ose fjalëkalim i pavlefshëm.'
invalid_token: 'Token mirëfilltësimi i pavlefshëm.'
timeout: "Sesionit tuaj i mbaroi koha, ju lutemi, hyni sërish që të vazhdoni."
inactive: "Llogaria juaj ende sështë aktive."
sessions:
new:
login: 'Hyni'
username: 'Emër përdoruesi'
password: 'Fjalëkalim'
sign_in: 'Hyni'
login: "Hyni"
username: "Emër përdoruesi"
password: "Fjalëkalim"
sign_in: "Hyni"
remember_me: "Mbamë mend"
alpha_software: 'Ju ndan një hap nga përdorimi i një programi në stad alfa.'
bugs_and_feedback: 'Ta dini që tani: do të hasni të meta. Ju nxisim të përdorni butonin Përshtypje në anën e djathtë të shfletuesit tuaj që të raportoni çfarëdo bllokimi! Do të punojmë sa më shpejt që të mundemi për të zgjidhur çfarëdo çështje që na raportoni.'
bugs_and_feedback_mobile: 'Ta dini që tani, do të hasni të meta. Ju nxisim të raportoni çfarëdo bllokimi! Do të punojmë sa më shpejt që të mundemi për të zgjidhur çfarëdo çështje që na raportoni.'
modern_browsers: 'mbulon vetëm shfletues modernë.'
modern_browsers: 'mbulon vetëm shfletuesit modernë.'
signed_in: 'Hytë me sukses.'
signed_out: 'Dolët me sukses.'
passwords:
send_instructions: "Brenda pak minutash do t'ju vijë email me udhëzime si të ricaktoni fjalëkalimin tuaj."
updated: 'Fjalëkalimi juaj u ndryshua me sukses. Tani jeni i futur.'
send_instructions: "Brenda pak minutash do tju vijë një email me udhëzime se si të ricaktoni fjalëkalimin tuaj."
updated: "Fjalëkalimi juaj u ndryshua me sukses. Tani jeni i futur."
edit:
change_password: "Ndërroje fjalëkalimin tim"
change_password: "Ndryshoje fjalëkalimin tim"
new_password: "Fjalëkalim i ri"
confirm_password: "Ripohoni fjalëkalimin"
new:
forgot_password: "Harruat fjalëkalimin?"
no_account: 'Nuk ka llogari me këtë email. Nëse po prisni për një ftesë, po shpërndajmë të tilla aq shpejt sa mundemi'
send_password_instructions: "Dërgomë udhëzime ricaktimi fjalëkalimi"
no_account: 'Ska llogari me këtë email'
reset_password: "Ricaktoni fjalëkalimin"
email: "Adresë email"
send_password_instructions: "Dërgomëni udhëzime ricaktimi fjalëkalimi"
confirmations:
send_instructions: "Brenda pak minutash do t'ju vijë një email me udhëzime se si të ripohoni llogarinë tuaj."
confirmed: 'Llogaria juaj u ripohua me sukses. Tani jeni i futur.'
send_instructions: "Brenda pak minutash do tju vijë një email me udhëzime se si të ripohoni llogarinë tuaj."
confirmed: "Llogaria juaj u ripohua me sukses. Tani jeni i futur."
new:
resend_confirmation: "Ridërgo udhëzime ripohimi"
registrations:
signed_up: 'U regjistruat me sukses. Po qe se mundësia përkatëse është e aktivizuar, ju është dërguar një mesazh ripohimi te e-mail-i juaj.'
updated: 'E përditësuat me sukses llogarinë tuaj.'
destroyed: "Shëndet! Llogaria juaj u anulua me sukses. Shpresojmë t'ju shohim prapë së shpejti."
signed_up: "U regjistruat me sukses. Po qe se mundësia përkatëse është e aktivizuar, ju është dërguar një mesazh ripohimi te email-i juaj."
updated: "E përditësuat me sukses llogarinë tuaj."
destroyed: "Shëndet! Llogaria juaj u anulua me sukses. Shpresojmë tju shohim prapë së shpejti."
unlocks:
send_instructions: "Brenda pak minutash do t'ju vijë një email me udhëzime se si zhbllokoni llogarinë."
send_instructions: "Brenda pak minutash do tju vijë një email me udhëzime se si të zhbllokoni llogarinë."
unlocked: 'Llogaria juaj u zhbllokua me sukses. Tani jeni i futur.'
new:
resend_unlock: "Ridërgoji udhësimet për zhbllokim"
resend_unlock: "Ridërgoji udhëzimet për zhbllokim"
invitations:
send_instructions: 'Ftesa juaj u dërgua.'
invitation_token_invalid: 'Ndjesën tonë! Ky mekanizëm ose këto të dhëna ftese nuk janë të vlefshme.'
updated: 'Fjalëkalimi juaj u caktua me sukses. Tani jeni i futur.'
send_instructions: "Ftesa juaj u dërgua."
invitation_token_invalid: "Ndjesën tonë! Ky mekanizëm ose këto të dhëna ftese sjanë të vlefshme."
updated: "Fjalëkalimi juaj u caktua me sukses. Tani jeni i futur."
mailer:
welcome: "Mirë se vini %{email}!"
hello: "Tungjatjeta %{email}!"
confirmation_instructions:
subject: 'Udhëzime ripohimi'
subject: "Udhëzime ripohimi"
you_can_confirm: "Llogarinë tuaj mund të ripohoni përmes lidhjes më poshtë:"
confirm: "Ripohoje llogarinë time"
reset_password_instructions:
subject: 'Udhëzime ricaktimi fjalëkalimi'
subject: "Udhëzime ricaktimi fjalëkalimi"
someone_requested: "Dikush kërkoi një lidhje për ndryshimin e fjalëkalimit tuaj, dhe këtë mund ta bëni përmes lidhjes më poshtë."
change: "Ndërroje fjalëkalimin tim"
wont_change: "Fjalëkalimi juaj nuk do të ndryshojë pa përdorur lidhjen e mësipërme për të krijuar një të ri."
ignore: "Nëse këtë nuk e kërkuat ju, ju lutem, shpërfilleni këtë email."
change: "Ndryshoje fjalëkalimin tim"
wont_change: "Fjalëkalimi juaj nuk do të ndryshojë pa përdorur lidhjen sipër për të krijuar një të ri."
ignore: "Nëse këtë se kërkuat ju, ju lutemi, shpërfilleni këtë email."
unlock_instructions:
subject: 'Udhëzime zhbllokimi'
account_locked: "Llogari juaj është bllokuar për shkak të një sasie të tepruar përpjekjesh për të hyrë në të."
click_to_unlock: "Që të zhbllokoni llogarinë tuaj, klikoni lidhjen e mëposhtme:"
subject: "Udhëzime zhbllokimi"
account_locked: "Llogaria juaj është bllokuar për shkak të një sasie të tepruar përpjekjesh për të hyrë në të."
click_to_unlock: "Që të zhbllokoni llogarinë tuaj, klikoni lidhjen më poshtë:"
unlock: "Zhbllokoje llogarinë time"
invitation_instructions:
displaying_correctly: "Nuk shfaqet si duhet email-i? %{link}"
view_in: "Shiheni te shlfetuesi juaj."
finally: "Më në fund - ja ku është"
arrived: "Rrjeti shoqëror që keni pritur, mbërriti. I rishikuar, më i sigurt, dhe më zbavitës, %{strong_diaspora} është gati t'ju ndihmojë të ndani me të tjerët dhe të eksploroni gjithçka në web nën një rrugë të re."
sign_up_now: "Regjistrohuni tani &rarr;"
friends_saying: "Ç'thonë miqtë tuaj..."
more_people: "Më tepër persona janë të ngazëllyer t'ju shohin!"
get_connected: "Lidhuni"
get_connected_paragraph: "Një lëvizje ndërkombëtare me një vizion të përbashkët për një web më të mirë, veçoria #1 e %{strong_diaspora}-s është bashkësia e saj. Njihuni me njerëz të rinj, lidhuni me miqtë, dhe merrni pjesë në zbavitje."
be_yourself: "Jini Vetvetja"
be_yourself_paragraph: "Interneti ka krijuar rrugë të reja unike që të shprehim vetveten. %{strong_diaspora} ju lejon të jeni vetvetja dhe të ndani me të tjerët çfarëdo që dëshironi, me ose pa emrin tuaj të vërtetë."
have_fun: "Zbavituni"
cubbies: "Cubbi.es"
have_fun_paragraph: "%{strong_diaspora} do të thotë zbulim online lënde dhe personash të rinj mahnitës. %{link}, zbatimi i parë në botë për %{strong_diaspora} është thjesht fillimi. Mblidhni dhe ndani me të tjerët gjëra nga web-i në tërë madhështinë e tij."
made_by_people: "%{strong_diaspora} është krijuar nga njerëz që e duan Internetin po aq sa ju. %{jointeam}, ose %{helpfund}!"
join_team: "Bëhuni Pjesë e Ekipit Tonë"
or: "ose"
help_fund: "ndihmoni në financimin e Diaspora-s"
unsubscribe: "Që të çregjistroheni, ju lutem, klikoni mbi %{link}."
here: "këtu"
love: "Me dashuri,"
team_diaspora: "Ekipi i Diaspora-s"
email_us: "Për pyetje dhe kërkesa të përgjithshme, ose për asistencë lidhur me llogarinë tuaj në Diaspora, ju lutem, na dërgoni një email te %{email}."
email_address: "questions@joindiaspora.com"
subject: "Jeni ftuar të merrni pjesë te Diaspora!"
accept: "Pranojeni ftesën"
ignore: "Nëse nuk doni ta pranoni ftesën, ju lutem, shpërfilleni këtë email."
no_account_till: "Llogaria juaj nuk do të krijohet pa shkuar te lidhja e mësipërme që të regjistroheni."
inviter:
has_invited_you: "%{name}"
have_invited_you: "%{names} ju ka ftuar të merrni pjesë në Diaspora"
have_invited_you: "%{names} ju ka ftuar të merrni pjesë në diaspora*"
accept_at: "te %{url}, mund ta pranoni përmes lidhjes më poshtë."
shared:
mail_signup_form:
sign_up_for_an_invite: "Regjistrohuni për një ftesë!"
links:
sign_in: 'Hyni'
sign_up: 'Regjistrohuni'
sign_up_closed: 'Hëpërhë regjistrimet janë të mbyllura.'
sign_up_closed: 'Regjistrimet e lira janë të mbyllura hëpërhë.'
forgot_your_password: 'Harruat fjalëkalimin tuaj?'
receive_confirmation: "Nuk i morët udhëzimet për ripohimin?"
receive_unlock: "Nuk i morët udhëzimet për zhbllokimin?"
receive_confirmation: "Si morët udhëzimet për ripohimin?"
receive_unlock: "Si morët udhëzimet për zhbllokimin?"

View file

@ -173,9 +173,6 @@ en:
video_title:
unknown: "Unknown video title"
aspects:
zero: "No aspects"
one: "1 aspect"
other: "%{count} aspects"
contacts_visible: "Contacts in this aspect will be able to see each other."
contacts_not_visible: "Contacts in this aspect will not be able to see each other."
edit:
@ -299,9 +296,6 @@ en:
other: "%{count} reactions"
contacts:
zero: "No contacts"
one: "1 contact"
other: "%{count} contacts"
create:
failure: "Failed to create contact"
sharing:
@ -1355,7 +1349,7 @@ en:
mr_wiggles: "Mr Wiggles will be sad to see you go"
what_we_delete: "We will delete all of your posts and profile data as soon as possible. Your comments on other peoples posts will still appear, but they will be associated with your diaspora* ID rather than your name."
locked_out: "You will get signed out and locked out of your account until it has been deleted."
lock_username: "Your username will be locked. You will not be able create a new account on this pod with the same ID."
lock_username: "Your username will be locked. You will not be able to create a new account on this pod with the same ID."
no_turning_back: "There is no turning back! If youre really sure, enter your password below."
if_you_want_this: "If you really want this to happen, type in your password below and click “Close account”"

File diff suppressed because it is too large Load diff

View file

@ -5,10 +5,85 @@
sq:
javascripts:
cancel: "Anuloje"
confirm_dialog: "Jeni i sigurt?"
confirm_unload: "Ju lutemi, ripohoni se doni ta braktisni këtë faqe. Të dhënat që keni dhënë sdo të ruhen."
create: "Krijoje"
delete: "Fshije"
ignore: "Shpërfille"
report:
prompt: "Ju lutemi, jepni një arsye:"
prompt_default: "p.sh. lëndë fyese"
name: "Njoftim"
status:
created: "Njoftimi u krijua me sukses"
exists: "Njoftimi ekziston"
ignore_user: "Të shpërfillet ky përdorues?"
ignore_failed: "Sarrihet të shpërfillet ky përdorues"
hide_post: "Të fshihet ky postim?"
hide_post_failed: "Sarrihet të fshihet ky postim"
remove_post: "Të hiqet ky postim?"
unblock_failed: "Zhbllokimi i këtij përdoruesi dështoi"
and: "dhe"
comma: ","
edit: "Përpunojeni"
no_results: "Su gjetën përfundime"
admins:
dashboard:
up_to_date: "Nyja juaj është e përditësuar!"
outdated: "Nyja juaj është e vjetruar."
compare_versions: "Versioni më i ri i diaspora* është <%= latestVersion %>, nyja juaj xhiron ende <%= podVersion %>."
error: "Su arrit të përcaktohej versioni më i ri i diaspora*."
admin:
pods:
pod: "Nyjë"
ssl: "SSL"
ssl_enabled: "SSL e aktivizuar"
ssl_disabled: "SSL e çaktivizuar"
added: "U shtua"
status: "Gjendje"
states:
unchecked: "E pakontrolluar"
no_errors: "OK"
dns_failed: "Ftillimi i emrit (DNS) dështoi"
net_failed: "Përpjekja për lidhje dështoi"
ssl_failed: "Lidhja e sigurt (SSL) dështoi"
http_failed: "Lidhja HTTP dështoi"
version_failed: "Su arrit të merrej version software-i"
unknown_error: "Gjatë kontrollit ndodhi një gabim i papërcaktuar"
actions: "Veprime"
offline_since: "jashtë linje që prej:"
last_check: "kontrolli i fundit:"
more_info: "shfaq më tepër të dhëna"
check: "kryej një provë të lidhjes"
recheck:
success: "Nyja u kontrolluar sërish."
failure: "Kontrolli nuk u krye."
follow_link: "hape lidhjen në shfletues"
no_info: "Ska të dhëna të tjera në këtë pikë"
server_software: "Software shërbyesi:"
response_time: "Kohë përgjigjeje:"
ms:
one: "<%= count %>ms"
other: "<%= count %>ms"
unknown: "e panjohur"
not_available: "jo gati"
unchecked:
one: "Ka ende një nyjë që sështë kontrolluar fare."
other: "Ka ende <%= count %> nyja që sjanë kontrolluar fare."
errors:
one: "Prova e lidhjes u përgjigj me një gabim për një nyjë."
other: "Prova e lidhjes u përgjigj me një gabim për <%= count %> nyje."
aspects:
make_aspect_list_visible: "Të bëhen kontaktet në këtë aspekt të dukshëm për njëri-tjetrin?"
name: "Emër"
create:
add_a_new_aspect: "Shtoni aspekt të ri"
success: "Aspekti juaj i ri <%= name %> u krijua"
failure: "Krijimi i aspektit dështoi."
timeago:
prefixAgo: ""
prefixFromNow: ""
@ -24,10 +99,21 @@ sq:
month: "rreth një muaj"
months: "%d muaj"
year: "rreth një vit"
years: "%d vjetë"
years: "%d vjet"
wordSeparator: " "
my_activity: "Veprimtaria Ime"
contacts:
add_contact: "Shtoni kontakt"
aspect_list_is_visible: "Kontaktet në këtë aspekt janë në gjendje të shohin njëri-tjetrin."
aspect_list_is_not_visible: "Kontaktet në këtë aspekt sjanë në gjendje të shohin njëri-tjetrin."
remove_contact: "Hiqe kontaktin"
error_add: "Su shtua dot <%= name %> te aspekti :("
error_remove: "Su hoq dot <%= name %> prej aspekti :("
search_no_results: "Su gjetën kontakte"
my_activity: "Veprimtaria ime"
my_stream: "Rrjedhë"
my_aspects: "Aspektet e mia"
videos:
watch: "Shiheni këtë video te <%= provider %>"
@ -36,51 +122,102 @@ sq:
publisher:
at_least_one_aspect: "Duhet të publikoni të paktën një aspekt"
limited: "I kufizuar - postimi juaj do të shihet vetëm nga persona me të cilët ndani gjëra"
public: "Publik - postimi juaj do të jetë i dukshëm nga kushdo dhe dhe motorët e kërkimeve do të jenë në gjendje ta kapin"
public: "Publik - postimi juaj do të jetë i dukshëm nga kushdo dhe motorët e kërkimeve do të jenë në gjendje ta kapin"
near_from: "Postuar që nga: <%= location %>"
option: "Përgjigjiuni"
add_option: "Shtoni një përgjigje"
question: "Pyetje"
bookmarklet:
post_something: "Postoni diçka te diaspora*"
post_submit: "Po parashtrohet postimit…"
post_success: "U postua! Po mbyllet dritarja flluskë…"
infinite_scroll:
no_more: "Nuk ka më postime."
no_more: "Ska më postime."
no_more_contacts: "Ska më kontakte."
aspect_dropdown:
add_to_aspect: "Shtoni kontakt"
select_aspects: "Përzgjidhni aspekte"
all_aspects: "Krejt aspektet"
updating: "po përditësohet…"
mobile_row_checked: "<%= name %> (hiqe)"
mobile_row_unchecked: "<%= name %> (shtoje)"
stopped_sharing_with: "Reshtët së ndari gjëra me <%= name %>."
started_sharing_with: "Filluat të ndani gjëra me <%= name %>!"
error: "Nuk u fillua dot ndarja e gjërave me <%= name %>. Mos po e shpërfillni?"
error: "Su fillua dot ndarja e gjërave me <%= name %>. Mos po i shpërfillni?"
error_remove: "Su hoq dot <%= name %> prej aspekti :("
toggle:
zero: "Përzgjidhni aspekte"
one: "Në <%= count %> aspekt"
other: "Në <%= count %> aspekte"
show_more: "shfaq më tepër"
failed_to_like: "Pëlqimi dështoi!"
failed_to_reshare: "Rindarja dështoi!"
failed_to_post_message: "Postimi i mesazhit dështoi!"
failed_to_remove: "Heqja e zërit dështoi!"
comments:
show: "shfaqi krejt komentet"
hide: "fshihi komentet"
show: "Shfaqi krejt komentet"
hide: "Fshihi komentet"
no_comments: "Ende ska komente."
reshares:
duplicate: "I bukur ky, hë? E keni ndarë një herë me të tjerët atë postim!"
duplicate: "Bukur, ë? E keni ndarë një herë me të tjerët atë postim!"
successful: "Postimi u rinda me sukses me të tjerët!"
post: "Të rindahet me të tjerët postimi nga <%= name %>?"
post: "Të rindahet me të tjerët postimi i <%= name %>?"
aspect_navigation:
select_all: "Përzgjidhi krejt"
deselect_all: "Çpërzgjidhi krejt"
no_aspects: "Nuk janë përzgjedhur aspekte"
deselect_all: "Shpërzgjidhi krejt"
no_aspects: "Sjanë përzgjedhur aspekte"
add_an_aspect: "+ Shtoni një aspekt"
getting_started:
hey: "Hej, <%= name %>!"
no_tags: "Hej, nuk jeni duke ndjekur ndonjë etiketë! Të vazhdohet, sido qoftë?"
no_tags: "Hej, sjeni duke ndjekur ndonjë etiketë! Të vazhdohet, sido qoftë?"
alright_ill_wait: "Në rregull, do të pres."
preparing_your_stream: "Po përgatitet rrjedha juaj e personalizuar..."
preparing_your_stream: "Po përgatitet rrjedha juaj e personalizuar"
photo_uploader:
looking_good: "O Zot, sa bukur që dukeni!"
completed: "<%= file %> u plotësua"
error: "Ndodhi një problem teksa ngarkohej kartela <%= file %>"
invalid_ext: "{file} ka një zgjatim të pavlefshëm. Lejohen vetëm {extensions}."
size_error: "{file} është shumë e madhe, madhësia maksimum për kartelat është {sizeLimit}."
empty: "{file} është e zbrazët, ju lutemi, ripërzgjidhni kartela pa e përfshirë atë."
tags:
wasnt_that_interesting: "OK, them se #<%= tagName %> nuk qe kushedi se çë interesant..."
wasnt_that_interesting: "OK, them se #<%= tagName %> sqe kushedi se çë interesante…"
people:
not_found: "dhe nuk u gjet ndonjë..."
not_found: "… dhe su gjet gjë"
mention: "Përmendje"
message: "Mesazh"
edit_my_profile: "Përpuno profilin tim"
stop_ignoring: "Resht së shpërfilluri"
helper:
is_sharing: "<%= name %> ndan gjëra me ju"
is_not_sharing: "<%= name %> ndan gjëra me ju"
profile:
edit: "Përpunojeni"
add_some: "Shtoni ca"
you_have_no_tags: "Skeni etiketa!"
ignoring: "I shpërfillni krejt postimet prej <%= name %>."
bio: "Jetëshkrim"
location: "Vendndodhje"
gender: "Gjini"
born: "Datëlindje"
photos: "Foto"
contacts: "Kontakte"
posts: "Postime"
conversation:
participants: "Pjesëmarrës"
new:
no_contacts: "Lypset të shtoni ca kontakte përpara se të filloni një bisedë."
notifications:
mark_read: "Shënoje si të lexuar"
mark_unread: "Shënoje si të palexuar"
stream:
hide: "Fshihe"
public: "Publike"
limited: "E kufizuar"
like: "Pëlqejeni"
unlike: "Çpëlqejeni"
unlike: "Shpëlqejeni"
reshare: "Rindajeni"
comment: "Komentojeni"
original_post_deleted: "Postimi origjinal është fshirë nga autori."
@ -89,6 +226,10 @@ sq:
hide_nsfw_posts: "Fshihi postimet #nsfw"
follow: "Ndiqe"
unfollow: "Mos e Ndiq Më"
enable_post_notifications: "Aktivizo njoftimet për këtë postim"
disable_post_notifications: "Çaktivizo njoftimet për këtë postim"
permalink: "Permalidhje"
via: "përmes <%= provider %>"
likes:
zero: "<%= count %> Pëlqime"
@ -102,33 +243,63 @@ sq:
more_comments:
zero: "Shfaq <%= count %> komente të tjera"
one: "Shfaq edhe <%= count %> koment"
other: "Shfaq edhe <%= count %> komente"
one: "Shfaq edhe <%= count %> koment tjetër"
other: "Shfaq edhe <%= count %> komente të tjera"
followed_tag:
title: "#Etiketa të ndjekura"
contacts_title: "Persona me këto etiketa në profil"
add_a_tag: "Shtoni një etiketë"
follow: "Ndiqe"
tags:
follow: "Ndiqe #<%= tag %>"
following: "Po ndiqet #<%= tag %>"
stop_following: "Resht së ndjekuri #<%= tag %>"
stop_following_confirm: "Të reshtet së ndjekuri #<%= tag %>?"
follow_error: "Su ndoq dot #<%= tag %> :("
stop_following_error: "Su resht dot së ndjekuri #<%= tag %> :("
header:
home: "Kreu"
profile: "Profil"
contacts: "Kontakte"
settings: "Rregullime"
help: "Ndihmë"
admin: "Admin"
moderator: "Moderator"
log_out: "Dilni"
toggle_navigation: "Shfaqni/fshihni lëvizjen"
toggle_mobile: "Shfaqeni/fshiheni për celular"
notifications: "Njoftime"
messages: "Mesazhe"
conversations: "Biseda"
search: "Kërko"
recent_notifications: "Njoftime Së Fundmi"
recent_notifications: "Njoftime së fundi"
mark_all_as_read: "Shënoji krejt si të lexuara"
view_all: "Shihini krejt"
close: "mbylle"
close: "Mbylle"
viewer:
stop_following_post: "Resht së ndjekuri postimin"
follow_post: "Ndiqe postimin"
like: "Pëlqejeni"
unlike: "Çpëlqejeni"
unlike: "Shpëlqejeni"
reshare: "Rindajeni"
reshared: "I rindarë"
comment: "Komentojeni"
home: "Kreu"
poll:
vote: "Votoni"
go_to_original_post: "Mund të merrni pjesë te ky votim përmes lidhjes te <%= original_post_link %>."
original_post: "postimi origjinal"
result: "Përfundimi"
count:
one: "1 votë deri tani"
other: "<%=count%> vota deri tani"
show_result: "Shfaqe përfundimin"
close_result: "Fshihe përfundimin"

View file

@ -19,3 +19,9 @@ mixcloud:
urls:
- http://www.mixcloud.com/*/*
- https://www.mixcloud.com/*/*
mediacccde:
endpoint: "https://media.ccc.de/public/oembed/"
urls:
- http://media.ccc.de/v/*
- https://media.ccc.de/v/*

View file

@ -18,6 +18,7 @@ Diaspora::Application.routes.draw do
mount Sidekiq::Web => '/sidekiq', :as => 'sidekiq'
end
# Federation
mount DiasporaFederation::Engine => "/"
get "/atom.xml" => redirect('http://blog.diasporafoundation.org/feed/atom') #too many stupid redirects :()
@ -182,17 +183,6 @@ Diaspora::Application.routes.draw do
get '/u/:username' => 'people#show', :as => 'user_profile', :constraints => { :username => /[^\/]+/ }
get '/u/:username/profile_photo' => 'users#user_photo', :constraints => { :username => /[^\/]+/ }
# Federation
controller :publics do
post 'receive/users/:guid' => :receive
post 'receive/public' => :receive_public
get 'hub' => :hub
end
# External
resources :services, :only => [:index, :destroy]

View file

@ -6,15 +6,15 @@ Feature: Hovercards
Background:
Given a user named "Bob Jones" with email "bob@bob.bob"
And "bob@bob.bob" has a public post with text "public stuff"
And "bob@bob.bob" has a public post with text "public stuff #hashtag"
And a user named "Alice" with email "alice@alice.alice"
And "alice@alice.alice" has a public post with text "alice public stuff"
And the post with text "public stuff" is reshared by "alice@alice.alice"
And the post with text "public stuff #hashtag" is reshared by "alice@alice.alice"
And the post with text "alice public stuff" is reshared by "bob@bob.bob"
And I sign in as "alice@alice.alice"
Scenario: Hovercards on the main stream
Given I am on "bob@bob.bob"'s page
Given I sign in as "alice@alice.alice"
And I am on "bob@bob.bob"'s page
Then I should see "public stuff" within ".stream_element"
When I activate the first hovercard
Then I should see a hovercard
@ -22,7 +22,8 @@ Feature: Hovercards
Then I should not see a hovercard
Scenario: Hovercards on the main stream in reshares
Given I am on "bob@bob.bob"'s page
Given I sign in as "alice@alice.alice"
And I am on "bob@bob.bob"'s page
Then I should see "Alice" within "#main_stream"
When I hover "Alice" within "#main_stream"
Then I should not see a hovercard
@ -30,3 +31,11 @@ Feature: Hovercards
Then I should see "Bob Jones" within "#main_stream"
When I hover "Bob Jones" within "#main_stream"
Then I should see a hovercard
Scenario: Hovercards on the tag stream as a logged out user
Given I am on the tag page for "hashtag"
Then I should see "public stuff" within ".stream_element"
When I activate the first hovercard
Then I should see a hovercard
When I deactivate the first hovercard
Then I should not see a hovercard

View file

@ -15,6 +15,7 @@ Then /^I should not see an uploaded image within the photo drop zone$/ do
end
Then /^I should not see any posts in my stream$/ do
page.assert_selector("#paginate .loader", visible: :hidden)
page.assert_selector(".stream_element", count: 0)
end

View file

@ -7,18 +7,20 @@
* Using underscore.js
*
* License: MIT License - http://www.opensource.org/licenses/mit-license.php
*
* Modifcations for Diaspora:
*
* Modifications for Diaspora:
*
* Prevent replacing the wrong text by marking the replacement position with a special character
* Don't add a space after inserting a mention
* Only use the first div as a wrapperBox
* Binded paste event on input box to trigger contacts search for autocompletion while adding mention via clipboard
*/
(function ($, _, undefined) {
// Settings
var KEY = { BACKSPACE : 8, TAB : 9, RETURN : 13, ESC : 27, LEFT : 37, UP : 38, RIGHT : 39, DOWN : 40, COMMA : 188, SPACE : 32, HOME : 36, END : 35 }; // Keys "enum"
var KEY = { PASTE : 118, BACKSPACE : 8, TAB : 9, RETURN : 13, ESC : 27, LEFT : 37, UP : 38, RIGHT : 39,
DOWN : 40, COMMA : 188, SPACE : 32, HOME : 36, END : 35 }; // Keys "enum"
var defaultSettings = {
triggerChar : '@',
onDataRequest : $.noop,
@ -95,6 +97,7 @@
elmInputBox.attr('data-mentions-input', 'true');
elmInputBox.bind('keydown', onInputBoxKeyDown);
elmInputBox.bind('keypress', onInputBoxKeyPress);
elmInputBox.bind('paste',onInputBoxPaste);
elmInputBox.bind('input', onInputBoxInput);
elmInputBox.bind('click', onInputBoxClick);
elmInputBox.bind('blur', onInputBoxBlur);
@ -208,6 +211,13 @@
hideAutoComplete();
}
function onInputBoxPaste(e) {
pastedData = e.originalEvent.clipboardData.getData("text/plain");
dataArray = pastedData.split("");
_.each(dataArray, function(value) {
inputBuffer.push(value);
});
}
function onInputBoxInput(e) {
updateValues();
updateMentionsCollection();
@ -223,7 +233,8 @@
}
function onInputBoxKeyPress(e) {
if(e.keyCode !== KEY.BACKSPACE) {
// Excluding ctrl+v from key press event in firefox
if (!((e.which === KEY.PASTE && e.ctrlKey) || (e.keyCode === KEY.BACKSPACE))) {
var typedValue = String.fromCharCode(e.which || e.keyCode);
inputBuffer.push(typedValue);
}

View file

@ -46,6 +46,14 @@ class Retraction
logger.info "event=retraction status=complete type=#{type} guid=#{post_guid}"
end
def correct_authorship?
if target.respond_to?(:relayable?) && target.relayable?
[target.author, target.parent.author].include?(person)
else
target.author == person
end
end
def receive(user, person)
if self.type == 'Person'
unless self.person.guid.to_s == self.post_guid.to_s
@ -55,7 +63,7 @@ class Retraction
return
end
user.disconnected_by(self.target)
elsif self.target.nil? || self.target.author != self.person
elsif target.nil? || !correct_authorship?
logger.warn "event=retraction status=abort reason='no post found authored by retractor' " \
"sender=#{person.diaspora_handle} post_guid=#{post_guid}"
else

View file

@ -69,6 +69,12 @@ module Diaspora
def receive(user, person=nil)
comment_or_like = self.class.where(guid: self.guid).first || self
unless comment_or_like.signature_valid?
logger.warn "event=receive status=abort reason='object signature not valid' recipient=#{user.diaspora_handle} "\
"sender=#{comment_or_like.author.diaspora_handle} payload_type=#{self.class} parent_id=#{parent.id}"
return
end
# Check to make sure the signature of the comment or like comes from the person claiming to author it
unless comment_or_like.parent_author == user.person || comment_or_like.verify_parent_author_signature
logger.warn "event=receive status=abort reason='object signature not valid' recipient=#{user.diaspora_handle} "\

View file

@ -24,7 +24,7 @@ class Postzord::Receiver::Public < Postzord::Receiver
parse_and_receive(@salmon.parsed_data)
logger.info "received a #{@object.inspect}"
if @object.is_a?(SignedRetraction) # feels like a hack
if @object.is_a?(SignedRetraction) || @object.is_a?(Retraction) # feels like a hack
self.recipient_user_ids.each do |user_id|
user = User.where(id: user_id).first
@object.perform user if user
@ -44,6 +44,11 @@ class Postzord::Receiver::Public < Postzord::Receiver
# receive relayable object only for the owner of the parent object
@object.receive(@object.parent_author.owner, @author)
end
unless @object.signature_valid?
@object.destroy
logger.warn "event=receive status=abort reason='object signature not valid' "
return
end
# notify everyone who can see the parent object
receiver = Postzord::Receiver::LocalBatch.new(@object, self.recipient_user_ids)
receiver.notify_users
@ -74,7 +79,11 @@ class Postzord::Receiver::Public < Postzord::Receiver
end
def xml_author
if @object.respond_to?(:relayable?)
if @object.is_a?(RelayableRetraction)
if [@object.parent_diaspora_handle, @object.target.parent.diaspora_handle].include?(@author.diaspora_handle)
@author.diaspora_handle
end
elsif @object.respond_to?(:relayable?)
#this is public, so it would only be owners sending us other people comments etc
@object.parent_author.local? ? @object.diaspora_handle : @object.parent_diaspora_handle
else

View file

@ -68,7 +68,7 @@ describe StreamsController, :type => :controller do
it "generates a jasmine fixture with a post containing a video", :fixture => true do
stub_request(
:get,
"http://www.youtube.com/oembed?format=json&frame=1&iframe=1&maxheight=420&maxwidth=420&scheme=https&url=http://www.youtube.com/watch?v=UYrkQL1bX4A"
"https://www.youtube.com/oembed?format=json&frame=1&iframe=1&maxheight=420&maxwidth=420&scheme=https&url=http://www.youtube.com/watch?v=UYrkQL1bX4A"
).with(
:headers => {'Accept'=>'*/*'}
).to_return(

View file

@ -46,7 +46,7 @@ describe NotificationsController, :type => :controller do
describe '#index' do
before do
@post = FactoryGirl.create(:status_message)
FactoryGirl.create(:notification, :recipient => alice, :target => @post)
@notification = FactoryGirl.create(:notification, recipient: alice, target: @post)
end
it 'succeeds' do
@ -56,8 +56,15 @@ describe NotificationsController, :type => :controller do
end
it 'succeeds for notification dropdown' do
Timecop.travel(6.seconds.ago) do
@notification.touch
end
get :index, :format => :json
expect(response).to be_success
note_html = JSON.parse(response.body)[0]["also_commented"]["note_html"]
note_html = Nokogiri::HTML(note_html)
timeago_content = note_html.css("time")[0]["data-time-ago"]
expect(timeago_content).to include(@notification.updated_at.iso8601)
expect(response.body).to match(/note_html/)
end
@ -84,7 +91,6 @@ describe NotificationsController, :type => :controller do
it "should not provide a contacts menu for standard notifications" do
FactoryGirl.create(:notification, :recipient => alice, :target => @post)
get :index, "per_page" => 5
expect(Nokogiri(response.body).css('.aspect_membership')).to be_empty
end

View file

@ -1,79 +0,0 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require 'spec_helper'
describe PublicsController, :type => :controller do
let(:fixture_path) { Rails.root.join('spec', 'fixtures') }
before do
@user = alice
@person = FactoryGirl.create(:person)
end
describe '#receive_public' do
it 'succeeds' do
post :receive_public, :xml => "<stuff/>"
expect(response).to be_success
end
it 'returns a 422 if no xml is passed' do
post :receive_public
expect(response.code).to eq('422')
end
it 'enqueues a ReceiveUnencryptedSalmon job' do
xml = "stuff"
expect(Workers::ReceiveUnencryptedSalmon).to receive(:perform_async).with(xml)
post :receive_public, :xml => xml
end
end
describe '#receive' do
let(:xml) { "<walruses></walruses>" }
it 'succeeds' do
post :receive, "guid" => @user.person.guid.to_s, "xml" => xml
expect(response).to be_success
end
it 'enqueues a receive job' do
expect(Workers::ReceiveEncryptedSalmon).to receive(:perform_async).with(@user.id, xml).once
post :receive, "guid" => @user.person.guid.to_s, "xml" => xml
end
it 'unescapes the xml before sending it to receive_salmon' do
aspect = @user.aspects.create(:name => 'foo')
post1 = @user.post(:status_message, :text => 'moms', :to => [aspect.id])
xml2 = post1.to_diaspora_xml
user2 = FactoryGirl.create(:user)
salmon_factory = Salmon::EncryptedSlap.create_by_user_and_activity(@user, xml2)
enc_xml = salmon_factory.xml_for(user2.person)
expect(Workers::ReceiveEncryptedSalmon).to receive(:perform_async).with(@user.id, enc_xml).once
post :receive, "guid" => @user.person.guid.to_s, "xml" => CGI::escape(enc_xml)
end
it 'returns a 422 if no xml is passed' do
post :receive, "guid" => @person.guid.to_s
expect(response.code).to eq('422')
end
it 'returns a 404 if no user is found' do
post :receive, "guid" => @person.guid.to_s, "xml" => xml
expect(response).to be_not_found
end
it 'returns a 404 if no person is found' do
post :receive, :guid => '2398rq3948yftn', :xml => xml
expect(response).to be_not_found
end
end
describe '#hub' do
it 'succeeds' do
get :hub
expect(response).to be_success
end
end
end

View file

@ -10,6 +10,9 @@ def r_str
SecureRandom.hex(3)
end
require "diaspora_federation/test"
DiasporaFederation::Test::Factories.federation_factories
FactoryGirl.define do
factory :profile do
sequence(:first_name) { |n| "Robert#{n}#{r_str}" }

View file

@ -1,4 +1,5 @@
require "spec_helper"
require "diaspora_federation/test"
describe "diaspora federation callbacks" do
describe ":fetch_person_for_webfinger" do
@ -12,6 +13,7 @@ describe "diaspora federation callbacks" do
expect(wf.profile_url).to eq(person.profile_url)
expect(wf.atom_url).to eq(person.atom_url)
expect(wf.salmon_url).to eq(person.receive_url)
expect(wf.subscribe_url).to eq(AppConfig.url_to("/people?q={uri}"))
expect(wf.guid).to eq(person.guid)
expect(wf.public_key).to eq(person.serialized_public_key)
end
@ -147,4 +149,151 @@ describe "diaspora federation callbacks" do
end
end
end
let(:local_person) { FactoryGirl.create(:user).person }
let(:remote_person) { FactoryGirl.create(:person) }
let(:post_by_a_local_person) { FactoryGirl.create(:status_message, author: local_person) }
let(:post_by_a_remote_person) { FactoryGirl.create(:status_message, author: remote_person) }
describe ":fetch_private_key_by_diaspora_id" do
it "returns a private key for a local user" do
key = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, local_person.diaspora_handle)
expect(key).to be_a(OpenSSL::PKey::RSA)
expect(key.to_s).to eq(local_person.owner.serialized_private_key)
end
it "returns nil for a remote user" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, remote_person.diaspora_handle)
).to be_nil
end
it "returns nil for an unknown id" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, FactoryGirl.generate(:diaspora_id))
).to be_nil
end
end
describe ":fetch_author_private_key_by_entity_guid" do
it "returns a private key for a post by a local user" do
key = DiasporaFederation.callbacks.trigger(:fetch_author_private_key_by_entity_guid,
"Post", post_by_a_local_person.guid)
expect(key).to be_a(OpenSSL::PKey::RSA)
expect(key.to_s).to eq(post_by_a_local_person.author.owner.serialized_private_key)
end
it "returns nil for a post by a remote user" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_author_private_key_by_entity_guid,
"Post", post_by_a_remote_person.guid)
).to be_nil
end
it "returns nil for an unknown post" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_author_private_key_by_entity_guid,
"Post", FactoryGirl.generate(:guid))
).to be_nil
end
end
describe ":fetch_public_key_by_diaspora_id" do
it "returns a public key for a person" do
key = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, remote_person.diaspora_handle)
expect(key).to be_a(OpenSSL::PKey::RSA)
expect(key.to_s).to eq(remote_person.serialized_public_key)
end
it "returns nil for an unknown person" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, FactoryGirl.generate(:diaspora_id))
).to be_nil
end
end
describe ":fetch_author_public_key_by_entity_guid" do
it "returns a public key for a known post" do
key = DiasporaFederation.callbacks.trigger(:fetch_author_public_key_by_entity_guid,
"Post", post_by_a_remote_person.guid)
expect(key).to be_a(OpenSSL::PKey::RSA)
expect(key.to_s).to eq(post_by_a_remote_person.author.serialized_public_key)
end
it "returns nil for an unknown post" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_author_public_key_by_entity_guid,
"Post", FactoryGirl.generate(:guid))
).to be_nil
end
end
describe ":entity_author_is_local?" do
it "returns true for a post by a local user" do
expect(
DiasporaFederation.callbacks.trigger(:entity_author_is_local?, "Post", post_by_a_local_person.guid)
).to be_truthy
end
it "returns false for a post by a remote user" do
expect(
DiasporaFederation.callbacks.trigger(:entity_author_is_local?, "Post", post_by_a_remote_person.guid)
).to be_falsey
end
it "returns false for a unknown post" do
expect(
DiasporaFederation.callbacks.trigger(:entity_author_is_local?, "Post", FactoryGirl.generate(:diaspora_id))
).to be_falsey
end
end
describe ":fetch_entity_author_id_by_guid" do
it "returns id for a existing guid" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_entity_author_id_by_guid, "Post", post_by_a_remote_person.guid)
).not_to eq(post_by_a_remote_person.author_id)
end
it "returns nil for a non-existing guid" do
expect(
DiasporaFederation.callbacks.trigger(:fetch_entity_author_id_by_guid, "Post", FactoryGirl.generate(:guid))
).to be_nil
end
end
describe ":queue_public_receive" do
it "enqueues a ReceiveUnencryptedSalmon job" do
xml = "<diaspora/>"
expect(Workers::ReceiveUnencryptedSalmon).to receive(:perform_async).with(xml)
DiasporaFederation.callbacks.trigger(:queue_public_receive, xml)
end
end
describe ":queue_private_receive" do
let(:xml) { "<diaspora/>" }
it "returns true if the user is found" do
result = DiasporaFederation.callbacks.trigger(:queue_private_receive, alice.person.guid, xml)
expect(result).to be_truthy
end
it "enqueues a ReceiveEncryptedSalmon job" do
expect(Workers::ReceiveEncryptedSalmon).to receive(:perform_async).with(alice.id, xml)
DiasporaFederation.callbacks.trigger(:queue_private_receive, alice.person.guid, xml)
end
it "returns false if the no user is found" do
person = FactoryGirl.create(:person)
result = DiasporaFederation.callbacks.trigger(:queue_private_receive, person.guid, xml)
expect(result).to be_falsey
end
it "returns false if the no person is found" do
result = DiasporaFederation.callbacks.trigger(:queue_private_receive, "2398rq3948yftn", xml)
expect(result).to be_falsey
end
end
end

View file

@ -0,0 +1,68 @@
def remote_user_on_pod_b
@remote_on_b ||= create_remote_user("remote-b.net")
end
def remote_user_on_pod_c
@remote_on_c ||= create_remote_user("remote-c.net")
end
def create_remote_user(pod)
FactoryGirl.build(:user).tap do |user|
user.person = FactoryGirl.create(:person,
profile: FactoryGirl.build(:profile),
serialized_public_key: user.encryption_key.public_key.export,
diaspora_handle: "#{user.username}@#{pod}")
allow(DiasporaFederation.callbacks).to receive(:trigger)
.with(:fetch_private_key_by_diaspora_id, user.diaspora_handle) {
user.encryption_key
}
end
end
def create_relayable_entity(entity_name, target, diaspora_id, parent_author_key)
target_entity_type = FactoryGirl.factory_by_name(entity_name).build_class.get_target_entity_type(@entity.to_h)
expect(DiasporaFederation.callbacks).to receive(:trigger)
.with(
:fetch_author_private_key_by_entity_guid,
target_entity_type,
target.guid
)
.and_return(parent_author_key)
FactoryGirl.build(
entity_name,
conversation_guid: target.guid,
parent_guid: target.guid,
diaspora_id: diaspora_id,
poll_answer_guid: target.respond_to?(:poll_answers) ? target.poll_answers.first.guid : nil
)
end
def generate_xml(entity, remote_user, recipient=nil)
if recipient
DiasporaFederation::Salmon::EncryptedSlap.generate_xml(
remote_user.diaspora_handle,
OpenSSL::PKey::RSA.new(remote_user.encryption_key),
entity,
OpenSSL::PKey::RSA.new(recipient.encryption_key)
)
else
DiasporaFederation::Salmon::Slap.generate_xml(
remote_user.diaspora_handle,
OpenSSL::PKey::RSA.new(remote_user.encryption_key),
entity
)
end
end
def post_message(xml, recipient=nil)
if recipient
inlined_jobs do
post "/receive/users/#{recipient.guid}", guid: recipient.guid, xml: xml
end
else
inlined_jobs do
post "/receive/public", xml: xml
end
end
end

View file

@ -0,0 +1,151 @@
require "spec_helper"
require "integration/federation/federation_helper"
require "integration/federation/shared_receive_relayable"
require "integration/federation/shared_receive_retraction"
require "integration/federation/shared_receive_stream_items"
describe "Receive federation messages feature" do
before do
allow(DiasporaFederation.callbacks).to receive(:trigger)
.with(:queue_public_receive, any_args).and_call_original
allow(DiasporaFederation.callbacks).to receive(:trigger)
.with(:queue_private_receive, any_args).and_call_original
end
let(:sender) { remote_user_on_pod_b }
let(:sender_id) { remote_user_on_pod_b.diaspora_handle }
context "with public receive" do
let(:recipient) { nil }
it "receives account deletion correctly" do
post_message(generate_xml(DiasporaFederation::Entities::AccountDeletion.new(diaspora_id: sender_id), sender))
expect(AccountDeletion.exists?(diaspora_handle: sender_id)).to be_truthy
end
it "rejects account deletion with wrong diaspora_id" do
delete_id = FactoryGirl.generate(:diaspora_id)
post_message(generate_xml(DiasporaFederation::Entities::AccountDeletion.new(diaspora_id: delete_id), sender))
expect(AccountDeletion.exists?(diaspora_handle: delete_id)).to be_falsey
expect(AccountDeletion.exists?(diaspora_handle: sender_id)).to be_falsey
end
context "reshare" do
it "reshare of public post passes" do
post = FactoryGirl.create(:status_message, author: alice.person, public: true)
reshare = FactoryGirl.build(
:reshare_entity, root_diaspora_id: alice.diaspora_handle, root_guid: post.guid, diaspora_id: sender_id)
post_message(generate_xml(reshare, sender))
expect(Reshare.exists?(root_guid: post.guid, diaspora_handle: sender_id)).to be_truthy
end
it "reshare of private post fails" do
post = FactoryGirl.create(:status_message, author: alice.person, public: false)
reshare = FactoryGirl.build(
:reshare_entity, root_diaspora_id: alice.diaspora_handle, root_guid: post.guid, diaspora_id: sender_id)
post_message(generate_xml(reshare, sender))
expect(Reshare.exists?(root_guid: post.guid, diaspora_handle: sender_id)).to be_falsey
end
end
it_behaves_like "messages which are indifferent about sharing fact"
context "with sharing" do
before do
contact = alice.contacts.find_or_initialize_by(person_id: sender.person.id)
contact.sharing = true
contact.save
end
it_behaves_like "messages which are indifferent about sharing fact"
it_behaves_like "messages which can't be send without sharing"
end
end
context "with private receive" do
let(:recipient) { alice }
it "treats sharing request recive correctly" do
entity = FactoryGirl.build(:request_entity, recipient_id: alice.diaspora_handle)
expect(Diaspora::Fetcher::Public).to receive(:queue_for).exactly(1).times
post_message(generate_xml(entity, sender, alice), alice)
expect(alice.contacts.count).to eq(2)
new_contact = alice.contacts.order(created_at: :asc).last
expect(new_contact).not_to be_nil
expect(new_contact.sharing).to eq(true)
expect(new_contact.person.diaspora_handle).to eq(sender_id)
expect(
Notifications::StartedSharing.exists?(
recipient_id: alice.id,
target_type: "Person",
target_id: sender.person.id
)
).to be_truthy
end
it "doesn't save the private status message if there is no sharing" do
entity = FactoryGirl.build(:status_message_entity, diaspora_id: sender_id, public: false)
post_message(generate_xml(entity, sender, alice), alice)
expect(StatusMessage.exists?(guid: entity.guid)).to be_falsey
end
context "with sharing" do
before do
contact = alice.contacts.find_or_initialize_by(person_id: sender.person.id)
contact.sharing = true
contact.save
end
it_behaves_like "messages which are indifferent about sharing fact"
it_behaves_like "messages which can't be send without sharing"
it "treats profile receive correctly" do
entity = FactoryGirl.build(:profile_entity, diaspora_id: sender_id)
post_message(generate_xml(entity, sender, alice), alice)
expect(Profile.exists?(diaspora_handle: entity.diaspora_id)).to be_truthy
end
it "receives conversation correctly" do
entity = FactoryGirl.build(
:conversation_entity,
diaspora_id: sender_id,
participant_ids: "#{sender_id};#{alice.diaspora_handle}"
)
post_message(generate_xml(entity, sender, alice), alice)
expect(Conversation.exists?(guid: entity.guid)).to be_truthy
end
context "with message" do
let(:local_target) {
FactoryGirl.build(:conversation, author: alice.person).tap do |target|
target.participants << remote_user_on_pod_b.person
target.participants << remote_user_on_pod_c.person
target.save
end
}
let(:remote_target) {
FactoryGirl.build(:conversation, author: remote_user_on_pod_b.person).tap do |target|
target.participants << alice.person
target.participants << remote_user_on_pod_c.person
target.save
end
}
let(:entity_name) { :message_entity }
let(:klass) { Message }
it_behaves_like "it deals correctly with a relayable"
end
end
end
end

View file

@ -0,0 +1,59 @@
shared_examples_for "it deals correctly with a relayable" do
context "local" do
let(:entity) { create_relayable_entity(entity_name, local_target, sender_id, nil) }
it "treats upstream receive correctly" do
expect(Postzord::Dispatcher).to receive(:build).with(alice, kind_of(klass)).and_call_original
post_message(generate_xml(entity, sender, recipient), recipient)
received_entity = klass.find_by(guid: entity.guid)
expect(received_entity).not_to be_nil
expect(received_entity.author.diaspora_handle).to eq(remote_user_on_pod_b.diaspora_handle)
end
# Checks when a remote pod wants to send us a relayable without having a key for declared diaspora ID
it "rejects an upstream entity with a malformed author signature" do
expect(Postzord::Dispatcher).not_to receive(:build)
allow(remote_user_on_pod_b).to receive(:encryption_key).and_return(OpenSSL::PKey::RSA.new(1024))
post_message(generate_xml(entity, sender, recipient), recipient)
expect(klass.exists?(guid: entity.guid)).to be_falsey
end
end
context "remote" do
let(:author_id) { remote_user_on_pod_c.diaspora_handle }
let(:entity) { create_relayable_entity(entity_name, remote_target, author_id, sender.encryption_key) }
it "treats downstream receive correctly" do
expect(Postzord::Dispatcher).to receive(:build)
.with(alice, kind_of(klass)).and_call_original unless recipient.nil?
post_message(generate_xml(entity, sender, recipient), recipient)
received_entity = klass.find_by(guid: entity.guid)
expect(received_entity).not_to be_nil
expect(received_entity.author.diaspora_handle).to eq(remote_user_on_pod_c.diaspora_handle)
end
# Checks when a remote pod B wants to send us a relayable with authorship from a remote pod C user
# without having correct signature from him.
it "rejects a downstream entity with a malformed author signature" do
expect(Postzord::Dispatcher).not_to receive(:build)
allow(remote_user_on_pod_c).to receive(:encryption_key).and_return(OpenSSL::PKey::RSA.new(1024))
post_message(generate_xml(entity, sender, recipient), recipient)
expect(klass.exists?(guid: entity.guid)).to be_falsey
end
# Checks when a remote pod C wants to send us a relayable from its user, but bypassing the pod B where
# remote status came from.
it "declines downstream receive when sender signed with a wrong key" do
expect(Postzord::Dispatcher).not_to receive(:build)
allow(sender).to receive(:encryption_key).and_return(OpenSSL::PKey::RSA.new(1024))
post_message(generate_xml(entity, sender, recipient), recipient)
expect(klass.exists?(guid: entity.guid)).to be_falsey
end
end
end

View file

@ -0,0 +1,57 @@
def retraction_entity(entity_name, target_object, sender)
allow(DiasporaFederation.callbacks).to receive(:trigger)
.with(
:fetch_entity_author_id_by_guid,
target_object.class.to_s,
target_object.guid
)
.and_return(sender.encryption_key)
FactoryGirl.build(
entity_name,
diaspora_id: sender.diaspora_handle,
target_guid: target_object.guid,
target_type: target_object.class.to_s
)
end
shared_examples_for "it retracts non-relayable object" do
it "retracts object by a correct retraction message" do
entity = retraction_entity(entity_name, target_object, sender)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(target_object.class.exists?(guid: target_object.guid)).to be_falsey
end
it "doesn't retract object when retraction has wrong signatures" do
allow(sender).to receive(:encryption_key).and_return(OpenSSL::PKey::RSA.new(1024))
entity = retraction_entity(entity_name, target_object, sender)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(target_object.class.exists?(guid: target_object.guid)).to be_truthy
end
it "doesn't retract object when sender is different from target object" do
entity = retraction_entity(entity_name, target_object, remote_user_on_pod_c)
post_message(generate_xml(entity, remote_user_on_pod_c, recipient), recipient)
expect(target_object.class.exists?(guid: target_object.guid)).to be_truthy
end
end
shared_examples_for "it retracts relayable object" do
it "retracts object by a correct message" do
entity = retraction_entity(entity_name, target_object, sender)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(target_object.class.exists?(guid: target_object.guid)).to be_falsey
end
it "doesn't retract object when retraction has wrong signatures" do
allow(sender).to receive(:encryption_key).and_return(OpenSSL::PKey::RSA.new(1024))
entity = retraction_entity(entity_name, target_object, sender)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(target_object.class.exists?(guid: target_object.guid)).to be_truthy
end
end

View file

@ -0,0 +1,166 @@
# by "stream items" we mean everything that could appear in the stream - post, comment, like, poll, etc and therefore
# could be send either publicly or privately
shared_examples_for "messages which are indifferent about sharing fact" do
let(:public) { recipient.nil? }
it "treats status message receive correctly" do
entity = FactoryGirl.build(:status_message_entity, diaspora_id: sender_id, public: public)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(StatusMessage.exists?(guid: entity.guid)).to be_truthy
end
it "doesn't accept status message with wrong signature" do
allow(sender).to receive(:encryption_key).and_return(OpenSSL::PKey::RSA.new(1024))
entity = FactoryGirl.build(:status_message_entity, diaspora_id: sender_id, public: public)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(StatusMessage.exists?(guid: entity.guid)).to be_falsey
end
describe "with messages which require a status to operate on" do
let(:local_target) { FactoryGirl.create(:status_message, author: alice.person, public: public) }
let(:remote_target) { FactoryGirl.create(:status_message, author: remote_user_on_pod_b.person, public: public) }
describe "notifications are sent where required" do
it "for comment on local post" do
entity = create_relayable_entity(:comment_entity, local_target, remote_user_on_pod_b.diaspora_handle, nil)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(
Notifications::CommentOnPost.exists?(
recipient_id: alice.id,
target_type: "Post",
target_id: local_target.id
)
).to be_truthy
end
it "for like on local post" do
entity = create_relayable_entity(:like_entity, local_target, remote_user_on_pod_b.diaspora_handle, nil)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(
Notifications::Liked.exists?(
recipient_id: alice.id,
target_type: "Post",
target_id: local_target.id
)
).to be_truthy
end
end
%w(comment like participation).each do |entity|
context "with #{entity}" do
let(:entity_name) { "#{entity}_entity".to_sym }
let(:klass) { entity.camelize.constantize }
it_behaves_like "it deals correctly with a relayable"
end
end
context "with poll_participation" do
let(:local_target) {
FactoryGirl.create(
:poll,
status_message: FactoryGirl.create(:status_message, author: alice.person, public: public)
)
}
let(:remote_target) {
FactoryGirl.create(
:poll,
status_message: FactoryGirl.create(:status_message, author: remote_user_on_pod_b.person, public: public)
)
}
let(:entity_name) { :poll_participation_entity }
let(:klass) { PollParticipation }
it_behaves_like "it deals correctly with a relayable"
end
end
end
shared_examples_for "messages which can't be send without sharing" do
# retractions shouldn't depend on sharing fact
describe "retractions for non-relayable objects" do
%w(retraction signed_retraction).each do |retraction_entity_name|
context "with #{retraction_entity_name}" do
let(:entity_name) { "#{retraction_entity_name}_entity".to_sym }
%w(status_message photo).each do |target|
context "with #{target}" do
let(:target_object) { FactoryGirl.create(target.to_sym, author: remote_user_on_pod_b.person) }
it_behaves_like "it retracts non-relayable object"
end
end
end
end
end
describe "with messages which require a status to operate on" do
let(:public) { recipient.nil? }
let(:local_target) { FactoryGirl.create(:status_message, author: alice.person, public: public) }
let(:remote_target) { FactoryGirl.create(:status_message, author: remote_user_on_pod_b.person, public: public) }
# this one shouldn't depend on the sharing fact. this must be fixed
describe "notifications are sent where required" do
it "for comment on remote post where we participate" do
alice.participate!(remote_target)
author_id = remote_user_on_pod_c.diaspora_handle
entity = create_relayable_entity(:comment_entity, remote_target, author_id, sender.encryption_key)
post_message(generate_xml(entity, sender, recipient), recipient)
expect(
Notifications::AlsoCommented.exists?(
recipient_id: alice.id,
target_type: "Post",
target_id: remote_target.id
)
).to be_truthy
end
end
describe "retractions for relayable objects" do
%w(retraction signed_retraction relayable_retraction).each do |retraction_entity_name|
context "with #{retraction_entity_name}" do
let(:entity_name) { "#{retraction_entity_name}_entity".to_sym }
context "with comment" do
it_behaves_like "it retracts relayable object" do
# case for to-upstream federation
let(:target_object) {
FactoryGirl.create(:comment, author: remote_user_on_pod_b.person, post: local_target)
}
end
it_behaves_like "it retracts relayable object" do
# case for to-downsteam federation
let(:target_object) {
FactoryGirl.create(:comment, author: remote_user_on_pod_c.person, post: remote_target)
}
end
end
context "with like" do
it_behaves_like "it retracts relayable object" do
# case for to-upstream federation
let(:target_object) {
FactoryGirl.create(:like, author: remote_user_on_pod_b.person, target: local_target)
}
end
it_behaves_like "it retracts relayable object" do
# case for to-downsteam federation
let(:target_object) {
FactoryGirl.create(:like, author: remote_user_on_pod_c.person, target: remote_target)
}
end
end
end
end
end
end
end

View file

@ -97,7 +97,7 @@ describe("app.helpers.textFormatter", function(){
it("works with markdown", function(){
var code = "```markdown\n# header\n**strong**\n```";
expect(this.formatter(code)).toContain("<span class=\"hljs-header\">");
expect(this.formatter(code)).toContain("<span class=\"hljs-section\">");
expect(this.formatter(code)).toContain("<span class=\"hljs-strong\">");
});

View file

@ -1,11 +1,57 @@
describe("app.views.Hovercard", function() {
beforeEach(function() {
this.view = new app.views.Hovercard();
context("user not signed in", function() {
beforeEach(function() {
logout();
this.view = new app.views.Hovercard();
});
describe("_populateHovercardWith", function() {
it("doesn't fetch the aspect dropdown", function() {
spyOn(jQuery, "ajax").and.callThrough();
this.view.parent = spec.content();
this.view._populateHovercardWith({});
expect(jQuery.ajax).not.toHaveBeenCalled();
});
});
});
describe("mouseIsOverElement", function() {
it("returns false if the element is undefined", function() {
expect(this.view.mouseIsOverElement(undefined, $.Event())).toBeFalsy();
context("user signed in", function() {
beforeEach(function() {
loginAs(factory.userAttrs());
this.view = new app.views.Hovercard();
});
describe("initialize", function() {
it("activates hovercards", function() {
expect(this.view.active).toBeTruthy();
});
});
describe("mouseIsOverElement", function() {
it("returns false if the element is undefined", function() {
expect(this.view.mouseIsOverElement(undefined, $.Event())).toBeFalsy();
});
});
describe("_populateHovercard", function() {
it("prevents global error handling for the ajax call", function() {
spyOn(jQuery, "ajax").and.callThrough();
this.view.parent = spec.content();
this.view._populateHovercard();
expect(jQuery.ajax).toHaveBeenCalledWith("undefined/hovercard.json", {preventGlobalErrorHandling: true});
});
});
describe("_populateHovercardWith", function() {
it("prevents global error handling for the ajax call", function() {
spyOn(jQuery, "ajax").and.callThrough();
this.view.parent = spec.content();
this.view._populateHovercardWith({});
expect(jQuery.ajax).toHaveBeenCalledWith(
"undefined/aspect_membership_button",
{preventGlobalErrorHandling: true}
);
});
});
});
});

View file

@ -97,8 +97,10 @@ describe Notification, :type => :model do
p = FactoryGirl.build(:status_message, :author => @user.person)
person2 = FactoryGirl.build(:person)
notification = Notification.notify(@user, FactoryGirl.build(:like, :author => @person, :target => p), @person)
earlier_updated_at = notification.updated_at
notification2 = Notification.notify(@user, FactoryGirl.build(:like, :author => person2, :target => p), person2)
expect(notification.id).to eq(notification2.id)
expect(earlier_updated_at).to_not eq(notification.reload.updated_at)
end
end
@ -107,8 +109,10 @@ describe Notification, :type => :model do
p = FactoryGirl.build(:status_message, :author => @user.person)
person2 = FactoryGirl.build(:person)
notification = Notification.notify(@user, FactoryGirl.build(:comment, :author => @person, :post => p), @person)
earlier_updated_at = notification.updated_at
notification2 = Notification.notify(@user, FactoryGirl.build(:comment, :author => person2, :post => p), person2)
expect(notification.id).to eq(notification2.id)
expect(earlier_updated_at).to_not eq(notification.reload.updated_at)
end
end

View file

@ -73,6 +73,8 @@ RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
config.mock_with :rspec
config.example_status_persistence_file_path = "tmp/rspec-persistance.txt"
config.render_views
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!

View file

@ -34,11 +34,11 @@ FixtureBuilder.configure do |fbuilder|
local_leia.contacts.create(:person => remote_raphael, :aspects => [leias_aspect])
local_luke.contacts.create(:person => remote_raphael, :aspects => [lukes_aspect])
# Set up a follower
peter = FactoryGirl.create(:user_with_aspect, :username => "peter")
peters_aspect = peter.aspects.where(:name => "generic").first
peter.contacts.create!(:person => alice.person,
:aspects => [peters_aspect],
:sharing => false,