mirror of
https://github.com/diaspora/diaspora.git
synced 2026-01-13 00:57:58 -05:00
Compare commits
445 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f042f5d490 | ||
|
|
42b835f0c0 | ||
|
|
52f206fa8a | ||
|
|
9075dfa470 | ||
|
|
9485a02639 | ||
|
|
eaedd3d26c | ||
|
|
65909700f3 | ||
|
|
586b319c79 | ||
|
|
646685b42c | ||
|
|
78b28c3d54 | ||
|
|
b29675fead | ||
|
|
eb1c571511 | ||
|
|
4efc4dabf8 | ||
|
|
01f8f55dbb | ||
|
|
49ba740b45 | ||
|
|
e984fa7d91 | ||
|
|
428c97d089 | ||
|
|
3cf84c838f | ||
|
|
ee68da7eeb | ||
|
|
2e3bd14a09 | ||
|
|
3c4da76be5 | ||
|
|
3b02eb87bd | ||
|
|
c72b30130e | ||
|
|
01ab639736 | ||
|
|
8a1e3fbec2 | ||
|
|
c1c9469840 | ||
|
|
3bb9b9a18d | ||
|
|
fe84d3e101 | ||
|
|
1ef3c83a0a | ||
|
|
ac86c29a85 | ||
|
|
17b84d3ddd | ||
|
|
b5a46cf7bb | ||
|
|
2d38a24a86 | ||
|
|
2f30b42d93 | ||
|
|
14e27a65ae | ||
|
|
429aa8f374 | ||
|
|
0382cb48c1 | ||
|
|
13eb095e83 | ||
|
|
3598a17ee2 | ||
|
|
a5e5c7f378 | ||
|
|
dd3bc39c97 | ||
|
|
3c02a1f067 | ||
|
|
a9ae84f3a6 | ||
|
|
6cea355636 | ||
|
|
f76a8d7deb | ||
|
|
41633fcea9 | ||
|
|
a7a02e87cf | ||
|
|
485af7ea78 | ||
|
|
5f48cedb84 | ||
|
|
739fc780c3 | ||
|
|
2d9f133d30 | ||
|
|
3ff162320e | ||
|
|
edbb26b926 | ||
|
|
9b23411d25 | ||
|
|
6753761c74 | ||
|
|
86f306fce8 | ||
|
|
b48c72f188 | ||
|
|
47d0269043 | ||
|
|
a1b6209415 | ||
|
|
7d7549e01e | ||
|
|
25f5236d66 | ||
|
|
f044030db0 | ||
|
|
e3e7d2daab | ||
|
|
9189dbf348 | ||
|
|
796047f543 | ||
|
|
61a560a58d | ||
|
|
aa0ac5bec6 | ||
|
|
1ba9416e22 | ||
|
|
c0450cbe9d | ||
|
|
8ccf94a587 | ||
|
|
5238bb4c5d | ||
|
|
e096c96c44 | ||
|
|
a5a0b28d39 | ||
|
|
ca40ca202a | ||
|
|
077bac95c0 | ||
|
|
dc1ec7665b | ||
|
|
d97ff9afce | ||
|
|
8c4381c1ce | ||
|
|
db74b364d6 | ||
|
|
5b298e330c | ||
|
|
3d8cdc78e0 | ||
|
|
d801adcb6e | ||
|
|
4076eb3fcf | ||
|
|
7447beb04a | ||
|
|
a8dc10f5ad | ||
|
|
0f7ea165f7 | ||
|
|
6fadfb30fe | ||
|
|
107f118db4 | ||
|
|
ae5333d67d | ||
|
|
4fe52a72f1 | ||
|
|
4588ce11c9 | ||
|
|
d14036b630 | ||
|
|
637dad208a | ||
|
|
4548380080 | ||
|
|
b67cf8e983 | ||
|
|
ef7a5f8d6e | ||
|
|
688245c0de | ||
|
|
245bc1a05f | ||
|
|
df4504979e | ||
|
|
e5b65f6498 | ||
|
|
cb774d1c50 | ||
|
|
692f5fdafb | ||
|
|
37d440f91e | ||
|
|
baeeee8e73 | ||
|
|
23c2487550 | ||
|
|
94956a2eda | ||
|
|
09ecaec0b5 | ||
|
|
2b352b86ae | ||
|
|
1c577fb5b2 | ||
|
|
b2ee986815 | ||
|
|
ae3bd1f62e | ||
|
|
b195861483 | ||
|
|
4e4d332d6e | ||
|
|
56ef83fa8a | ||
|
|
f4234fa3a0 | ||
|
|
f85135f726 | ||
|
|
0831d4e294 | ||
|
|
058090afe7 | ||
|
|
02eba842ae | ||
|
|
9212fd3f46 | ||
|
|
31ea07daa1 | ||
|
|
43ee2dbb50 | ||
|
|
8e6f3b91d3 | ||
|
|
1cfe0037f9 | ||
|
|
f88807909c | ||
|
|
6ad4eb3be7 | ||
|
|
7611391f9f | ||
|
|
d896744ca1 | ||
|
|
82291ed7e7 | ||
|
|
d7fb7405ae | ||
|
|
d4800544f0 | ||
|
|
eb977dc25a | ||
|
|
1570e3fb9a | ||
|
|
c67fc4e0f7 | ||
|
|
f6c885394d | ||
|
|
37f081959c | ||
|
|
f69215edf1 | ||
|
|
ec22f5883e | ||
|
|
fbd14c8804 | ||
|
|
b8e5021dd1 | ||
|
|
862796131f | ||
|
|
a5f59ef105 | ||
|
|
eea6d71c8d | ||
|
|
c8fba1ffad | ||
|
|
fe0c143c89 | ||
|
|
62f98dcaff | ||
|
|
19f6057ded | ||
|
|
ae6b5a634c | ||
|
|
cd32959b93 | ||
|
|
6e8a0dd66a | ||
|
|
b3c13bc49e | ||
|
|
fef6380721 | ||
|
|
9548a3645c | ||
|
|
51a46f60f1 | ||
|
|
a66bfc9614 | ||
|
|
10f62391d4 | ||
|
|
a0646e9363 | ||
|
|
2eb52cedec | ||
|
|
67069b1519 | ||
|
|
ad24678be3 | ||
|
|
f27b4ae920 | ||
|
|
c939829912 | ||
|
|
39ab87d111 | ||
|
|
8a3c9a2463 | ||
|
|
5714e83ab2 | ||
|
|
3cb1e470a4 | ||
|
|
88e2e593a4 | ||
|
|
3292ce64fc | ||
|
|
89cd77751f | ||
|
|
d22ae06cff | ||
|
|
af9f26d11c | ||
|
|
5b3f75f011 | ||
|
|
dc99f0f77a | ||
|
|
59baef3146 | ||
|
|
0bb4ffce89 | ||
|
|
b2a56376cd | ||
|
|
4c337c6952 | ||
|
|
d39a4e3621 | ||
|
|
fab48ee96d | ||
|
|
b8ea120ff2 | ||
|
|
2a99cc93ba | ||
|
|
8f9ac33649 | ||
|
|
c71caa5cb8 | ||
|
|
122e12a068 | ||
|
|
28f03f0a11 | ||
|
|
8392c894d2 | ||
|
|
b2ba0123e1 | ||
|
|
8691e650dc | ||
|
|
20a3abd864 | ||
|
|
07a49de7e1 | ||
|
|
7d0c29e99a | ||
|
|
7e9987b7f5 | ||
|
|
805a35e985 | ||
|
|
407f51d5a3 | ||
|
|
8f804e376a | ||
|
|
342d4f7fde | ||
|
|
b31f9106a1 | ||
|
|
7b73002a2c | ||
|
|
c203c1eb94 | ||
|
|
c1093abaef | ||
|
|
319d5b55d9 | ||
|
|
6b48580373 | ||
|
|
da68d363a0 | ||
|
|
2f29bb3035 | ||
|
|
b08202f51d | ||
|
|
053a93ea08 | ||
|
|
e790e01753 | ||
|
|
0e81a2da86 | ||
|
|
2fd82c92dd | ||
|
|
72b66a2782 | ||
|
|
72ad6fd23b | ||
|
|
29ea68737d | ||
|
|
c98598b8bc | ||
|
|
edccab4ab3 | ||
|
|
414638476e | ||
|
|
8eb2a9ca12 | ||
|
|
e1061c3d5c | ||
|
|
096297bd86 | ||
|
|
dc3bef6a93 | ||
|
|
0c4d9bb702 | ||
|
|
ca44e91de6 | ||
|
|
93fae13cab | ||
|
|
bd68e8ec83 | ||
|
|
22f0538464 | ||
|
|
486026a1b6 | ||
|
|
32e580b3ec | ||
|
|
2a22bb01c4 | ||
|
|
b375bfa630 | ||
|
|
77edc5105e | ||
|
|
43d489edda | ||
|
|
3793d36609 | ||
|
|
b2b03d2679 | ||
|
|
92a096f03c | ||
|
|
1f510d0b40 | ||
|
|
7042237218 | ||
|
|
d4331f4e65 | ||
|
|
ba905334f7 | ||
|
|
1d0982822b | ||
|
|
33b7d3253a | ||
|
|
0fcd166387 | ||
|
|
cba2b9a3a9 | ||
|
|
22815abb22 | ||
|
|
6e55ae7b5e | ||
|
|
6f9c52e2b4 | ||
|
|
231ca2c3b1 | ||
|
|
24e8be37c2 | ||
|
|
1d8b9bde43 | ||
|
|
a18defc90f | ||
|
|
e4164eb18f | ||
|
|
a36ffff5f7 | ||
|
|
2412ee390d | ||
|
|
f949ae2aab | ||
|
|
b4b4efbab1 | ||
|
|
7277200bc5 | ||
|
|
7960a51d12 | ||
|
|
f55237ca6b | ||
|
|
52f08f1178 | ||
|
|
aa51329a49 | ||
|
|
62bb4dc7b6 | ||
|
|
f52dbe570d | ||
|
|
8d7b866c87 | ||
|
|
ee35ad3200 | ||
|
|
cb675f5c8d | ||
|
|
4c6937838d | ||
|
|
18ea3343fd | ||
|
|
cd9f79a018 | ||
|
|
394eafccc5 | ||
|
|
ef9e764f7a | ||
|
|
a420ba2cfc | ||
|
|
a98fdc8079 | ||
|
|
7154fc3ccc | ||
|
|
cd6eb3de7f | ||
|
|
79133df4a9 | ||
|
|
e7c5da2fff | ||
|
|
d7941230a4 | ||
|
|
d5d53baa1c | ||
|
|
7a7c48a470 | ||
|
|
875f54b846 | ||
|
|
1faddbc911 | ||
|
|
98e70c8221 | ||
|
|
cfd5397cfc | ||
|
|
d9013250fd | ||
|
|
f51ad14c1b | ||
|
|
6f3d68110a | ||
|
|
8bca84422e | ||
|
|
e1aff7e3ab | ||
|
|
203ca77a2f | ||
|
|
9793f89761 | ||
|
|
e24eb65ca4 | ||
|
|
b8a85850e1 | ||
|
|
d0eb711ca0 | ||
|
|
2aaf37659d | ||
|
|
c268495e04 | ||
|
|
ce82ba3dde | ||
|
|
2acdc8e095 | ||
|
|
08395cc877 | ||
|
|
9dff9642b6 | ||
|
|
0937bfc420 | ||
|
|
d061c4e2cf | ||
|
|
4ca68a71d9 | ||
|
|
3c124cefc3 | ||
|
|
9771a96add | ||
|
|
efa89cc2f3 | ||
|
|
77062cbcaf | ||
|
|
ad91dddd63 | ||
|
|
7193099902 | ||
|
|
f882dd2d6f | ||
|
|
827a2ce991 | ||
|
|
ba8e0907cc | ||
|
|
38d746b240 | ||
|
|
bd7feb83a6 | ||
|
|
813e6d4781 | ||
|
|
9b6bc59854 | ||
|
|
3a3a9008b6 | ||
|
|
1da14f2ef7 | ||
|
|
bec7e77e9e | ||
|
|
4a5610df2f | ||
|
|
a7119fa7c1 | ||
|
|
abec056c02 | ||
|
|
60a50c881d | ||
|
|
de4a416280 | ||
|
|
3042b385c6 | ||
|
|
a7f3ea976f | ||
|
|
33405d6ee6 | ||
|
|
a681b317f3 | ||
|
|
db8bc5d874 | ||
|
|
04c545ef7d | ||
|
|
ecdf130bcd | ||
|
|
a4dd210669 | ||
|
|
8913a30d57 | ||
|
|
d6814878e9 | ||
|
|
78b62dd3ed | ||
|
|
c74b0ab611 | ||
|
|
3eba2f3fa3 | ||
|
|
d9ef60b8b3 | ||
|
|
05ee8f3db0 | ||
|
|
872d87c772 | ||
|
|
27493cee41 | ||
|
|
d0e5f90f84 | ||
|
|
25a6c9583f | ||
|
|
e5e4189569 | ||
|
|
8f0826a8bc | ||
|
|
9c7d9186f6 | ||
|
|
d3210f1154 | ||
|
|
d5c22c3e49 | ||
|
|
ea4b670582 | ||
|
|
9c449b0298 | ||
|
|
fa26c29bb2 | ||
|
|
7f90110696 | ||
|
|
8779a15e27 | ||
|
|
196f0699b0 | ||
|
|
19314f8a94 | ||
|
|
90926d95e9 | ||
|
|
95aaa7a140 | ||
|
|
95f08ac9af | ||
|
|
f0f8cf334c | ||
|
|
195780122b | ||
|
|
403960811f | ||
|
|
659bdf4b7a | ||
|
|
ffa69df704 | ||
|
|
2d742ec0ff | ||
|
|
95422c7566 | ||
|
|
fc6d736471 | ||
|
|
2149ebb2df | ||
|
|
e046a4cc3a | ||
|
|
4ac1b9ae87 | ||
|
|
eb7a71a2a5 | ||
|
|
b325d2ca43 | ||
|
|
7ec921c956 | ||
|
|
d561d2caf1 | ||
|
|
67924fc404 | ||
|
|
51e7eae2c3 | ||
|
|
b54679a634 | ||
|
|
b146c90e57 | ||
|
|
9211f930cd | ||
|
|
00c5f35190 | ||
|
|
c432a658dd | ||
|
|
c2a991fec1 | ||
|
|
6f65d9f96c | ||
|
|
b0181fbbb9 | ||
|
|
ec72ac1277 | ||
|
|
bc601f7c34 | ||
|
|
905df19a34 | ||
|
|
43b83cf8f7 | ||
|
|
d898b5ba69 | ||
|
|
b7ee911778 | ||
|
|
67d73ece80 | ||
|
|
71023a8713 | ||
|
|
2e2b42ef1a | ||
|
|
4685df634c | ||
|
|
e40a07f204 | ||
|
|
45e8b54bea | ||
|
|
35da56109f | ||
|
|
75ef13b5d1 | ||
|
|
25e9728fae | ||
|
|
93b0e1eb22 | ||
|
|
1e642be040 | ||
|
|
1d72f95705 | ||
|
|
36b4076af6 | ||
|
|
3856b44c57 | ||
|
|
ba16185b8e | ||
|
|
6937fa13e5 | ||
|
|
5b09e9d38d | ||
|
|
6a7e937d90 | ||
|
|
593614aef1 | ||
|
|
b42c9896bc | ||
|
|
df4e79b842 | ||
|
|
397dbdbee8 | ||
|
|
68234fc91f | ||
|
|
2b8cc070f2 | ||
|
|
18d6d39c62 | ||
|
|
6ede2ade7b | ||
|
|
4b2414c9eb | ||
|
|
b654ca7f82 | ||
|
|
5278ae6a96 | ||
|
|
4b921816eb | ||
|
|
2503934a04 | ||
|
|
cde29af545 | ||
|
|
1e2e064268 | ||
|
|
435e60c214 | ||
|
|
51e7958c4b | ||
|
|
18b0dd0060 | ||
|
|
26b247bf98 | ||
|
|
800676a90f | ||
|
|
556fa42004 | ||
|
|
1458d2d57f | ||
|
|
d2c4faeb9f | ||
|
|
3a1428a672 | ||
|
|
06c582a672 | ||
|
|
fa08ebf7bd | ||
|
|
c059550943 | ||
|
|
ee503737cb | ||
|
|
a6261fdc64 | ||
|
|
56670865b9 | ||
|
|
325a9122b8 | ||
|
|
a018abcfe9 | ||
|
|
8f5c248536 | ||
|
|
e2ce43c3c7 | ||
|
|
c154c4e2af | ||
|
|
07513e2ec0 | ||
|
|
b1441356d2 | ||
|
|
e7a7f62531 | ||
|
|
4ae373e3a2 | ||
|
|
4cef2a4325 | ||
|
|
d674f53910 |
63
.github/workflows/ci.yml
vendored
Normal file
63
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- next-minor
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ruby:
|
||||
- 2.7
|
||||
- 2.6
|
||||
db:
|
||||
- mysql
|
||||
- postgresql
|
||||
kind:
|
||||
- cucumber
|
||||
- other
|
||||
env:
|
||||
DB: ${{ matrix.db }}
|
||||
RAILS_ENV: test
|
||||
BUNDLE_WITH: ${{ matrix.db }}
|
||||
BUNDLE_WITHOUT: development
|
||||
BUNDLE_FROZEN: true
|
||||
BUNDLE_DISABLE_SHARED_GEMS: true
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- name: Install system dependencies
|
||||
run: sudo apt update && sudo apt install -y build-essential curl git gsfonts imagemagick libcurl4-openssl-dev libidn11-dev libmagickwand-dev libssl-dev libxml2-dev libxslt1-dev
|
||||
- name: Start MySQL
|
||||
run: sudo systemctl start mysql.service
|
||||
if: matrix.db == 'mysql'
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby }}
|
||||
bundler-cache: true
|
||||
- name: Prepare
|
||||
run: script/ci/prepare.sh
|
||||
- name: Run tests
|
||||
run: bin/rake --trace ci:${{ matrix.kind }}
|
||||
- name: Run Jasmine
|
||||
run: bin/rake jasmine:ci
|
||||
timeout-minutes: 2
|
||||
if: matrix.kind == 'other'
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -9,6 +9,7 @@ app/views/terms/terms.*
|
||||
app/assets/images/custom/
|
||||
|
||||
# Configuration files
|
||||
config/diaspora.toml
|
||||
config/diaspora.yml
|
||||
config/initializers/secret_token.rb
|
||||
.bundle
|
||||
@@ -81,3 +82,9 @@ diaspora.iml
|
||||
|
||||
# WebTranslateIt
|
||||
.wti
|
||||
|
||||
# MacOS
|
||||
/__MACOSX/
|
||||
|
||||
# yarn
|
||||
node_modules
|
||||
|
||||
29
.rubocop.yml
29
.rubocop.yml
@@ -1,19 +1,19 @@
|
||||
require: rubocop-rails
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.3
|
||||
TargetRubyVersion: 2.6
|
||||
NewCops: enable
|
||||
Exclude:
|
||||
- "bin/**/*"
|
||||
- "db/schema.rb"
|
||||
- "config/locales/cldr/plurals.rb"
|
||||
|
||||
Rails:
|
||||
Enabled: true
|
||||
|
||||
# Disable for rails 4
|
||||
Rails/HttpPositionalArguments:
|
||||
Enabled: false
|
||||
|
||||
# Commonly used screens these days easily fit more than 80 characters.
|
||||
Metrics/LineLength:
|
||||
Layout/LineLength:
|
||||
Max: 120
|
||||
|
||||
# Too short methods lead to extraction of single-use methods, which can make
|
||||
@@ -57,13 +57,19 @@ 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:
|
||||
Enabled: true
|
||||
|
||||
# Most readable form.
|
||||
Layout/AlignHash:
|
||||
Layout/HashAlignment:
|
||||
EnforcedHashRocketStyle: table
|
||||
EnforcedColonStyle: table
|
||||
|
||||
@@ -85,7 +91,6 @@ Style/CollectionMethods:
|
||||
# inject seems more common in the community.
|
||||
reduce: "inject"
|
||||
|
||||
|
||||
# Either allow this style or don't. Marking it as safe with parenthesis
|
||||
# is silly. Let's try to live without them for now.
|
||||
Style/ParenthesesAroundCondition:
|
||||
@@ -112,7 +117,7 @@ Style/SignalException:
|
||||
# Suppressing exceptions can be perfectly fine, and be it to avoid to
|
||||
# explicitly type nil into the rescue since that's what you want to return,
|
||||
# or suppressing LoadError for optional dependencies
|
||||
Lint/HandleExceptions:
|
||||
Lint/SuppressedException:
|
||||
Enabled: false
|
||||
|
||||
Layout/SpaceInsideBlockBraces:
|
||||
@@ -175,3 +180,11 @@ Style/NumericPredicate:
|
||||
# Reset some HoundCI changes back to Rubocop defaults
|
||||
Layout/DotPosition:
|
||||
EnforcedStyle: leading
|
||||
|
||||
# Not enabled by default but good
|
||||
Style/HashEachMethods:
|
||||
Enabled: true
|
||||
|
||||
# It makes more sense to allow to structure and group them how it makes sense in the code
|
||||
Style/AccessorGrouping:
|
||||
Enabled: false
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.4
|
||||
2.7
|
||||
|
||||
40
.travis.yml
40
.travis.yml
@@ -1,40 +0,0 @@
|
||||
language: ruby
|
||||
|
||||
rvm:
|
||||
- 2.4.2
|
||||
- 2.3.5
|
||||
|
||||
env:
|
||||
- DB=postgresql BUILD_TYPE=cucumber
|
||||
- DB=mysql BUILD_TYPE=cucumber
|
||||
- DB=postgresql BUILD_TYPE=other
|
||||
- DB=mysql BUILD_TYPE=other
|
||||
|
||||
sudo: false
|
||||
cache:
|
||||
bundler: true
|
||||
directories:
|
||||
- app/assets/images
|
||||
- tmp/cache/assets
|
||||
|
||||
branches:
|
||||
only:
|
||||
- 'master'
|
||||
- 'next-minor'
|
||||
- 'develop'
|
||||
|
||||
before_install:
|
||||
- script/ci/prepare.sh
|
||||
- mkdir travis-phantomjs
|
||||
- wget http://cifiles.diasporafoundation.org/phantomjs-2.1.1-linux-x86_64.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2
|
||||
- tar -xvf $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis-phantomjs
|
||||
- export PATH=$PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH
|
||||
|
||||
script: "bin/rake --trace ci:travis:${BUILD_TYPE}"
|
||||
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
- secure: YvYkeTAw+5oOl/RaXVwu7JkKGNWPoFosNQRmLvJkBFbWzZ1s5LZD1u3+Qj819bT3lGzJu9pxmJg765IRYrGWmBi4mcAV3dpO6qowVdFTcorf0JsnLw3Kvkga9rrDunsRNr21KTAQqHOO5mKUzw9DtMzd52BiWuZwIj3xcl72gQI=
|
||||
template:
|
||||
- "%{repository_slug}#%{commit} (%{branch} - %{commit_subject}): %{message} %{build_url}"
|
||||
119
Changelog.md
119
Changelog.md
@@ -1,3 +1,122 @@
|
||||
# 0.7.18.2
|
||||
|
||||
To avoid potential security issues, diaspora\* now makes sure that ImageMagick image processing always runs with a restricted `policy.xml`, regardless of the global system settings.
|
||||
|
||||
# 0.7.18.1
|
||||
|
||||
## Bug fixes
|
||||
* Update binstubs to fix diaspora\* being unable to start when multiple bundler versions were available [#8392](https://github.com/diaspora/diaspora/pull/8392/commits/bfd42a1914a99ac9c71ecb16bbf6fa5bb118148a)
|
||||
|
||||
# 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
|
||||
* Bump Rails to 5.2.7 to address [CVE-2022-22577](https://discuss.rubyonrails.org/t/cve-2022-22577-possible-xss-vulnerability-in-action-pack/80533) and [CVE-2022-27777](https://discuss.rubyonrails.org/t/cve-2022-27777-possible-xss-vulnerability-in-action-view-tag-helpers/80534) [#8350](https://github.com/diaspora/diaspora/pull/8350)
|
||||
* Do not allow the user to mass assign their own password and 2fa settings alongside other parameters. Reported by Breno Vitório (@brenu) - thank you! [#8351](https://github.com/diaspora/diaspora/pull/8351)
|
||||
|
||||
## Bug fixes
|
||||
* Don't suggest to retry exports on failure [#8343](https://github.com/diaspora/diaspora/pull/8343)
|
||||
|
||||
# 0.7.16.0
|
||||
|
||||
## Security
|
||||
|
||||
* Update rails to fix [CVE-2022-23633](https://github.com/advisories/GHSA-wh98-p28r-vrc9) [#8336](https://github.com/diaspora/diaspora/pull/8336)
|
||||
|
||||
## Refactor
|
||||
* Cache local posts/comments count for statistics [#8241](https://github.com/diaspora/diaspora/pull/8241)
|
||||
* Fix html-syntax in some handlebars templates [#8251](https://github.com/diaspora/diaspora/pull/8251)
|
||||
* Remove `chat_enabled` flag from archive export [#8265](https://github.com/diaspora/diaspora/pull/8265)
|
||||
* Change thumbnails in image slideshow to squares [#8275](https://github.com/diaspora/diaspora/pull/8275)
|
||||
* Replace uglifier with terser for JS compression [#8268](https://github.com/diaspora/diaspora/pull/8268)
|
||||
|
||||
## Bug fixes
|
||||
* Ensure the log folder exists [#8287](https://github.com/diaspora/diaspora/pull/8287)
|
||||
* Limit name length in header [#8313](https://github.com/diaspora/diaspora/pull/8313)
|
||||
* Fix fallback avatar in hovercards [#8316](https://github.com/diaspora/diaspora/pull/8316)
|
||||
* Use old person private key for export if relayable author migrated away [#8310](https://github.com/diaspora/diaspora/pull/8310)
|
||||
|
||||
## Features
|
||||
* Add tags to tumblr posts [#8244](https://github.com/diaspora/diaspora/pull/8244)
|
||||
* Add blocks to the archive export [#8263](https://github.com/diaspora/diaspora/pull/8263)
|
||||
* Allow points and dashes in the username [#8266](https://github.com/diaspora/diaspora/pull/8266)
|
||||
* Add support for footnotes in markdown [#8277](https://github.com/diaspora/diaspora/pull/8277)
|
||||
* Send `AccountMigration` if receiving message to a migrated account [#8288](https://github.com/diaspora/diaspora/pull/8288)
|
||||
* Add podmin mail address to the footer [#8242](https://github.com/diaspora/diaspora/pull/8242)
|
||||
* Add username to password-reset mail [#8037](https://github.com/diaspora/diaspora/pull/8037)
|
||||
* Resend account migration and deletion for closed recipients [#8309](https://github.com/diaspora/diaspora/pull/8309)
|
||||
* Add sharing status to hovercards [#8317](https://github.com/diaspora/diaspora/pull/8317)
|
||||
* Migrate photo URLs and cleanup old uploaded photos [#8314](https://github.com/diaspora/diaspora/pull/8314)
|
||||
|
||||
# 0.7.15.0
|
||||
|
||||
## Refactor
|
||||
* Replaced some `http://` links in the UI with their `https://` counterparts [#8207](https://github.com/diaspora/diaspora/pull/8207)
|
||||
* Testing: Replaced phantomjs with headless Chrome/Chromium [#8234](https://github.com/diaspora/diaspora/pull/8234)
|
||||
|
||||
## Bug fixes
|
||||
* Update comment counter when weleting a comment in the Single Post View [#7938](https://github.com/diaspora/diaspora/pull/7938)
|
||||
* Link diaspora only poduptime list [#8174](https://github.com/diaspora/diaspora/pull/8174)
|
||||
* Delete a user's invitation code during account deletion [#8202](https://github.com/diaspora/diaspora/pull/8202)
|
||||
* Bump mimemagic [#8231](https://github.com/diaspora/diaspora/pull/8231)
|
||||
* Removed support for defunct Uni Heidelberg OSM tile server, Mapbox is now required if you want to show maps [#8215](https://github.com/diaspora/diaspora/pull/8215)
|
||||
* Render only two fractional digits in the posts per user/day admin statistics [#8227](https://github.com/diaspora/diaspora/pull/8227)
|
||||
* Make aspect dropdowns scrollable [#8213](https://github.com/diaspora/diaspora/pull/8213)
|
||||
* Fix `Photo#ownserhip_of_status_message` validation [#8214](https://github.com/diaspora/diaspora/pull/8214)
|
||||
|
||||
## Features
|
||||
* Support and recommend TOML as configuration format [#8132](https://github.com/diaspora/diaspora/pull/8132)
|
||||
|
||||
# 0.7.14.0
|
||||
|
||||
## Refactor
|
||||
* Update the suggested Ruby version to 2.6. If you run into trouble during the update and you followed our installation guides, run `rvm install 2.6`. [#7929](https://github.com/diaspora/diaspora/pull/7929)
|
||||
|
||||
## Bug fixes
|
||||
* Don't link to deleted users in admin user stats [#8063](https://github.com/diaspora/diaspora/pull/8063)
|
||||
* Properly validate a profile's gender field length instead of failing with a database error. [#8127](https://github.com/diaspora/diaspora/pull/8127)
|
||||
|
||||
## Features
|
||||
|
||||
# 0.7.13.0
|
||||
|
||||
## Security
|
||||
* Fixes [USN-4274-1](https://usn.ubuntu.com/4274-1/), a potential Denial-of-Service vulnerability in Nokogiri. [#8108](https://github.com/diaspora/diaspora/pull/8108)
|
||||
|
||||
## Refactor
|
||||
* Set better example values for unicorn stdout/stderr log settings [#8058](https://github.com/diaspora/diaspora/pull/8058)
|
||||
* Replace dependency on rails-assets.org with custom gems cache at gems.diasporafoundation.org [#8087](https://github.com/diaspora/diaspora/pull/8087)
|
||||
|
||||
## Bug fixes
|
||||
* Fix error while trying to fetch some sites with invalid OpenGraph data [#8049](https://github.com/diaspora/diaspora/pull/8049)
|
||||
* Don't show sign up link on mobile when registrations are disabled [#8060](https://github.com/diaspora/diaspora/pull/8060)
|
||||
|
||||
## Features
|
||||
* Add cronjob to cleanup pending photos which were never posted [#8041](https://github.com/diaspora/diaspora/pull/8041)
|
||||
|
||||
# 0.7.12.0
|
||||
|
||||
## Refactor
|
||||
|
||||
213
Gemfile
213
Gemfile
@@ -2,115 +2,112 @@
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "rails", "5.1.6.2"
|
||||
gem "rails", "6.1.6.1"
|
||||
|
||||
# Legacy Rails features, remove me!
|
||||
# responders (class level)
|
||||
gem "responders", "2.4.1"
|
||||
gem "responders", "3.0.1"
|
||||
|
||||
# Appserver
|
||||
|
||||
gem "unicorn", "5.5.0", require: false
|
||||
gem "unicorn-worker-killer", "0.4.4"
|
||||
gem "unicorn", "6.1.0", require: false
|
||||
gem "unicorn-worker-killer", "0.4.5"
|
||||
|
||||
# Federation
|
||||
|
||||
gem "diaspora_federation-json_schema", "0.2.6"
|
||||
gem "diaspora_federation-rails", "0.2.6"
|
||||
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.2.0"
|
||||
gem "json-schema", "2.8.1"
|
||||
gem "json", "2.6.2"
|
||||
gem "json-schema", "3.0.0"
|
||||
|
||||
# Authentication
|
||||
|
||||
gem "devise", "4.6.1"
|
||||
gem "devise-two-factor", "3.0.3"
|
||||
gem "devise", "4.8.1"
|
||||
gem "devise_lastseenable", "0.0.6"
|
||||
gem "rqrcode", "0.10.1"
|
||||
gem "devise-two-factor", "4.0.2"
|
||||
gem "rqrcode", "2.1.1"
|
||||
|
||||
# Captcha
|
||||
|
||||
gem "simple_captcha2", "0.4.3", require: "simple_captcha"
|
||||
gem "simple_captcha2", "0.5.0", require: "simple_captcha"
|
||||
|
||||
# Background processing
|
||||
|
||||
gem "redis", "3.3.5" # Pinned to 3.3.x because of https://github.com/antirez/redis/issues/4272
|
||||
gem "sidekiq", "5.2.5"
|
||||
gem "redis", "4.7.0"
|
||||
gem "sidekiq", "6.5.1"
|
||||
|
||||
# Scheduled processing
|
||||
|
||||
gem "sidekiq-cron", "1.1.0"
|
||||
gem "sidekiq-cron", "1.6.0"
|
||||
|
||||
# Compression
|
||||
|
||||
gem "uglifier", "4.1.20"
|
||||
gem "terser", "1.1.10"
|
||||
|
||||
# Configuration
|
||||
|
||||
gem "configurate", "0.3.1"
|
||||
gem "configurate", "0.5.0"
|
||||
gem "toml-rb", "2.1.2"
|
||||
|
||||
# Cross-origin resource sharing
|
||||
|
||||
gem "rack-cors", "1.0.2", require: "rack/cors"
|
||||
gem "rack-cors", "1.1.1", require: "rack/cors"
|
||||
|
||||
# CSS
|
||||
|
||||
gem "autoprefixer-rails", "8.6.5"
|
||||
gem "autoprefixer-rails", "10.4.7.0"
|
||||
gem "bootstrap-sass", "3.4.1"
|
||||
gem "bootstrap-switch-rails", "3.3.3" # 3.3.4 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.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 "sassc-rails", "2.1.2"
|
||||
gem "sprockets-rails", "3.4.2"
|
||||
|
||||
# Database
|
||||
|
||||
group :mysql, optional: true do
|
||||
gem "mysql2", "0.5.2"
|
||||
gem "mysql2", "0.5.4"
|
||||
end
|
||||
group :postgresql, optional: true do
|
||||
gem "pg", "1.1.4"
|
||||
gem "pg", "1.4.1"
|
||||
end
|
||||
|
||||
|
||||
gem "activerecord-import", "1.0.1"
|
||||
gem "activerecord-import", "1.4.0"
|
||||
|
||||
# File uploading
|
||||
|
||||
gem "carrierwave", "1.3.1"
|
||||
gem "fog-aws", "3.4.0"
|
||||
gem "mini_magick", "4.9.3"
|
||||
gem "carrierwave", "2.2.2"
|
||||
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.3"
|
||||
gem "jquery-rails", "4.3.3"
|
||||
gem "js-routes", "1.4.4"
|
||||
gem "js_image_paths", "0.1.1"
|
||||
gem "handlebars_assets", "0.23.9"
|
||||
gem "jquery-rails", "4.5.0"
|
||||
gem "js_image_paths", "0.2.0"
|
||||
gem "js-routes", "2.2.4"
|
||||
|
||||
source "https://rails-assets.org" do
|
||||
gem "rails-assets-jquery", "3.3.1" # Should be kept in sync with jquery-rails
|
||||
source "https://gems.diasporafoundation.org" do
|
||||
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"
|
||||
gem "rails-assets-markdown-it", "8.4.2"
|
||||
gem "rails-assets-markdown-it-hashtag", "0.4.0"
|
||||
gem "rails-assets-markdown-it-diaspora-mention", "1.2.0"
|
||||
gem "rails-assets-markdown-it-sanitizer", "0.4.3"
|
||||
gem "rails-assets-markdown-it-footnote", "3.0.3"
|
||||
gem "rails-assets-markdown-it-hashtag", "0.4.0"
|
||||
gem "rails-assets-markdown-it--markdown-it-for-inline", "0.1.1"
|
||||
gem "rails-assets-markdown-it-sanitizer", "0.4.3"
|
||||
gem "rails-assets-markdown-it-sub", "1.0.0"
|
||||
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"
|
||||
@@ -131,69 +128,66 @@ 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.3.1"
|
||||
gem "leaflet-rails", "1.7.0"
|
||||
|
||||
# Parsing
|
||||
|
||||
gem "nokogiri", "1.10.1"
|
||||
gem "open_graph_reader", "0.6.2" # also update User-Agent in features/support/webmock.rb
|
||||
gem "redcarpet", "3.4.0"
|
||||
gem "ruby-oembed", "0.12.0"
|
||||
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.16.1"
|
||||
gem "twitter-text", "1.14.7"
|
||||
|
||||
# RTL support
|
||||
|
||||
gem "string-direction", "1.2.1"
|
||||
gem "string-direction", "1.2.2"
|
||||
|
||||
# Security Headers
|
||||
|
||||
gem "secure_headers", "6.1.0"
|
||||
gem "secure_headers", "6.3.3"
|
||||
|
||||
# Services
|
||||
|
||||
gem "omniauth", "1.9.0"
|
||||
gem "omniauth-tumblr", "1.2"
|
||||
gem "omniauth-twitter", "1.4.0"
|
||||
gem "omniauth-wordpress", "0.2.2"
|
||||
gem "twitter", "6.2.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"
|
||||
gem "twitter", "7.0.0"
|
||||
|
||||
# OpenID Connect
|
||||
gem "openid_connect", "1.1.6"
|
||||
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"
|
||||
gem "rails-assets-diaspora_jsxc", "0.1.5.develop.7", source: "https://rails-assets.org"
|
||||
gem "rails-assets-diaspora_jsxc", "0.1.5.develop.7", source: "https://gems.diasporafoundation.org"
|
||||
|
||||
# Tags
|
||||
|
||||
gem "acts-as-taggable-on", "6.0.0"
|
||||
gem "acts-as-taggable-on", "9.0.1"
|
||||
|
||||
# URIs and HTTP
|
||||
|
||||
gem "addressable", "2.5.2", require: "addressable/uri"
|
||||
gem "faraday", "0.15.4"
|
||||
gem "faraday_middleware", "0.12.2"
|
||||
gem "faraday-cookie_jar", "0.0.6"
|
||||
gem "typhoeus", "1.3.1"
|
||||
gem "addressable", "2.8.0", require: "addressable/uri"
|
||||
gem "faraday", "0.17.5"
|
||||
gem "faraday-cookie_jar", "0.0.7"
|
||||
gem "faraday_middleware", "0.14.0"
|
||||
gem "typhoeus", "1.4.0"
|
||||
|
||||
# Views
|
||||
|
||||
gem "gon", "6.2.1"
|
||||
gem "hamlit", "2.9.2"
|
||||
gem "gon", "6.4.0"
|
||||
gem "hamlit", "2.16.0"
|
||||
gem "mobile-fu", "1.4.0"
|
||||
gem "rails-timeago", "2.17.1"
|
||||
gem "will_paginate", "3.1.7"
|
||||
gem "rails-timeago", "2.20.0"
|
||||
gem "will_paginate", "3.3.1"
|
||||
|
||||
# Logging
|
||||
|
||||
@@ -201,16 +195,16 @@ gem "logging-rails", "0.6.0", require: "logging/rails"
|
||||
|
||||
# Reading and writing zip files
|
||||
|
||||
gem "rubyzip", "1.2.2", require: "zip"
|
||||
gem "rubyzip", "2.3.2", require: "zip"
|
||||
|
||||
# Prevent occasions where minitest is not bundled in
|
||||
# packaged versions of ruby. See following issues/prs:
|
||||
# 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", "1.7.0"
|
||||
gem "versionist", "2.0.1"
|
||||
|
||||
# Windows and OSX have an execjs compatible runtime built-in, Linux users should
|
||||
# install Node.js or use "therubyracer".
|
||||
@@ -236,84 +230,71 @@ group :production do # we don"t install these on travis to speed up test runs
|
||||
|
||||
# Third party asset hosting
|
||||
|
||||
gem "asset_sync", "2.7.0", require: false
|
||||
gem "asset_sync", "2.15.2", require: false
|
||||
end
|
||||
|
||||
group :development do
|
||||
# Automatic test runs
|
||||
gem "guard", "2.15.0", require: false
|
||||
gem "guard-rspec", "4.7.3", require: false
|
||||
gem "guard-rubocop", "1.3.0", require: false
|
||||
gem "rb-fsevent", "0.10.3", require: false
|
||||
gem "rb-inotify", "0.10.0", require: false
|
||||
|
||||
# Linters
|
||||
gem "haml_lint", "0.28.0", require: false
|
||||
gem "pronto", "0.9.5", require: false
|
||||
gem "pronto-eslint", "0.9.1", require: false
|
||||
gem "pronto-haml", "0.9.0", require: false
|
||||
gem "pronto-rubocop", "0.9.1", require: false
|
||||
gem "pronto-scss", "0.9.1", require: false
|
||||
gem "rubocop", "0.66.0", require: false
|
||||
|
||||
# Preloading environment
|
||||
|
||||
gem "spring", "2.0.2"
|
||||
gem "spring-commands-rspec", "1.0.4"
|
||||
gem "spring-commands-cucumber", "1.0.1"
|
||||
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.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
|
||||
gem "rubocop-rails", "2.9.1", require: false
|
||||
|
||||
# Debugging
|
||||
gem "pry"
|
||||
gem "pry-byebug"
|
||||
|
||||
# test coverage
|
||||
gem "simplecov", "0.16.1", require: false
|
||||
gem "simplecov", "0.21.2", require: false
|
||||
|
||||
gem "turbo_dev_assets", "0.0.2"
|
||||
|
||||
gem "listen", "3.7.1"
|
||||
end
|
||||
|
||||
group :test do
|
||||
# RSpec (unit tests, some integration tests)
|
||||
|
||||
gem "fixture_builder", "0.5.2.rc3"
|
||||
gem "fuubar", "2.3.2"
|
||||
gem "json-schema-rspec", "0.0.4"
|
||||
gem "fixture_builder", "0.5.2"
|
||||
gem "fuubar", "2.5.1"
|
||||
gem "rspec-json_expectations", "~> 2.1"
|
||||
|
||||
# Cucumber (integration tests)
|
||||
|
||||
gem "capybara", "3.15.0"
|
||||
gem "database_cleaner", "1.7.0"
|
||||
gem "poltergeist", "1.18.1"
|
||||
gem "apparition", "0.6.0"
|
||||
gem "capybara", "3.35.3"
|
||||
gem "database_cleaner-active_record", "2.0.1"
|
||||
|
||||
gem "cucumber-api-steps", "0.14", require: false
|
||||
|
||||
# General helpers
|
||||
|
||||
gem "factory_girl_rails", "4.8.0"
|
||||
gem "shoulda-matchers", "4.0.1"
|
||||
gem "timecop", "0.9.1"
|
||||
gem "webmock", "3.5.1", require: false
|
||||
gem "factory_girl_rails", "4.9.0"
|
||||
gem "shoulda-matchers", "4.5.1"
|
||||
gem "timecop", "0.9.5"
|
||||
gem "webmock", "3.14.0", require: false
|
||||
|
||||
gem "diaspora_federation-test", "0.2.6"
|
||||
|
||||
# Coverage
|
||||
gem "coveralls", "0.8.22", require: false
|
||||
gem "diaspora_federation-test", "0.2.8"
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
# RSpec (unit tests, some integration tests)
|
||||
gem "rspec-rails", "3.8.2"
|
||||
gem "rspec-rails", "5.1.2"
|
||||
|
||||
# Cucumber (integration tests)
|
||||
gem "cucumber-rails", "1.6.0", require: false
|
||||
gem "cucumber-rails", "2.5.1", require: false
|
||||
|
||||
# Jasmine (client side application tests (JS))
|
||||
gem "jasmine", "3.3.0"
|
||||
gem "chrome_remote", "0.3.0"
|
||||
gem "jasmine", "3.10.0"
|
||||
gem "jasmine-jquery-rails", "2.0.3"
|
||||
gem "rails-assets-jasmine-ajax", "3.4.0", source: "https://rails-assets.org"
|
||||
gem "rails-assets-jasmine-ajax", "4.0.0", source: "https://gems.diasporafoundation.org"
|
||||
gem "sinon-rails", "1.15.0"
|
||||
|
||||
# For `assigns` in controller specs
|
||||
gem "rails-controller-testing", "1.0.4"
|
||||
gem "rails-controller-testing", "1.0.5"
|
||||
end
|
||||
|
||||
1102
Gemfile.lock
1102
Gemfile.lock
File diff suppressed because it is too large
Load Diff
29
Guardfile
29
Guardfile
@@ -1,29 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
guard :rspec, cmd: "bin/spring rspec", all_on_start: false, all_after_pass: false do
|
||||
watch(/^spec\/.+_spec\.rb$/)
|
||||
watch(/^lib\/(.+)\.rb$/) {|m| "spec/lib/#{m[1]}_spec.rb" }
|
||||
watch(/spec\/spec_helper.rb/) { "spec" }
|
||||
|
||||
# Rails example
|
||||
watch(/^spec\/.+_spec\.rb$/)
|
||||
watch(/^app\/(.+)\.rb$/) {|m| "spec/#{m[1]}_spec.rb" }
|
||||
watch(/^lib\/(.+)\.rb$/) {|m| "spec/lib/#{m[1]}_spec.rb" }
|
||||
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) {|m|
|
||||
["spec/routing/#{m[1]}_routing_spec.rb",
|
||||
"spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb",
|
||||
"spec/acceptance/#{m[1]}_spec.rb"]
|
||||
}
|
||||
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
||||
watch("spec/spec_helper.rb") { "spec" }
|
||||
watch("config/routes.rb") { "spec/routing" }
|
||||
watch("app/controllers/application_controller.rb") { "spec/controllers" }
|
||||
|
||||
# Capybara request specs
|
||||
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) {|m| "spec/requests/#{m[1]}_spec.rb" }
|
||||
end
|
||||
|
||||
guard :rubocop, all_on_start: false, keep_failed: false do
|
||||
watch(/(?:app|config|db|lib|features|spec)\/.+\.rb$/)
|
||||
watch(/(config.ru|Gemfile|Guardfile|Rakefile)$/)
|
||||
end
|
||||
11
README.md
11
README.md
@@ -1,13 +1,6 @@
|
||||
# diaspora\*
|
||||
### A privacy-aware, distributed, open source social network
|
||||
|
||||
**master:** [](http://travis-ci.org/diaspora/diaspora)
|
||||
**next-minor:** [](http://travis-ci.org/diaspora/diaspora)
|
||||
[](https://coveralls.io/github/diaspora/diaspora?branch=next-minor)|
|
||||
**develop:** [](http://travis-ci.org/diaspora/diaspora)
|
||||
[](https://coveralls.io/github/diaspora/diaspora?branch=develop) |
|
||||
[](https://codeclimate.com/github/diaspora/diaspora)
|
||||
|
||||
[Project site](https://diasporafoundation.org) |
|
||||
[Wiki](https://wiki.diasporafoundation.org) |
|
||||
[Bugtracker](https://github.com/diaspora/diaspora/issues) |
|
||||
@@ -17,7 +10,7 @@
|
||||
|
||||
## Installation
|
||||
|
||||
You don't have to install diaspora\* to use the network. There are many servers connected to diaspora\*s network which are open to anyone, and you can create an account on one of these servers. Have a look at our [tips for finding a home](https://wiki.diasporafoundation.org/Choosing_a_pod), or you can just go straight to the [list of open servers](http://podupti.me) to sign up.
|
||||
You don't have to install diaspora\* to use the network. There are many servers connected to diaspora\*s network which are open to anyone, and you can create an account on one of these servers. Have a look at our [tips for finding a home](https://wiki.diasporafoundation.org/Choosing_a_pod), or you can just go straight to the [list of open servers](https://diaspora.fediverse.observer) to sign up.
|
||||
|
||||
Want to own your data and install diaspora\*? Whether you just want to try it out, want to install it on your server or want to contribute and need a development setup, our [installation guides](https://wiki.diasporafoundation.org/Installation) will get you started!
|
||||
|
||||
@@ -35,4 +28,4 @@ Everyone interacting in diaspora’s codebases, issue trackers, chat rooms, the
|
||||
|
||||
## Security
|
||||
|
||||
Found a security issue? Please disclose it responsibly. We have a team of developers listening to [security@diasporafoundation.org](mailto:security@diasporafoundation.org). The PGP fingerprint is [AB0D AB02 0FC5 D398 03AB 3CE1 6F70 243F 27AD 886A](https://pgp.mit.edu/pks/lookup?op=get&search=0x6F70243F27AD886A).
|
||||
See [`SECURITY.md`](/SECURITY.md) for instructions on how to responsibly report a security vulnerability.
|
||||
|
||||
9
SECURITY.md
Normal file
9
SECURITY.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We support the latest stable release, as well as the current state of the `next-minor` and `develop` branches. Security issues for older releases are out of scope.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Found a security issue? Please disclose it responsibly. We have a team of developers listening to [security@diasporafoundation.org](mailto:security@diasporafoundation.org). The PGP fingerprint is [AB0D AB02 0FC5 D398 03AB 3CE1 6F70 243F 27AD 886A](https://pgp.mit.edu/pks/lookup?op=get&search=0x6F70243F27AD886A).
|
||||
@@ -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
|
||||
|
||||
@@ -44,7 +44,7 @@ Handlebars.registerHelper('linkToPerson', function(context, block) {
|
||||
// relationship indicator for profile page
|
||||
Handlebars.registerHelper("sharingMessage", function(person) {
|
||||
var i18nScope = "people.helper.is_not_sharing";
|
||||
var icon = "circle";
|
||||
var icon = "entypo-record";
|
||||
if( person.is_sharing ) {
|
||||
i18nScope = "people.helper.is_sharing";
|
||||
icon = "entypo-check";
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
(function() {
|
||||
app.helpers.locations = {
|
||||
getTiles: function() {
|
||||
// If the mapbox option is enabled in the diaspora.yml, the mapbox tiles with the podmin's credentials are used.
|
||||
// If the mapbox option is enabled in the diaspora.toml, the mapbox tiles with the podmin's credentials are used.
|
||||
if (gon.appConfig.map.mapbox.enabled) {
|
||||
return L.tileLayer("https://api.mapbox.com/styles/v1/{style}/tiles/256/{z}/{x}/{y}?access_token={accessToken}", {
|
||||
accessToken: gon.appConfig.map.mapbox.access_token,
|
||||
style: gon.appConfig.map.mapbox.style,
|
||||
attribution: "Map data © <a href='http://openstreetmap.org'>OpenStreetMap</a> contributors, " +
|
||||
"<a href='http://creativecommons.org/licenses/by-sa/2.0/''>CC-BY-SA</a>, " +
|
||||
"Imagery © <a href='https://www.mapbox.com'>Mapbox</a>",
|
||||
maxZoom: 18
|
||||
});
|
||||
return L.tileLayer(
|
||||
"https://api.mapbox.com/styles/v1/{style}/tiles/256/{z}/{x}/{y}?access_token={accessToken}",
|
||||
{
|
||||
accessToken: gon.appConfig.map.mapbox.access_token,
|
||||
style: gon.appConfig.map.mapbox.style,
|
||||
attribution:
|
||||
"Map data © <a href='https://openstreetmap.org'>OpenStreetMap</a> contributors, " +
|
||||
"<a href='http://opendatacommons.org/licenses/dbcl/1.0/'>Open Database License, ODbL 1.0</a>, " +
|
||||
"Imagery © <a href='https://www.mapbox.com'>Mapbox</a>",
|
||||
maxZoom: 18,
|
||||
tileSize: 512,
|
||||
zoomOffset: -1
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// maptiles from the Heidelberg University are used by default.
|
||||
return L.tileLayer("http://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}", {
|
||||
attribution: "Map data © <a href='http://openstreetmap.org'>OpenStreetMap</a> contributors, " +
|
||||
"rendering <a href='http://giscience.uni-hd.de/'>" +
|
||||
"GIScience Research Group @ Heidelberg University</a>",
|
||||
maxZoom: 18
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
typographer: true
|
||||
});
|
||||
|
||||
var footnote = window.markdownitFootnote;
|
||||
md.use(footnote);
|
||||
|
||||
var inlinePlugin = window.markdownitForInline;
|
||||
md.use(inlinePlugin, "utf8_symbols", "text", function (tokens, idx) {
|
||||
tokens[idx].content = tokens[idx].content.replace(/<->/g, "↔")
|
||||
@@ -40,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
|
||||
|
||||
@@ -85,6 +85,10 @@ app.models.Post.Interactions = Backbone.Model.extend({
|
||||
});
|
||||
},
|
||||
|
||||
removedComment: function() {
|
||||
this.set({"comments_count": this.get("comments_count") - 1});
|
||||
},
|
||||
|
||||
reshare : function(){
|
||||
var interactions = this;
|
||||
|
||||
|
||||
@@ -16,10 +16,8 @@ app.views.AspectMembership = app.views.Base.extend({
|
||||
},
|
||||
|
||||
events: {
|
||||
"click ul.aspect_membership.dropdown-menu > li.aspect_selector"
|
||||
: "_clickHandler",
|
||||
"keypress ul.aspect_membership.dropdown-menu > li.aspect_selector"
|
||||
: "_clickHandler"
|
||||
"click ul.aspect-membership.dropdown-menu > li.aspect_selector": "_clickHandler",
|
||||
"keypress ul.aspect-membership.dropdown-menu > li.aspect_selector": "_clickHandler"
|
||||
},
|
||||
|
||||
initialize: function(opts) {
|
||||
|
||||
@@ -135,7 +135,10 @@ app.views.CommentStream = app.views.Base.extend({
|
||||
},
|
||||
|
||||
removeComment: function(comment) {
|
||||
this.$("#" + comment.get("guid")).closest(".comment.media").remove();
|
||||
var result = this.$("#" + comment.get("guid")).closest(".comment.media").remove();
|
||||
if (result.hasClass("deleting")) {
|
||||
this.model.interactions.removedComment();
|
||||
}
|
||||
},
|
||||
|
||||
expandComments: function(evt){
|
||||
|
||||
@@ -13,9 +13,10 @@ app.views.Help = app.views.StaticContentView.extend({
|
||||
"click .faq-link-chat": "chat"
|
||||
},
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
initialize : function() {
|
||||
this.GETTING_HELP_SUBS = {
|
||||
getting_started_a: {tutorial_series: this.linkHtml("http://diasporafoundation.org/getting_started/sign_up", Diaspora.I18n.t("getting_started_tutorial"))},
|
||||
getting_started_a: {tutorial_series: this.linkHtml("https://diasporafoundation.org/getting_started/sign_up", Diaspora.I18n.t("getting_started_tutorial"))},
|
||||
get_support_a_website: {link: this.linkHtml("https://diasporafoundation.org/", Diaspora.I18n.t("foundation_website"))},
|
||||
get_support_a_tutorials: {tutorials: this.linkHtml("https://diasporafoundation.org/tutorials", Diaspora.I18n.t("tutorials"))},
|
||||
get_support_a_wiki: {link: this.linkHtml("https://wiki.diasporafoundation.org/Special:Search", Diaspora.I18n.t("wiki"))},
|
||||
@@ -28,10 +29,11 @@ app.views.Help = app.views.StaticContentView.extend({
|
||||
this.POSTS_AND_POSTING_SUBS = {
|
||||
post_report_a: {community_guidelines: this.linkHtml("https://diasporafoundation.org/community_guidelines", Diaspora.I18n.t("community_guidelines"))},
|
||||
format_text_a: {
|
||||
markdown: this.linkHtml("http://diasporafoundation.org/formatting", Diaspora.I18n.t( 'markdown' )),
|
||||
here: this.linkHtml("http://daringfireball.net/projects/markdown/syntax", Diaspora.I18n.t( 'here' ))
|
||||
markdown: this.linkHtml("https://diasporafoundation.org/formatting", Diaspora.I18n.t("markdown")),
|
||||
here: this.linkHtml("https://daringfireball.net/projects/markdown/syntax", Diaspora.I18n.t("here"))
|
||||
}
|
||||
};
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
this.TAGS_SUBS = {
|
||||
filter_tags_a: {
|
||||
|
||||
@@ -19,10 +19,15 @@ app.views.Hovercard = app.views.Base.extend({
|
||||
|
||||
this.showMe = false;
|
||||
this.parent = null; // current 'hovercardable' element that caused HC to appear
|
||||
|
||||
this.active = true;
|
||||
},
|
||||
|
||||
presenter: function() {
|
||||
return _.extend({}, this.defaultPresenter(), {
|
||||
person: this.person
|
||||
});
|
||||
},
|
||||
|
||||
postRenderTemplate: function() {
|
||||
this.$el.appendTo($("body"));
|
||||
|
||||
@@ -102,14 +107,14 @@ app.views.Hovercard = app.views.Base.extend({
|
||||
if( !person || person.length === 0 ) {
|
||||
throw new Error("received data is not a person object");
|
||||
}
|
||||
|
||||
var personModel = new app.models.Person(person);
|
||||
person.is_sharing = personModel.isSharing();
|
||||
self.person = person;
|
||||
if (app.currentUser.authenticated()) {
|
||||
self.aspectMembershipDropdown = new app.views.AspectMembership({person: new app.models.Person(person)});
|
||||
self.aspectMembershipDropdown = new app.views.AspectMembership({person: personModel});
|
||||
}
|
||||
|
||||
self.render();
|
||||
|
||||
self._populateHovercardWith(person);
|
||||
if( !self.showMe ) {
|
||||
// mouse has left element
|
||||
return;
|
||||
@@ -118,23 +123,6 @@ app.views.Hovercard = app.views.Base.extend({
|
||||
});
|
||||
},
|
||||
|
||||
_populateHovercardWith: function(person) {
|
||||
this.avatarLink.attr("href", this.href());
|
||||
this.personLink.attr("href", this.href());
|
||||
this.personLink.text(person.name);
|
||||
this.personID.text(person.diaspora_id);
|
||||
|
||||
if (person.profile) {
|
||||
this.avatar.attr("src", person.profile.avatar);
|
||||
|
||||
// set hashtags
|
||||
this.hashtags.empty();
|
||||
this.hashtags.html($(_.map(person.profile.tags, function(tag) {
|
||||
return $("<a/>", {href: Routes.tag(tag)}).text("#" + tag)[0];
|
||||
})));
|
||||
}
|
||||
},
|
||||
|
||||
_positionHovercard: function() {
|
||||
var p_pos = this.parent.offset();
|
||||
var p_height = this.parent.height();
|
||||
|
||||
@@ -19,7 +19,7 @@ app.views.Location = Backbone.View.extend({
|
||||
var locator = new OSM.Locator();
|
||||
locator.getAddress(function(address, latlng){
|
||||
$(element).empty();
|
||||
$("<input/>",
|
||||
$("<input></input>",
|
||||
{ id: "location_address",
|
||||
value: address,
|
||||
type: "text",
|
||||
|
||||
@@ -351,7 +351,7 @@ app.views.Publisher = Backbone.View.extend({
|
||||
};
|
||||
|
||||
var previewPost = new app.views.PreviewPost({model: new app.models.Post(previewMessage)}).render().el;
|
||||
return $("<div/>").append(previewPost).html();
|
||||
return $("<div></div>").append(previewPost).html();
|
||||
},
|
||||
|
||||
keyDown : function(evt) {
|
||||
|
||||
@@ -36,8 +36,9 @@ app.views.SinglePostContent = app.views.Base.extend({
|
||||
|
||||
var map = L.map(mapContainer[0]).setView([location.lat, location.lng], 14);
|
||||
var tiles = app.helpers.locations.getTiles();
|
||||
|
||||
tiles.addTo(map);
|
||||
if (tiles) {
|
||||
tiles.addTo(map);
|
||||
}
|
||||
|
||||
// put marker on map
|
||||
L.marker(location).addTo(map);
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
//= require markdown-it
|
||||
//= require markdown-it-diaspora-mention
|
||||
//= require markdown-it-for-inline
|
||||
//= require markdown-it-footnote
|
||||
//= require markdown-it-hashtag
|
||||
//= require markdown-it-sanitizer
|
||||
//= require markdown-it-sub
|
||||
|
||||
@@ -185,8 +185,8 @@
|
||||
|
||||
addNewComments: function(bottomBar, data) {
|
||||
if ($(".comment-container", bottomBar).length === 0) {
|
||||
$(".show-comments", bottomBar).after($("<div/>", {"class": "comment-container"}));
|
||||
$(".comment-container", bottomBar).append($("<ul/>", {"class": "comments"}));
|
||||
$(".show-comments", bottomBar).after($("<div></div>", {"class": "comment-container"}));
|
||||
$(".comment-container", bottomBar).append($("<ul></ul>", {"class": "comments"}));
|
||||
}
|
||||
$(".comment-container .comments", bottomBar).append(data);
|
||||
},
|
||||
@@ -212,8 +212,10 @@
|
||||
var postGuid = bottomBar.parents(".stream-element").data("guid");
|
||||
|
||||
toggleReactionsLink.remove();
|
||||
toggleReactionsLink = $("<a/>", {"class": "show-comments", "href": Routes.postComments(postGuid) + ".mobile"})
|
||||
.html(text + "<i class='entypo-chevron-up'/>");
|
||||
toggleReactionsLink = $("<a></a>", {
|
||||
"class": "show-comments",
|
||||
"href": Routes.postComments(postGuid) + ".mobile"
|
||||
}).html(text + "<i class='entypo-chevron-up'/>");
|
||||
parent.prepend(toggleReactionsLink);
|
||||
bottomBar.removeClass("inactive").addClass("active");
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ $(document).ready(function(){
|
||||
if(hiddenField.length > 0) { hiddenField.remove(); }
|
||||
else {
|
||||
$("#new_status_message").append(
|
||||
$("<input/>", {
|
||||
$("<input></input>", {
|
||||
name: "services[]",
|
||||
type: "hidden",
|
||||
value: provider
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
@import 'icons';
|
||||
@import 'animations';
|
||||
@import 'flash_messages';
|
||||
@import 'sprites';
|
||||
@import 'hovercard';
|
||||
@import 'base';
|
||||
@import 'interactions';
|
||||
|
||||
@@ -21,3 +21,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.aspect-membership {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -55,8 +55,8 @@ body {
|
||||
|
||||
.tag:hover { background-color: desaturate(darken($link-color, 35%), 20%); }
|
||||
|
||||
#profile_container .profile_header {
|
||||
#author_info #sharing_message.entypo-check { color: lighten($green, 10%); }
|
||||
#sharing_message.entypo-check {
|
||||
color: lighten($green, 10%);
|
||||
}
|
||||
|
||||
#invitationsModal #email_invitation { border-top: 1px dashed $gray-light; }
|
||||
|
||||
@@ -55,7 +55,6 @@ $margin: 15px;
|
||||
|
||||
li {
|
||||
border: 0;
|
||||
border-radius: $thumbnail-size / 2;
|
||||
height: $thumbnail-size;
|
||||
margin: $margin 6px;
|
||||
vertical-align: middle;
|
||||
|
||||
@@ -119,6 +119,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
.user-name {
|
||||
margin-right: 3px;
|
||||
max-width: 250px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.user-menu-dropdown {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.status-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#hovercard_dropdown_container {
|
||||
overflow: visible !important; /* otherwise the aspect dropdown is cropped */
|
||||
}
|
||||
@@ -53,10 +59,7 @@
|
||||
|
||||
.handle {
|
||||
color: $text-grey;
|
||||
line-height: 18px;
|
||||
padding-top: 0px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.btn-group.aspect-membership-dropdown { margin: 0 !important; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
}
|
||||
.invitations-button { padding-left: 0; }
|
||||
}
|
||||
|
||||
#people-stream {
|
||||
.media, .media-body {
|
||||
overflow: visible;
|
||||
@@ -28,6 +29,7 @@
|
||||
.info { font-size: $font-size-small; }
|
||||
}
|
||||
}
|
||||
|
||||
#blocked_people {
|
||||
.blocked-person {
|
||||
border-bottom: 1px solid $border-grey;
|
||||
@@ -45,3 +47,13 @@
|
||||
.btn-danger { margin-top: 9px; }
|
||||
}
|
||||
}
|
||||
|
||||
#sharing_message {
|
||||
&.entypo-check {
|
||||
color: darken($brand-success, 20%);
|
||||
}
|
||||
|
||||
&.entypo-record {
|
||||
color: $text-grey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,6 @@
|
||||
#sharing_message {
|
||||
cursor: default;
|
||||
font-size: 20px;
|
||||
&.circle {
|
||||
color: $text-grey;
|
||||
&:before { content: '\26aa'; }
|
||||
}
|
||||
&.entypo-check { color: darken($brand-success,20%); }
|
||||
}
|
||||
.description {
|
||||
margin-bottom: 20px;
|
||||
@@ -145,14 +140,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
#email-form{
|
||||
padding: 0;
|
||||
.form-group{
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#birth-date{
|
||||
text-align: center;
|
||||
select{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/* ===== sprites ===== */
|
||||
@import 'branding/logos/*.png';
|
||||
@import 'social-media-logos/*.png';
|
||||
@include all-logos-sprites;
|
||||
@include all-social-media-logos-sprites;
|
||||
@@ -10,10 +10,10 @@
|
||||
{{ t "aspect_dropdown.toggle" count=aspectMembershipsLength }}
|
||||
{{/if}}
|
||||
</span>
|
||||
<span class="caret" />
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu aspect_membership pull-right" unselectable="on">
|
||||
<ul class="dropdown-menu aspect-membership pull-right" unselectable="on">
|
||||
{{#each aspects}}
|
||||
<li
|
||||
{{#if membership}}
|
||||
@@ -29,8 +29,8 @@
|
||||
>
|
||||
<a>
|
||||
<span class="status_indicator">
|
||||
<i class="glyphicon glyphicon-ok" />
|
||||
<i class="glyphicon glyphicon-refresh" />
|
||||
<i class="glyphicon glyphicon-ok"></i>
|
||||
<i class="glyphicon glyphicon-refresh"></i>
|
||||
</span>
|
||||
<span class="text">
|
||||
{{name}}
|
||||
@@ -39,7 +39,7 @@
|
||||
</li>
|
||||
{{/each}}
|
||||
{{#if dropdownMayCreateNewAspect}}
|
||||
<li class="divider" />
|
||||
<li class="divider"></li>
|
||||
<li class="newItem add_aspect">
|
||||
<a data-target="#newAspectModal" data-toggle="modal" href="#">
|
||||
{{ t "aspects.create.add_a_new_aspect" }}
|
||||
@@ -48,5 +48,5 @@
|
||||
{{/if}}
|
||||
</ul>
|
||||
{{#if dropdownMayCreateNewAspect}}
|
||||
<div class="newAspectContainer"/>
|
||||
<div class="newAspectContainer"></div>
|
||||
{{/if}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<li class="hoverable">
|
||||
<a class="selectable toggle_selector" href="#">
|
||||
<a class="selectable toggle_selector aspect-membership" href="#">
|
||||
{{ t "aspect_navigation.select_all" }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
class="new-comment" id="new-comment-on-{{id}}" method="post">
|
||||
|
||||
<textarea class="comment-box form-control mention-textarea"
|
||||
id="comment_text_on_{{id}}" name="text" rows="1" required placeholder="{{t "stream.comment"}}" />
|
||||
id="comment_text_on_{{id}}" name="text" rows="1" required placeholder="{{t "stream.comment"}}"></textarea>
|
||||
<div class="typeahead-mention-box-wrap">
|
||||
<input class="typeahead-mention-box hidden" type="text">
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{{#if canRemove}}
|
||||
<a href="#" class="delete comment_delete" title="{{t "delete"}}">
|
||||
<i class="entypo-trash"></i>
|
||||
<a/>
|
||||
</a>
|
||||
{{else}}
|
||||
<a href="#" data-type="Comment" class="comment_report" title="{{t "report.name"}}">
|
||||
<i class="entypo-warning"></i>
|
||||
@@ -26,7 +26,7 @@
|
||||
{{/linkToAuthor}}
|
||||
-
|
||||
<a href="/posts/{{parent.id}}#{{guid}}" class="permalink_comment">
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}"/>
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}"></time>
|
||||
</a>
|
||||
<a href="/posts/{{parent.guid}}#{{guid}}" class="permalink gray" title="{{t "stream.permalink"}}">
|
||||
<i class="entypo-link"></i>
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown user-menu" id="user-menu">
|
||||
<a href="{{urlTo "person" current_user.guid}}" class="dropdown-toggle hidden-xs hidden-sm" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||
<span class="user-avatar pull-left">
|
||||
<span class="user-avatar">
|
||||
{{{personImage current_user "small"}}}
|
||||
</span>
|
||||
<span class="user-name">{{current_user.name}}</span>
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
{{#with person}}
|
||||
<div id="hovercard">
|
||||
<a class='person_avatar'>
|
||||
<img class="avatar">
|
||||
<a class="person_avatar" href="{{urlTo 'person' guid}}">
|
||||
<img class="avatar" src="{{profile.avatar}}" />
|
||||
</a>
|
||||
<h4>
|
||||
<a class="person"></a>
|
||||
<a class="person" href="{{urlTo 'person' guid}}">{{name}}</a>
|
||||
</h4>
|
||||
<div class="handle"></div>
|
||||
<div class="status-container">
|
||||
<div class="handle">{{diaspora_id}}</div>
|
||||
{{{sharingMessage this}}}
|
||||
</div>
|
||||
<div id="hovercard_dropdown_container"></div>
|
||||
<div class="card-footer">
|
||||
<div class="footer-container">
|
||||
<div class="hashtags"></div>
|
||||
<div class="hashtags">
|
||||
{{fmtTags profile.tags}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/with}}
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
<div class="footer-container">
|
||||
{{#if status_message}}
|
||||
<a href="{{urlTo "post" status_message.id}}">
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}" />
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}"></time>
|
||||
</a>
|
||||
{{else}}
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}" />
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}"></time>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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}}
|
||||
@@ -9,19 +9,20 @@
|
||||
</td>
|
||||
<td class="pod-title" title="{{host}}">{{host}}</td>
|
||||
<td class="added">
|
||||
<small><time datetime="{{created_at}}" title="{{localTime created_at}}" /></small>
|
||||
<small><time datetime="{{created_at}}" title="{{localTime created_at}}"></time></small>
|
||||
</td>
|
||||
<td>
|
||||
{{#if has_no_errors}}
|
||||
<i title="{{status_text}}" class="glyphicon glyphicon-ok"></i>
|
||||
{{software}}
|
||||
{{else}}
|
||||
{{status_text}}
|
||||
{{/if}}
|
||||
{{#unless is_unchecked}}
|
||||
<br><small>{{t 'admin.pods.last_check'}} <time datetime="{{checked_at}}" title="{{localTime checked_at}}" /></small>
|
||||
<br><small>{{t 'admin.pods.last_check'}} <time datetime="{{checked_at}}" title="{{localTime checked_at}}"></time></small>
|
||||
{{/unless}}
|
||||
{{#if offline}}
|
||||
| <small>{{t 'admin.pods.offline_since'}} <time datetime="{{offline_since}}" title="{{localTime offline_since}}" /></small>
|
||||
| <small>{{t 'admin.pods.offline_since'}} <time datetime="{{offline_since}}" title="{{localTime offline_since}}"></time></small>
|
||||
{{/if}}
|
||||
{{#if is_unchecked}}<br><small class="text-muted">{{t 'admin.pods.no_info'}}</small>{{/if}}
|
||||
<pre class="details" style="display: none;">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<span class="details gray">
|
||||
-
|
||||
<a href="/posts/{{id}}">
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}" />
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}"></time>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -40,11 +40,11 @@
|
||||
<span class="post-time">
|
||||
{{#if root}}
|
||||
<a href="/posts/{{root.guid}}">
|
||||
<time datetime="{{root.created_at}}" title="{{localTime root.created_at}}" />
|
||||
<time datetime="{{root.created_at}}" title="{{localTime root.created_at}}"></time>
|
||||
</a>
|
||||
{{else}}
|
||||
<a href="/posts/{{guid}}">
|
||||
<time datetime="{{created_at}}" title="{{localTime created_at}}" />
|
||||
<time datetime="{{created_at}}" title="{{localTime created_at}}"></time>
|
||||
</a>
|
||||
{{/if}}
|
||||
</span>
|
||||
@@ -59,12 +59,12 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#unless root}}
|
||||
<div id="single-post-moderation" />
|
||||
<div id="single-post-moderation"></div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{#unless root}}
|
||||
<div id="single-post-actions" class="col-md-4" />
|
||||
<div id="single-post-actions" class="col-md-4"></div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
{{#if location.lat}}
|
||||
@@ -92,13 +92,13 @@
|
||||
<div class="post-context">
|
||||
<span class="post-time">
|
||||
<a href="/posts/{{guid}}">
|
||||
<time datetime="{{created_at}}" title="{{localTime created_at}}" />
|
||||
<time datetime="{{created_at}}" title="{{localTime created_at}}"></time>
|
||||
</a>
|
||||
</span>
|
||||
<span id="single-post-moderation" />
|
||||
<span id="single-post-moderation"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="single-post-actions" class="col-md-4" />
|
||||
<div id="single-post-actions" class="col-md-4"></div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<span class="details gray post-timestamp">
|
||||
-
|
||||
<a href="/posts/{{id}}">
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}" />
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}"></time>
|
||||
</a>
|
||||
|
||||
<a href="/posts/{{guid}}" class="permalink" title="{{t "stream.permalink"}}">
|
||||
|
||||
@@ -43,7 +43,7 @@ class AdminsController < Admin::AdminController
|
||||
@created_users = User.where("username IS NOT NULL and created_at IS NOT NULL")
|
||||
@created_users.find_each do |u|
|
||||
week = u.created_at.beginning_of_week.strftime("%Y-%m-%d")
|
||||
@created_users_by_week[week] << u.username
|
||||
@created_users_by_week[week] << {username: u.username, closed_account: u.person.closed_account}
|
||||
end
|
||||
|
||||
@selected_week = params[:week] || @created_users_by_week.keys.last
|
||||
@@ -51,7 +51,11 @@ class AdminsController < Admin::AdminController
|
||||
end
|
||||
|
||||
def stats
|
||||
@popular_tags = ActsAsTaggableOn::Tagging.joins(:tag).limit(50).order('count(taggings.id) DESC').group(:tag).count
|
||||
@popular_tags = ActsAsTaggableOn::Tagging.joins(:tag)
|
||||
.limit(50)
|
||||
.order(Arel.sql("count(taggings.id) DESC"))
|
||||
.group(:tag)
|
||||
.count
|
||||
|
||||
case params[:range]
|
||||
when "week"
|
||||
@@ -72,7 +76,10 @@ class AdminsController < Admin::AdminController
|
||||
create_hash(model, :range => range)
|
||||
end
|
||||
|
||||
@posts_per_day = Post.where("created_at >= ?", Date.today - 21.days).group("DATE(created_at)").order("DATE(created_at) ASC").count
|
||||
@posts_per_day = Post.where("created_at >= ?", Time.zone.today - 21.days)
|
||||
.group(Arel.sql("DATE(created_at)"))
|
||||
.order(Arel.sql("DATE(created_at) ASC"))
|
||||
.count
|
||||
@most_posts_within = @posts_per_day.values.max.to_f
|
||||
|
||||
@user_count = User.count
|
||||
|
||||
@@ -104,8 +104,9 @@ module Api
|
||||
end
|
||||
|
||||
def handle_start_point_response(endpoint)
|
||||
_status, header, response = endpoint.call(request.env)
|
||||
if response.redirect?
|
||||
status, header, _response = endpoint.call(request.env)
|
||||
|
||||
if status.in?([301, 302, 303, 307, 308])
|
||||
redirect_to header["Location"]
|
||||
else
|
||||
save_params_and_render_consent_form(endpoint)
|
||||
|
||||
@@ -29,21 +29,19 @@ class AspectsController < ApplicationController
|
||||
end
|
||||
|
||||
def destroy
|
||||
@aspect = current_user.aspects.where(id: params[:id]).first
|
||||
|
||||
begin
|
||||
if current_user.auto_follow_back && @aspect.id == current_user.auto_follow_back_aspect.id
|
||||
if current_user.auto_follow_back && aspect.id == current_user.auto_follow_back_aspect.id
|
||||
current_user.update(auto_follow_back: false, auto_follow_back_aspect: nil)
|
||||
flash[:notice] = I18n.t "aspects.destroy.success_auto_follow_back", name: @aspect.name
|
||||
flash[:notice] = I18n.t "aspects.destroy.success_auto_follow_back", name: aspect.name
|
||||
else
|
||||
flash[:notice] = I18n.t "aspects.destroy.success", name: @aspect.name
|
||||
flash[:notice] = I18n.t "aspects.destroy.success", name: aspect.name
|
||||
end
|
||||
@aspect.destroy
|
||||
aspect.destroy
|
||||
rescue ActiveRecord::StatementInvalid => e
|
||||
flash[:error] = I18n.t "aspects.destroy.failure", name: @aspect.name
|
||||
flash[:error] = I18n.t "aspects.destroy.failure", name: aspect.name
|
||||
end
|
||||
|
||||
if request.referer.include?('contacts')
|
||||
if request.referer.include?("contacts")
|
||||
redirect_to contacts_path
|
||||
else
|
||||
redirect_to aspects_path
|
||||
@@ -51,41 +49,41 @@ class AspectsController < ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
if @aspect = current_user.aspects.where(:id => params[:id]).first
|
||||
redirect_to aspects_path('a_ids[]' => @aspect.id)
|
||||
if aspect
|
||||
redirect_to aspects_path("a_ids[]" => aspect.id)
|
||||
else
|
||||
redirect_to aspects_path
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@aspect = current_user.aspects.where(:id => params[:id]).first
|
||||
|
||||
if @aspect.update_attributes!(aspect_params)
|
||||
flash[:notice] = I18n.t 'aspects.update.success', :name => @aspect.name
|
||||
if aspect.update!(aspect_params)
|
||||
flash[:notice] = I18n.t "aspects.update.success", name: aspect.name
|
||||
else
|
||||
flash[:error] = I18n.t 'aspects.update.failure', :name => @aspect.name
|
||||
flash[:error] = I18n.t "aspects.update.failure", name: aspect.name
|
||||
end
|
||||
render :json => { :id => @aspect.id, :name => @aspect.name }
|
||||
render json: {id: aspect.id, name: aspect.name}
|
||||
end
|
||||
|
||||
def update_order
|
||||
params[:ordered_aspect_ids].each_with_index do |id, i|
|
||||
current_user.aspects.find(id).update_attributes(order_id: i)
|
||||
current_user.aspects.find(id).update(order_id: i)
|
||||
end
|
||||
head :no_content
|
||||
end
|
||||
|
||||
def toggle_chat_privilege
|
||||
@aspect = current_user.aspects.where(:id => params[:aspect_id]).first
|
||||
|
||||
@aspect.chat_enabled = !@aspect.chat_enabled
|
||||
@aspect.save
|
||||
aspect.chat_enabled = !aspect.chat_enabled
|
||||
aspect.save
|
||||
head :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def aspect
|
||||
@aspect ||= current_user.aspects.where(id: (params[:id] || params[:aspect_id])).first
|
||||
end
|
||||
|
||||
def connect_person_to_aspect(aspecting_person_id)
|
||||
@person = Person.find(aspecting_person_id)
|
||||
if @contact = current_user.contact_for(@person)
|
||||
|
||||
@@ -66,7 +66,7 @@ class ContactsController < ApplicationController
|
||||
when "receiving"
|
||||
current_user.contacts.receiving
|
||||
when "by_aspect"
|
||||
order.unshift "contact_id IS NOT NULL DESC"
|
||||
order.unshift Arel.sql("contact_id IS NOT NULL DESC")
|
||||
contacts_by_aspect(@aspect.id)
|
||||
else
|
||||
raise ArgumentError, "unknown type #{type}"
|
||||
|
||||
@@ -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
|
||||
@@ -113,15 +112,6 @@ class PeopleController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def retrieve_remote
|
||||
if params[:diaspora_handle]
|
||||
Workers::FetchWebfinger.perform_async(params[:diaspora_handle])
|
||||
head :ok
|
||||
else
|
||||
head :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_person
|
||||
|
||||
@@ -147,12 +147,7 @@ class PhotosController < ApplicationController
|
||||
current_user.dispatch_post(@photo, to: photo_params[:aspect_ids])
|
||||
end
|
||||
|
||||
if photo_params[:set_profile_photo]
|
||||
profile_params = {:image_url => @photo.url(:thumb_large),
|
||||
:image_url_medium => @photo.url(:thumb_medium),
|
||||
:image_url_small => @photo.url(:thumb_small)}
|
||||
current_user.update_profile(profile_params)
|
||||
end
|
||||
current_user.update_profile(photo: @photo) if photo_params[:set_profile_photo]
|
||||
|
||||
respond_to do |format|
|
||||
format.json{ render(:layout => false , :json => {"success" => true, "data" => @photo}.to_json )}
|
||||
|
||||
@@ -18,31 +18,23 @@ class UsersController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
password_changed = false
|
||||
user_data = user_params
|
||||
@user = current_user
|
||||
|
||||
if user_data
|
||||
# change password
|
||||
if params[:change_password]
|
||||
password_changed = change_password(user_data)
|
||||
else
|
||||
update_user(user_data)
|
||||
end
|
||||
if params[:change_password] && user_password_params
|
||||
password_changed = change_password(user_password_params)
|
||||
return redirect_to new_user_session_path if password_changed
|
||||
elsif user_params
|
||||
update_user(user_params)
|
||||
end
|
||||
|
||||
if password_changed
|
||||
redirect_to new_user_session_path
|
||||
else
|
||||
set_email_preferences
|
||||
render :edit
|
||||
end
|
||||
set_email_preferences
|
||||
render :edit
|
||||
end
|
||||
|
||||
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")
|
||||
@@ -137,13 +129,9 @@ class UsersController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def user_params
|
||||
params.fetch(:user).permit(
|
||||
:email,
|
||||
:current_password,
|
||||
:password,
|
||||
:password_confirmation,
|
||||
:language,
|
||||
:color_theme,
|
||||
:disable_mail,
|
||||
@@ -152,12 +140,17 @@ class UsersController < ApplicationController
|
||||
:auto_follow_back_aspect_id,
|
||||
:getting_started,
|
||||
:post_default_public,
|
||||
:otp_required_for_login,
|
||||
:otp_secret,
|
||||
email_preferences: UserPreference::VALID_EMAIL_TYPES.map(&:to_sym)
|
||||
)
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
def user_password_params
|
||||
params.fetch(:user).permit(
|
||||
:current_password,
|
||||
:password,
|
||||
:password_confirmation
|
||||
)
|
||||
end
|
||||
|
||||
def update_user(user_data)
|
||||
if user_data[:email_preferences]
|
||||
@@ -177,8 +170,8 @@ class UsersController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def change_password(user_data)
|
||||
if @user.update_with_password(user_data)
|
||||
def change_password(password_params)
|
||||
if @user.update_with_password(password_params)
|
||||
flash[:notice] = t("users.update.password_changed")
|
||||
true
|
||||
else
|
||||
@@ -206,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
|
||||
@@ -236,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)
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module InterimStreamHackinessHelper
|
||||
def commenting_disabled?(post)
|
||||
return true unless user_signed_in?
|
||||
if defined?(@commenting_disabled)
|
||||
@commenting_disabled
|
||||
elsif defined?(@stream)
|
||||
!@stream.can_comment?(post)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
##### These methods need to go away once we pass publisher object into the partial ######
|
||||
def publisher_formatted_text
|
||||
if params[:prefill].present?
|
||||
|
||||
@@ -5,7 +5,7 @@ module MetaDataHelper
|
||||
include ActionView::Helpers::TagHelper
|
||||
|
||||
def og_prefix
|
||||
'og: http://ogp.me/ns# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#'
|
||||
"og: https://ogp.me/ns# article: https://ogp.me/ns/article# profile: https://ogp.me/ns/profile#"
|
||||
end
|
||||
|
||||
def site_url
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,7 +11,7 @@ module SessionsHelper
|
||||
end
|
||||
|
||||
def display_registration_link?
|
||||
AppConfig.settings.enable_registrations? && devise_mapping.registerable? && controller_name != "registrations"
|
||||
AppConfig.settings.enable_registrations? && controller_name != "registrations"
|
||||
end
|
||||
|
||||
def display_password_reset_link?
|
||||
|
||||
@@ -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
|
||||
|
||||
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' }
|
||||
private
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -90,6 +90,10 @@ class AccountMigration < ApplicationRecord
|
||||
old_user && new_user
|
||||
end
|
||||
|
||||
def includes_photo_migration?
|
||||
remote_photo_path.present?
|
||||
end
|
||||
|
||||
# We need to resend contacts of users of our pod for the remote new person so that the remote pod received this
|
||||
# contact information from the authoritative source.
|
||||
def dispatch_contacts
|
||||
@@ -122,13 +126,14 @@ class AccountMigration < ApplicationRecord
|
||||
end
|
||||
|
||||
def update_all_references
|
||||
update_remote_photo_path if remotely_initiated? && includes_photo_migration?
|
||||
update_person_references
|
||||
update_user_references if user_changed_id_locally?
|
||||
end
|
||||
|
||||
def person_references
|
||||
references = Person.reflections.reject {|key, _|
|
||||
%w[profile owner notifications pod].include?(key)
|
||||
%w[profile owner notifications pod account_deletion account_migration].include?(key)
|
||||
}
|
||||
|
||||
references.map {|key, value|
|
||||
@@ -200,6 +205,20 @@ class AccountMigration < ApplicationRecord
|
||||
.destroy_all
|
||||
end
|
||||
|
||||
def update_remote_photo_path
|
||||
Photo.where(author: old_person)
|
||||
.update_all(remote_photo_path: remote_photo_path) # rubocop:disable Rails/SkipsModelValidations
|
||||
return unless user_left_our_pod?
|
||||
|
||||
Photo.where(author: old_person).find_in_batches do |batch|
|
||||
batch.each do |photo|
|
||||
photo.processed_image = nil
|
||||
photo.unprocessed_image = nil
|
||||
logger.warn "Error cleaning up photo #{photo.id}" unless photo.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_person_references
|
||||
logger.debug "Updating references from person id=#{old_person.id} to person id=#{new_person.id}"
|
||||
eliminate_person_duplicates
|
||||
|
||||
@@ -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
|
||||
@@ -4,16 +4,16 @@ class Block < ApplicationRecord
|
||||
belongs_to :person
|
||||
belongs_to :user
|
||||
|
||||
delegate :name, to: :person, prefix: true
|
||||
delegate :name, :diaspora_handle, to: :person, prefix: true
|
||||
|
||||
validates :person_id, uniqueness: {scope: :user_id}
|
||||
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -57,6 +57,9 @@ class Person < ApplicationRecord
|
||||
|
||||
has_many :mentions, :dependent => :destroy
|
||||
|
||||
has_one :account_deletion, dependent: :destroy
|
||||
has_one :account_migration, foreign_key: :old_person_id, dependent: :nullify, inverse_of: :old_person
|
||||
|
||||
validate :owner_xor_pod
|
||||
validate :other_person_with_same_guid, on: :create
|
||||
validates :profile, :presence => true
|
||||
@@ -162,7 +165,7 @@ class Person < ApplicationRecord
|
||||
contacts.id IS NOT NULL AS is_contact
|
||||
SQL
|
||||
)
|
||||
.order(<<-SQL
|
||||
.order(Arel.sql(<<-SQL
|
||||
is_author DESC,
|
||||
is_commenter DESC,
|
||||
is_liker DESC,
|
||||
@@ -170,7 +173,7 @@ class Person < ApplicationRecord
|
||||
profiles.full_name,
|
||||
people.diaspora_handle
|
||||
SQL
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
def self.community_spotlight
|
||||
@@ -185,6 +188,8 @@ class Person < ApplicationRecord
|
||||
# end
|
||||
# will not work! The nil profile will be overriden with an empty one.
|
||||
def initialize(params={})
|
||||
params = {} if params.nil?
|
||||
|
||||
profile_set = params.has_key?(:profile) || params.has_key?("profile")
|
||||
params[:profile_attributes] = params.delete(:profile) if params.has_key?(:profile) && params[:profile].is_a?(Hash)
|
||||
super
|
||||
@@ -207,7 +212,7 @@ class Person < ApplicationRecord
|
||||
self.guid
|
||||
end
|
||||
|
||||
private_class_method def self.search_query_string(query)
|
||||
def self.search_query_string(query)
|
||||
query = query.downcase
|
||||
like_operator = AppConfig.postgres? ? "ILIKE" : "LIKE"
|
||||
|
||||
@@ -239,7 +244,7 @@ class Person < ApplicationRecord
|
||||
query = query.where(contacts: {sharing: true, receiving: true}) if mutual
|
||||
|
||||
query.where(closed_account: false)
|
||||
.order(["contacts.user_id IS NULL", "profiles.last_name ASC", "profiles.first_name ASC"])
|
||||
.order([Arel.sql("contacts.user_id IS NULL"), "profiles.last_name ASC", "profiles.first_name ASC"])
|
||||
end
|
||||
|
||||
def name(opts = {})
|
||||
|
||||
@@ -68,11 +68,9 @@ class Photo < ApplicationRecord
|
||||
|
||||
def ownership_of_status_message
|
||||
message = StatusMessage.find_by_guid(self.status_message_guid)
|
||||
if self.status_message_guid && message
|
||||
self.diaspora_handle == message.diaspora_handle
|
||||
else
|
||||
true
|
||||
end
|
||||
return unless status_message_guid && message && diaspora_handle != message.diaspora_handle
|
||||
|
||||
errors.add(:base, "Photo must have the same owner as status message")
|
||||
end
|
||||
|
||||
def self.diaspora_initialize(params={})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,6 +21,7 @@ class Profile < ApplicationRecord
|
||||
validates :first_name, :length => { :maximum => 32 }
|
||||
validates :last_name, :length => { :maximum => 32 }
|
||||
validates :location, :length => { :maximum =>255 }
|
||||
validates :gender, length: {maximum: 255}
|
||||
|
||||
validates_format_of :first_name, :with => /\A[^;]+\z/, :allow_blank => true
|
||||
validates_format_of :last_name, :with => /\A[^;]+\z/, :allow_blank => true
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,69 +1,78 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Services::Tumblr < Service
|
||||
MAX_CHARACTERS = 1000
|
||||
module Services
|
||||
class Tumblr < Service
|
||||
MAX_CHARACTERS = 1000
|
||||
|
||||
def provider
|
||||
"tumblr"
|
||||
end
|
||||
|
||||
def consumer_key
|
||||
AppConfig.services.tumblr.key
|
||||
end
|
||||
|
||||
def consumer_secret
|
||||
AppConfig.services.tumblr.secret
|
||||
end
|
||||
|
||||
def post(post, url='')
|
||||
body = build_tumblr_post(post, url)
|
||||
user_info = JSON.parse(client.get("/v2/user/info").body)
|
||||
blogs = user_info["response"]["user"]["blogs"]
|
||||
primaryblog = blogs.find {|blog| blog["primary"] } || blogs[0]
|
||||
tumblr_ids = {}
|
||||
|
||||
blogurl = URI.parse(primaryblog["url"])
|
||||
resp = client.post("/v2/blog/#{blogurl.host}/post", body)
|
||||
if resp.code == "201"
|
||||
tumblr_ids[blogurl.host.to_s] = JSON.parse(resp.body)["response"]["id"]
|
||||
def provider
|
||||
"tumblr"
|
||||
end
|
||||
|
||||
post.tumblr_ids = tumblr_ids.to_json
|
||||
post.save
|
||||
end
|
||||
def post(post, url="") # rubocop:disable Metrics/AbcSize
|
||||
return true if post.nil? # return if post is deleted while waiting in queue
|
||||
|
||||
def build_tumblr_post(post, url)
|
||||
{ :type => 'text', :format => "markdown", :body => tumblr_template(post, url) }
|
||||
end
|
||||
body = build_tumblr_post(post, url)
|
||||
user_info = JSON.parse(client.get("/v2/user/info").body)
|
||||
blogs = user_info["response"]["user"]["blogs"]
|
||||
primaryblog = blogs.find {|blog| blog["primary"] } || blogs[0]
|
||||
|
||||
def tumblr_template(post, url)
|
||||
photo_html = post.photos.map {|photo|
|
||||
"})\n\n"
|
||||
}.join
|
||||
tumblr_ids = {}
|
||||
|
||||
"#{photo_html}#{post.message.html(mentioned_people: [])}\n\n[original post](#{url})"
|
||||
end
|
||||
blogurl = URI.parse(primaryblog["url"])
|
||||
tumblr_ids[blogurl.host.to_s] = request_to_external_blog(blogurl, body)
|
||||
|
||||
def post_opts(post)
|
||||
{tumblr_ids: post.tumblr_ids} if post.tumblr_ids.present?
|
||||
end
|
||||
|
||||
def delete_from_service(opts)
|
||||
logger.debug "event=delete_from_service type=tumblr sender_id=#{user_id} tumblr_ids=#{opts[:tumblr_ids]}"
|
||||
tumblr_posts = JSON.parse(opts[:tumblr_ids])
|
||||
tumblr_posts.each do |blog_name, post_id|
|
||||
delete_from_tumblr(blog_name, post_id)
|
||||
post.tumblr_ids = tumblr_ids.to_json
|
||||
post.save
|
||||
end
|
||||
end
|
||||
|
||||
def delete_from_tumblr(blog_name, service_post_id)
|
||||
client.post("/v2/blog/#{blog_name}/post/delete", "id" => service_post_id)
|
||||
end
|
||||
def post_opts(post)
|
||||
{tumblr_ids: post.tumblr_ids} if post.tumblr_ids.present?
|
||||
end
|
||||
|
||||
private
|
||||
def client
|
||||
@consumer ||= OAuth::Consumer.new(consumer_key, consumer_secret, :site => 'http://api.tumblr.com')
|
||||
@client ||= OAuth::AccessToken.new(@consumer, self.access_token, self.access_secret)
|
||||
def delete_from_service(opts)
|
||||
logger.debug "event=delete_from_service type=tumblr sender_id=#{user_id} tumblr_ids=#{opts[:tumblr_ids]}"
|
||||
tumblr_posts = JSON.parse(opts[:tumblr_ids])
|
||||
tumblr_posts.each do |blog_name, post_id|
|
||||
delete_from_tumblr(blog_name, post_id)
|
||||
end
|
||||
end
|
||||
|
||||
def build_tumblr_post(post, url)
|
||||
{type: "text", format: "markdown", body: tumblr_template(post, url), tags: tags(post), native_inline_images: true}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def client
|
||||
@consumer ||= OAuth::Consumer.new(consumer_key, consumer_secret, site: "https://api.tumblr.com")
|
||||
@client ||= OAuth::AccessToken.new(@consumer, access_token, access_secret)
|
||||
end
|
||||
|
||||
def tumblr_template(post, url)
|
||||
photo_html = post.photos.map {|photo| "})\n\n" }.join
|
||||
|
||||
"#{photo_html}#{post.message.html(mentioned_people: [])}\n\n[original post](#{url})"
|
||||
end
|
||||
|
||||
def tags(post)
|
||||
post.tags.pluck(:name).join(",").to_s
|
||||
end
|
||||
|
||||
def delete_from_tumblr(blog_name, service_post_id)
|
||||
client.post("/v2/blog/#{blog_name}/post/delete", "id" => service_post_id)
|
||||
end
|
||||
|
||||
def request_to_external_blog(blogurl, body)
|
||||
resp = client.post("/v2/blog/#{blogurl.host}/post", body)
|
||||
JSON.parse(resp.body)["response"]["id"] if resp.code == "201"
|
||||
end
|
||||
|
||||
def consumer_key
|
||||
AppConfig.services.tumblr.key
|
||||
end
|
||||
|
||||
def consumer_secret
|
||||
AppConfig.services.tumblr.secret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
require "attr_encrypted"
|
||||
|
||||
class User < ApplicationRecord
|
||||
include AuthenticationToken
|
||||
include Connecting
|
||||
@@ -34,10 +36,8 @@ class User < ApplicationRecord
|
||||
before_validation :set_current_language, :on => :create
|
||||
before_validation :set_default_color_theme, on: :create
|
||||
|
||||
validates :username, :presence => true, :uniqueness => true
|
||||
validates_format_of :username, :with => /\A[A-Za-z0-9_]+\z/
|
||||
validates_length_of :username, :maximum => 32
|
||||
validates_exclusion_of :username, :in => AppConfig.settings.username_blacklist
|
||||
validates :username, presence: true, uniqueness: true, format: {with: /\A[A-Za-z0-9_.\-]+\z/},
|
||||
length: {maximum: 32}, exclusion: {in: AppConfig.settings.username_blacklist}
|
||||
validates_inclusion_of :language, :in => AVAILABLE_LANGUAGE_CODES
|
||||
validates :color_theme, inclusion: {in: AVAILABLE_COLOR_THEMES}, allow_blank: true
|
||||
validates_format_of :unconfirmed_email, :with => Devise.email_regexp, :allow_blank => true
|
||||
@@ -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
|
||||
@@ -442,8 +442,13 @@ class User < ApplicationRecord
|
||||
aq = self.aspects.create(:name => I18n.t('aspects.seed.acquaintances'))
|
||||
|
||||
if AppConfig.settings.autofollow_on_join?
|
||||
default_account = Person.find_or_fetch_by_identifier(AppConfig.settings.autofollow_on_join_user)
|
||||
self.share_with(default_account, aq) if default_account
|
||||
begin
|
||||
default_account = Person.find_or_fetch_by_identifier(AppConfig.settings.autofollow_on_join_user)
|
||||
share_with(default_account, aq)
|
||||
rescue DiasporaFederation::Discovery::DiscoveryError
|
||||
logger.warn "Error auto-sharing with #{AppConfig.settings.autofollow_on_join_user}
|
||||
fix autofollow_on_join_user in configuration."
|
||||
end
|
||||
end
|
||||
aq
|
||||
end
|
||||
@@ -530,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!
|
||||
|
||||
@@ -58,7 +58,7 @@ class User
|
||||
if destroy
|
||||
contact.destroy
|
||||
else
|
||||
contact.update_attributes(direction => false)
|
||||
contact.update(direction => false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -105,15 +107,19 @@ class NodeInfoPresenter
|
||||
end
|
||||
|
||||
def local_posts
|
||||
@local_posts ||= Post.where(type: "StatusMessage")
|
||||
.joins(:author)
|
||||
.where("owner_id IS NOT null")
|
||||
.count
|
||||
Rails.cache.fetch("NodeInfoPresenter/local_posts", expires_in: 1.hour) do
|
||||
@local_posts ||= Post.where(type: "StatusMessage")
|
||||
.joins(:author)
|
||||
.where.not(people: {owner_id: nil})
|
||||
.count
|
||||
end
|
||||
end
|
||||
|
||||
def local_comments
|
||||
@local_comments ||= Comment.joins(:author)
|
||||
.where("owner_id IS NOT null")
|
||||
.count
|
||||
Rails.cache.fetch("NodeInfoPresenter/local_comments", expires_in: 1.hour) do
|
||||
@local_comments ||= Comment.joins(:author)
|
||||
.where.not(people: {owner_id: nil})
|
||||
.count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,7 +24,7 @@ class PersonPresenter < BasePresenter
|
||||
end
|
||||
|
||||
def hovercard
|
||||
base_hash_with_contact.merge(profile: ProfilePresenter.new(profile).for_hovercard)
|
||||
full_hash.merge(profile: ProfilePresenter.new(profile).for_hovercard)
|
||||
end
|
||||
|
||||
def metas_attributes
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
module Export
|
||||
class AspectSerializer < ActiveModel::Serializer
|
||||
attributes :name, :chat_enabled
|
||||
attributes :name
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,8 @@ module Export
|
||||
:show_community_spotlight_in_stream,
|
||||
:auto_follow_back,
|
||||
:auto_follow_back_aspect,
|
||||
:strip_exif
|
||||
:strip_exif,
|
||||
:blocks
|
||||
has_one :profile, serializer: FederationEntitySerializer
|
||||
has_many :contact_groups, each_serializer: Export::AspectSerializer
|
||||
has_many :contacts, each_serializer: Export::ContactSerializer
|
||||
@@ -45,6 +46,10 @@ module Export
|
||||
}
|
||||
end
|
||||
|
||||
def blocks
|
||||
object.blocks.map(&:person_diaspora_handle)
|
||||
end
|
||||
|
||||
%i[comments likes poll_participations].each {|collection|
|
||||
delegate collection, to: :person
|
||||
}
|
||||
|
||||
@@ -5,11 +5,26 @@
|
||||
# are used as for federation messages generation.
|
||||
class FederationEntitySerializer < ActiveModel::Serializer
|
||||
include SerializerPostProcessing
|
||||
include Diaspora::Logging
|
||||
|
||||
private
|
||||
|
||||
def modify_serializable_object(hash)
|
||||
hash.merge(entity.to_json)
|
||||
rescue DiasporaFederation::Entities::Relayable::AuthorPrivateKeyNotFound => e
|
||||
# The author of this relayable probably migrated from this pod to a different pod,
|
||||
# and we neither have the signature nor the new private key to generate a valid signature.
|
||||
# But we can use the private key of the old user to generate the signature it had when this entity was created
|
||||
old_person = AccountMigration.joins(:old_person)
|
||||
.where("new_person_id = ? AND people.owner_id IS NOT NULL", object.author_id)
|
||||
.first.old_person
|
||||
if old_person
|
||||
logger.info "Using private key of #{old_person.diaspora_handle} to export: #{e.message}"
|
||||
object.author = old_person
|
||||
hash.merge(entity.to_json)
|
||||
else
|
||||
logger.warn "Skip entity for export because #{e.class}: #{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
def entity
|
||||
|
||||
@@ -22,7 +22,7 @@ class LikeService
|
||||
|
||||
def find_for_post(post_id)
|
||||
likes = post_service.find!(post_id).likes
|
||||
user ? likes.order("author_id = #{user.person.id} DESC") : likes
|
||||
user ? likes.order(Arel.sql("author_id = #{user.person.id} DESC")) : likes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -13,7 +13,7 @@ class ReshareService
|
||||
|
||||
def find_for_post(post_id)
|
||||
reshares = post_service.find!(post_id).reshares
|
||||
user ? reshares.order("author_id = #{user.person.id} DESC") : reshares
|
||||
user ? reshares.order(Arel.sql("author_id = #{user.person.id} DESC")) : reshares
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -9,7 +9,7 @@ class ExportedUser < SecureUploader
|
||||
"uploads/users"
|
||||
end
|
||||
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[gz]
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class ProcessedImage < CarrierWave::Uploader::Base
|
||||
"uploads/images"
|
||||
end
|
||||
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg png gif]
|
||||
end
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class UnprocessedImage < CarrierWave::Uploader::Base
|
||||
"uploads/images"
|
||||
end
|
||||
|
||||
def extension_whitelist
|
||||
def extension_allowlist
|
||||
%w[jpg jpeg png gif]
|
||||
end
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
.row
|
||||
%p.col-md-12.alert.alert-info.text-center{role: "alert"}
|
||||
!= t("admins.stats.current_segment",
|
||||
post_yest: content_tag(:strong, posts[:yesterday] / user_count),
|
||||
post_day: content_tag(:strong, posts[:day_before] / user_count))
|
||||
post_yest: content_tag(:strong, "%0.2f" % (posts[:yesterday] / user_count)),
|
||||
post_day: content_tag(:strong, "%0.2f" % (posts[:day_before] / user_count)))
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
|
||||
@@ -18,4 +18,8 @@
|
||||
= t(".amount_of", count: counter)
|
||||
%br
|
||||
- created_users_by_week[selected_week].each do |m|
|
||||
= link_to m, "/u/#{m}"
|
||||
- if m[:closed_account]
|
||||
%s
|
||||
= m[:username]
|
||||
- else
|
||||
= link_to m[:username], "/u/#{m[:username]}"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
- else
|
||||
= t("shared.aspect_dropdown.toggle", count: selected_aspects.size)
|
||||
%span.caret
|
||||
%ul.dropdown-menu.pull-right{unSelectable: "on"}
|
||||
%ul.dropdown-menu.aspect-membership.pull-right{unSelectable: "on"}
|
||||
|
||||
%li.public.radio{"data-aspect_id" => "public", :class => ("selected" if public_selected?(selected_aspects))}
|
||||
%a
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
%script{nonce: content_security_policy_nonce(:script)}
|
||||
%script{nonce: content_security_policy_script_nonce}
|
||||
:plain
|
||||
$(document).ready(function () {
|
||||
var data = $.parseJSON( "#{escape_javascript(@contacts_json).html_safe}" ),
|
||||
|
||||
@@ -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)
|
||||
@@ -1,7 +0,0 @@
|
||||
<%= t('devise.mailer.welcome', :email => @resource.email) %>
|
||||
|
||||
<%= t('.you_can_confirm') %>
|
||||
|
||||
[<%= t('.confirm') %>][1]
|
||||
|
||||
[1]: <%= confirmation_url(@resource, :confirmation_token => @token) %>
|
||||
@@ -0,0 +1,4 @@
|
||||
<%= t("devise.mailer.welcome", username: @resource.username) %>
|
||||
|
||||
<%= t(".you_can_confirm") %>
|
||||
<%= confirmation_url(@resource, confirmation_token: @token) %>
|
||||
@@ -1 +0,0 @@
|
||||
<%= t('.message', :invite_url => invite_code_url(@invitation_code)) %>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user