mirror of
https://github.com/diaspora/diaspora.git
synced 2026-01-13 09:07:58 -05:00
Compare commits
538 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 | ||
|
|
09a425cbbc | ||
|
|
1e8a96d817 | ||
|
|
d674f53910 | ||
|
|
5602dc4418 | ||
|
|
88e35d3f3a | ||
|
|
ef31ea6b96 | ||
|
|
78538d034a | ||
|
|
d8b3718a08 | ||
|
|
1227f34b2a | ||
|
|
4a22f08539 | ||
|
|
dc7c5ffef6 | ||
|
|
5aec9b966c | ||
|
|
e5ba9a1a46 | ||
|
|
4feab5219e | ||
|
|
469983a623 | ||
|
|
6826e89a95 | ||
|
|
e04ddd0bcc | ||
|
|
4d02aee375 | ||
|
|
165b8f4f6e | ||
|
|
2d23a2601e | ||
|
|
3704be8bec | ||
|
|
39b86ed486 | ||
|
|
83a9877def | ||
|
|
554faa4116 | ||
|
|
caf822f497 | ||
|
|
54fd4846c0 | ||
|
|
ecda6eccf6 | ||
|
|
3c06bb2f4c | ||
|
|
ef137f09f2 | ||
|
|
607659939d | ||
|
|
9d5b981809 | ||
|
|
3f74a759b3 | ||
|
|
1e827161fe | ||
|
|
17af65e22c | ||
|
|
91aae4d755 | ||
|
|
035b6f39fc | ||
|
|
2073791cee | ||
|
|
5b6cef0679 | ||
|
|
d443401361 | ||
|
|
a38a93523d | ||
|
|
a28be72e74 | ||
|
|
093cca9a76 | ||
|
|
ccbc65993d | ||
|
|
d9d0eb1512 | ||
|
|
f8419b14ba | ||
|
|
290ddbf271 | ||
|
|
48c4cabd3f | ||
|
|
18d7b38037 | ||
|
|
01468c34dd | ||
|
|
7ae2dc6249 | ||
|
|
6f53f1bc0a | ||
|
|
5195f7daac | ||
|
|
2585fb9b49 | ||
|
|
02617a3562 | ||
|
|
0372924b90 | ||
|
|
05472cc4f9 | ||
|
|
da39750244 | ||
|
|
3b0f435f69 | ||
|
|
adaca8d0a3 | ||
|
|
8a10655f7f | ||
|
|
c8bef1077d | ||
|
|
da83456660 | ||
|
|
b7183d7cee | ||
|
|
cd7af6df50 | ||
|
|
54e44d6d7e | ||
|
|
a63f11bbf4 | ||
|
|
7b201f4bb9 | ||
|
|
f4fa7e10bd | ||
|
|
23d637b9a1 | ||
|
|
360780c17f | ||
|
|
c253272d83 | ||
|
|
c063f6fa1b | ||
|
|
94a32b2833 | ||
|
|
a4031e09e1 | ||
|
|
663da1ef25 | ||
|
|
7595168e01 | ||
|
|
189923040d | ||
|
|
a3a0a1fba9 | ||
|
|
4687d7e1ea | ||
|
|
e47d0d9675 | ||
|
|
3ea4396ddb | ||
|
|
1edcb0013c | ||
|
|
1925127964 | ||
|
|
2894984f57 | ||
|
|
71595b4cbd | ||
|
|
654b524397 | ||
|
|
efcaa860ac | ||
|
|
3f700c3960 | ||
|
|
c8a1f308c6 | ||
|
|
6804132c15 | ||
|
|
58d2ce7ba6 | ||
|
|
a21cde4c00 | ||
|
|
5a0381f832 | ||
|
|
2d6a68c28f |
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
|
||||
|
||||
47
.rubocop.yml
47
.rubocop.yml
@@ -1,24 +1,24 @@
|
||||
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
|
||||
# the code easier to read (by naming things), but can also clutter the class
|
||||
Metrics/MethodLength:
|
||||
Metrics/MethodLength:
|
||||
Max: 20
|
||||
|
||||
# The guiding principle of classes is SRP, SRP can't be accurately measured by LoC
|
||||
@@ -26,11 +26,17 @@ Metrics/ClassLength:
|
||||
Max: 1500
|
||||
Metrics/ModuleLength:
|
||||
Max: 1500
|
||||
|
||||
# Raise AbcSize from 15 to 20
|
||||
|
||||
# Raise complexity metrics
|
||||
Metrics/AbcSize:
|
||||
Max: 20
|
||||
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 20
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 20
|
||||
|
||||
# Some blocks are longer.
|
||||
Metrics/BlockLength:
|
||||
ExcludedMethods:
|
||||
@@ -51,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
|
||||
|
||||
@@ -79,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:
|
||||
@@ -88,7 +99,7 @@ Lint/AssignmentInCondition:
|
||||
AllowSafeAssignment: false
|
||||
|
||||
# A specialized exception class will take one or more arguments and construct the message from it.
|
||||
# So both variants make sense.
|
||||
# So both variants make sense.
|
||||
Style/RaiseArgs:
|
||||
Enabled: false
|
||||
|
||||
@@ -106,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:
|
||||
@@ -151,11 +162,11 @@ Lint/ShadowingOuterLocalVariable:
|
||||
|
||||
# Check with yard instead.
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
Enabled: false
|
||||
|
||||
# This is just silly. Calling the argument `other` in all cases makes no sense.
|
||||
Naming/BinaryOperatorParameterName:
|
||||
Enabled: false
|
||||
Enabled: false
|
||||
|
||||
# There are valid cases, for example debugging Cucumber steps,
|
||||
# also they'll fail CI anyway
|
||||
@@ -169,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}"
|
||||
168
Changelog.md
168
Changelog.md
@@ -1,3 +1,171 @@
|
||||
# 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
|
||||
* Harmonize markdown titles sizes [#8029](https://github.com/diaspora/diaspora/pull/8029)
|
||||
|
||||
## Bug fixes
|
||||
* Improve handling of mixed case hostnames while fetching OpenGraph data [#8021](https://github.com/diaspora/diaspora/pull/8021)
|
||||
* Fix "remember me" with two factor authentication enabled [#8031](https://github.com/diaspora/diaspora/pull/8031)
|
||||
|
||||
## Features
|
||||
* Add line mentioning diaspora\* on the splash page [#7966](https://github.com/diaspora/diaspora/pull/7966)
|
||||
* Improve communication about signing up on closed pods [#7896](https://github.com/diaspora/diaspora/pull/7896)
|
||||
|
||||
# 0.7.11.0
|
||||
|
||||
## Refactor
|
||||
* Enable paranoid mode for devise [#8003](https://github.com/diaspora/diaspora/pull/8003)
|
||||
* Refactor likes cucumber test [#8002](https://github.com/diaspora/diaspora/pull/8002)
|
||||
|
||||
## Bug fixes
|
||||
* Fix old photos without remote url for export [#8012](https://github.com/diaspora/diaspora/pull/8012)
|
||||
|
||||
## Features
|
||||
* Add a manifest.json file as a first step to make diaspora\* a Progressive Web App [#7998](https://github.com/diaspora/diaspora/pull/7998)
|
||||
* Allow `web+diaspora://` links to link to a profile with only the diaspora ID [#8000](https://github.com/diaspora/diaspora/pull/8000)
|
||||
* Support TOTP two factor authentication [#7751](https://github.com/diaspora/diaspora/pull/7751)
|
||||
|
||||
# 0.7.10.0
|
||||
|
||||
## Refactor
|
||||
* Replace dandelion.jpg with a public domain photo [#7976](https://github.com/diaspora/diaspora/pull/7976)
|
||||
|
||||
## Bug fixes
|
||||
* Fix incorrect post sorting on tag streams and tag searches for tags containing the word "activity" [#7959](https://github.com/diaspora/diaspora/issues/7959)
|
||||
|
||||
# 0.7.9.0
|
||||
|
||||
## Refactor
|
||||
* Improve public stream performance and cleanup unused indexes [#7944](https://github.com/diaspora/diaspora/pull/7944)
|
||||
* Improve wording of "Toggle mobile" [#7926](https://github.com/diaspora/diaspora/pull/7926)
|
||||
|
||||
## Bug fixes
|
||||
* Do not autofollow back a user you are ignoring [#7913](https://github.com/diaspora/diaspora/pull/7913)
|
||||
* Fix photos gallery when too many thumbnails are shown [#7943](https://github.com/diaspora/diaspora/pull/7943)
|
||||
* Fix extended profile visibility switch showing the wrong state [#7955](https://github.com/diaspora/diaspora/pull/7955)
|
||||
|
||||
## Features
|
||||
* Support ignore users on mobile [#7884](https://github.com/diaspora/diaspora/pull/7884)
|
||||
|
||||
# 0.7.8.0
|
||||
|
||||
## Refactor
|
||||
|
||||
213
Gemfile
213
Gemfile
@@ -2,113 +2,112 @@
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "rails", "5.1.6"
|
||||
gem "rails", "6.1.6.1"
|
||||
|
||||
# Legacy Rails features, remove me!
|
||||
# responders (class level)
|
||||
gem "responders", "2.4.0"
|
||||
gem "responders", "3.0.1"
|
||||
|
||||
# Appserver
|
||||
|
||||
gem "unicorn", "5.4.1", 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.5"
|
||||
gem "diaspora_federation-rails", "0.2.5"
|
||||
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.1.0"
|
||||
gem "json-schema", "2.8.1"
|
||||
gem "json", "2.6.2"
|
||||
gem "json-schema", "3.0.0"
|
||||
|
||||
# Authentication
|
||||
|
||||
gem "devise", "4.5.0"
|
||||
gem "devise", "4.8.1"
|
||||
gem "devise_lastseenable", "0.0.6"
|
||||
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.3"
|
||||
gem "redis", "4.7.0"
|
||||
gem "sidekiq", "6.5.1"
|
||||
|
||||
# Scheduled processing
|
||||
|
||||
gem "sidekiq-cron", "1.0.4"
|
||||
gem "sidekiq-cron", "1.6.0"
|
||||
|
||||
# Compression
|
||||
|
||||
gem "uglifier", "4.1.19"
|
||||
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 "bootstrap-sass", "3.3.7"
|
||||
gem "bootstrap-switch-rails", "3.3.4"
|
||||
gem "compass-rails", "3.1.0"
|
||||
gem "sass-rails", "5.0.7"
|
||||
gem "sprockets-rails", "3.2.1"
|
||||
gem "autoprefixer-rails", "10.4.7.0"
|
||||
gem "bootstrap-sass", "3.4.1"
|
||||
gem "bootstrap-switch-rails", "3.3.3" # 3.3.4 and 3.3.5 is broken, see https://github.com/Bttstrp/bootstrap-switch/issues/691
|
||||
gem "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.3"
|
||||
gem "pg", "1.4.1"
|
||||
end
|
||||
|
||||
|
||||
gem "activerecord-import", "0.27.0"
|
||||
gem "activerecord-import", "1.4.0"
|
||||
|
||||
# File uploading
|
||||
|
||||
gem "carrierwave", "1.2.3"
|
||||
gem "fog-aws", "3.3.0"
|
||||
gem "mini_magick", "4.9.2"
|
||||
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.2"
|
||||
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"
|
||||
@@ -129,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.2"
|
||||
|
||||
# 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.8.5"
|
||||
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.0.0"
|
||||
gem "secure_headers", "6.3.3"
|
||||
|
||||
# Services
|
||||
|
||||
gem "omniauth", "1.8.1"
|
||||
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.3"
|
||||
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.1"
|
||||
gem "gon", "6.4.0"
|
||||
gem "hamlit", "2.16.0"
|
||||
gem "mobile-fu", "1.4.0"
|
||||
gem "rails-timeago", "2.16.0"
|
||||
gem "will_paginate", "3.1.6"
|
||||
gem "rails-timeago", "2.20.0"
|
||||
gem "will_paginate", "3.3.1"
|
||||
|
||||
# Logging
|
||||
|
||||
@@ -199,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".
|
||||
@@ -234,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.5.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.9.10", 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.60.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.11.1"
|
||||
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", "3.1.2"
|
||||
gem "timecop", "0.9.1"
|
||||
gem "webmock", "3.4.2", 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.5"
|
||||
|
||||
# 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.1"
|
||||
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.2"
|
||||
gem "rails-controller-testing", "1.0.5"
|
||||
end
|
||||
|
||||
1118
Gemfile.lock
1118
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
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
BIN
app/assets/images/branding/logos/app-icon-512.png
Normal file
BIN
app/assets/images/branding/logos/app-icon-512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
BIN
app/assets/images/branding/logos/app-icon.png
Normal file
BIN
app/assets/images/branding/logos/app-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 64 KiB |
@@ -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;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ app.models.Stream = Backbone.Collection.extend({
|
||||
},
|
||||
|
||||
sortOrder : function() {
|
||||
return /activity/.test(this.basePath()) ? "interactedAt" : "createdAt";
|
||||
return /^\/activity/.test(this.basePath()) ? "interactedAt" : "createdAt";
|
||||
},
|
||||
|
||||
/* This function is for adding a large number of posts one by one.
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -41,7 +41,7 @@ app.views.Gallery = app.views.Base.extend({
|
||||
if (image.naturalHeight > window.innerHeight && image.naturalHeight > image.naturalWidth * 2) {
|
||||
image.classList.add("too-tall");
|
||||
} else {
|
||||
var margins = 95; // Margins are 80px for thumbnails height and 15px for top image margin
|
||||
var margins = 110; // Margins are 80px for thumbnails height and 15px for top image margin + scroll-x height
|
||||
image.style = "max-height: " + (window.innerHeight - margins) + "px";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -10,14 +10,15 @@ body {
|
||||
.page-contacts,
|
||||
.page-conversations,
|
||||
.page-notifications,
|
||||
.page-people.action-show,
|
||||
.page-people.action-contacts,
|
||||
.page-people.action-show,
|
||||
.page-photos,
|
||||
.page-posts,
|
||||
.page-profiles.action-edit,
|
||||
.page-services.action-index,
|
||||
.page-streams,
|
||||
.page-tags,
|
||||
.page-two_factor_authentications,
|
||||
.page-user_applications,
|
||||
.page-users.action-edit,
|
||||
.page-users.action-update,
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -93,5 +93,10 @@ textarea {
|
||||
}
|
||||
|
||||
::placeholder { text-transform: uppercase; }
|
||||
|
||||
p {
|
||||
margin-top: .5rem;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,15 +50,16 @@ $margin: 15px;
|
||||
|
||||
.indicator {
|
||||
bottom: 0;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
|
||||
li {
|
||||
border: 0;
|
||||
border-radius: $thumbnail-size / 2;
|
||||
height: $thumbnail-size;
|
||||
margin: 6px;
|
||||
margin-bottom: $margin;
|
||||
margin: $margin 6px;
|
||||
vertical-align: middle;
|
||||
width: $thumbnail-size;
|
||||
background-size: cover;
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,14 @@
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.part-of-diaspora {
|
||||
font-style: italic;
|
||||
|
||||
a {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
fieldset { background: none; }
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
.page-sessions.action-new,
|
||||
.page-sessions.action-create,
|
||||
.page-passwords.action-new,
|
||||
.page-passwords.action-edit {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.7rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.3rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.img-responsive {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@@ -350,6 +350,7 @@ footer {
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
margin: 0;
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
@@ -694,6 +695,21 @@ select#aspect_ids_ {
|
||||
.entypo-camera { margin-right: 0; }
|
||||
}
|
||||
|
||||
.mobile-icon-bar {
|
||||
background: $framed-background;
|
||||
border-top: 1px solid $border-grey;
|
||||
display: block;
|
||||
padding: 1px 6px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mobile-icon-bar-button {
|
||||
color: $text-grey;
|
||||
float: right;
|
||||
font-size: large;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#publisher-textarea-wrapper {
|
||||
border-radius: 2px;
|
||||
margin: 12px 0px;
|
||||
|
||||
@@ -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 +1,4 @@
|
||||
.page-registrations.action-new,
|
||||
.page-registrations.action-create {
|
||||
.page-registrations {
|
||||
.ball {
|
||||
background: image-url('branding/ball.png') no-repeat;
|
||||
background-size: contain;
|
||||
@@ -12,19 +11,24 @@
|
||||
height: 633px;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
.v-center {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
|
||||
h2 {
|
||||
h1 {
|
||||
font-size: 35px;
|
||||
margin: 12px;
|
||||
text-align: center;
|
||||
margin: 12px 0;
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
max-width: 400px;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.captcha-img {
|
||||
@@ -34,16 +38,13 @@
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.captcha-input {
|
||||
.form-control.captcha-input {
|
||||
border-bottom: 1px solid $input-border;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
font-size: 16px;
|
||||
height: 40px;
|
||||
line-height: $line-height-base;
|
||||
padding: 10px 10px 10px 130px;
|
||||
width: 100%;
|
||||
padding-left: 130px;
|
||||
}
|
||||
|
||||
.terms > a {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -64,13 +64,12 @@
|
||||
<ul class="nav navbar-nav navbar-left visible-sm-block visible-xs-block">
|
||||
<li class="visible-xs-block"><a href="/stream">{{t "my_stream"}}</a></li>
|
||||
<li class="visible-xs-block"><a href="/activity">{{t "my_activity"}}</a></li>
|
||||
<li><a href="/mobile/toggle">{{t "header.toggle_mobile"}}</a></li>
|
||||
</ul>
|
||||
|
||||
<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>
|
||||
@@ -87,6 +86,7 @@
|
||||
{{else if current_user.moderator}}
|
||||
<li><a href="/report">{{t "header.moderator"}}</a></li>
|
||||
{{/if}}
|
||||
<li><a class="visible-xs-block" href="/mobile/toggle">{{t "header.switch_to_touch_optimized_mode"}}</a></li>
|
||||
<li><a href="/users/sign_out" data-method="delete">{{t "header.log_out"}}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -27,6 +27,7 @@ class ApplicationController < ActionController::Base
|
||||
before_action :gon_set_current_user
|
||||
before_action :gon_set_appconfig
|
||||
before_action :gon_set_preloads
|
||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||
|
||||
inflection_method grammatical_gender: :gender
|
||||
|
||||
@@ -182,4 +183,10 @@ class ApplicationController < ActionController::Base
|
||||
return unless gon.preloads.nil?
|
||||
gon.preloads = {}
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.permit(:sign_in, keys: [:otp_attempt])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -10,6 +10,7 @@ class BlocksController < ApplicationController
|
||||
|
||||
respond_to do |format|
|
||||
format.json { head :no_content }
|
||||
format.any { redirect_back fallback_location: root_path }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -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}"
|
||||
|
||||
27
app/controllers/manifest_controller.rb
Normal file
27
app/controllers/manifest_controller.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ManifestController < ApplicationController
|
||||
def show # rubocop:disable Metrics/MethodLength
|
||||
render json: {
|
||||
short_name: AppConfig.settings.pod_name,
|
||||
name: AppConfig.settings.pod_name,
|
||||
description: "diaspora* is a free, decentralized and privacy-respecting social network",
|
||||
icons: [
|
||||
{
|
||||
src: helpers.image_path("branding/logos/app-icon.png"),
|
||||
type: "image/png",
|
||||
sizes: "192x192"
|
||||
},
|
||||
{
|
||||
src: helpers.image_path("branding/logos/app-icon-512.png"),
|
||||
type: "image/png",
|
||||
sizes: "512x512"
|
||||
}
|
||||
],
|
||||
start_url: "/",
|
||||
background_color: "#000000",
|
||||
display: "standalone",
|
||||
theme_color: "#000000"
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -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 )}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
before_action :check_registrations_open_or_valid_invite!
|
||||
before_action :check_registrations_open_or_valid_invite!, except: :registrations_closed
|
||||
|
||||
layout -> { request.format == :mobile ? "application" : "with_header" }
|
||||
layout -> { request.format == :mobile ? "application" : "with_header_with_footer" }
|
||||
|
||||
def create
|
||||
@user = User.build(user_params)
|
||||
@@ -28,13 +28,17 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
end
|
||||
end
|
||||
|
||||
def registrations_closed
|
||||
render "registrations/registrations_closed"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_registrations_open_or_valid_invite!
|
||||
return true if AppConfig.settings.enable_registrations? || invite.try(:can_be_used?)
|
||||
|
||||
flash[:error] = params[:invite] ? t("registrations.invalid_invite") : t("registrations.closed")
|
||||
redirect_to new_user_session_path
|
||||
flash[:error] = t("registrations.invalid_invite") if params[:invite]
|
||||
redirect_to registrations_closed_path
|
||||
end
|
||||
|
||||
def invite
|
||||
|
||||
@@ -5,10 +5,54 @@
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class SessionsController < Devise::SessionsController
|
||||
after_action :reset_authentication_token, only: [:create]
|
||||
before_action :reset_authentication_token, only: [:destroy]
|
||||
# rubocop:disable Rails/LexicallyScopedActionFilter
|
||||
before_action :authenticate_with_2fa, only: :create
|
||||
after_action :reset_authentication_token, only: :create
|
||||
before_action :reset_authentication_token, only: :destroy
|
||||
# rubocop:enable Rails/LexicallyScopedActionFilter
|
||||
|
||||
def find_user
|
||||
return User.find_for_authentication(username: params[:user][:username]) if params[:user][:username]
|
||||
|
||||
User.find(session[:otp_user_id]) if session[:otp_user_id]
|
||||
end
|
||||
|
||||
def authenticate_with_2fa
|
||||
self.resource = find_user
|
||||
|
||||
return true unless resource&.otp_required_for_login?
|
||||
|
||||
if params[:user][:otp_attempt].present? && session[:otp_user_id]
|
||||
authenticate_with_two_factor_via_otp(resource)
|
||||
else
|
||||
strategy = Warden::Strategies[:database_authenticatable].new(warden.env, :user)
|
||||
prompt_for_two_factor(strategy.user) if strategy.valid? && strategy._run!.successful?
|
||||
end
|
||||
end
|
||||
|
||||
def valid_otp_attempt?(user)
|
||||
user.validate_and_consume_otp!(params[:user][:otp_attempt]) ||
|
||||
user.invalidate_otp_backup_code!(params[:user][:otp_attempt])
|
||||
rescue OpenSSL::Cipher::CipherError => _error
|
||||
false
|
||||
end
|
||||
|
||||
def authenticate_with_two_factor_via_otp(user)
|
||||
if valid_otp_attempt?(user)
|
||||
session.delete(:otp_user_id)
|
||||
sign_in(user)
|
||||
else
|
||||
flash.now[:alert] = "Invalid token"
|
||||
prompt_for_two_factor(user)
|
||||
end
|
||||
end
|
||||
|
||||
def prompt_for_two_factor(user)
|
||||
session[:otp_user_id] = user.id
|
||||
render :two_factor
|
||||
end
|
||||
|
||||
def reset_authentication_token
|
||||
current_user.reset_authentication_token! unless current_user.nil?
|
||||
current_user&.reset_authentication_token!
|
||||
end
|
||||
end
|
||||
|
||||
55
app/controllers/two_factor_authentications_controller.rb
Normal file
55
app/controllers/two_factor_authentications_controller.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TwoFactorAuthenticationsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :verify_otp_required, only: [:create]
|
||||
|
||||
def show
|
||||
@user = current_user
|
||||
end
|
||||
|
||||
def create
|
||||
current_user.otp_secret = User.generate_otp_secret(32)
|
||||
current_user.save!
|
||||
redirect_to confirm_two_factor_authentication_path
|
||||
end
|
||||
|
||||
def confirm_2fa
|
||||
redirect_to two_factor_authentication_path if current_user.otp_required_for_login?
|
||||
end
|
||||
|
||||
def confirm_and_activate_2fa
|
||||
if current_user.validate_and_consume_otp!(params[:user][:code])
|
||||
current_user.otp_required_for_login = true
|
||||
current_user.save!
|
||||
|
||||
flash[:notice] = t("two_factor_auth.flash.success_activation")
|
||||
redirect_to recovery_codes_two_factor_authentication_path
|
||||
else
|
||||
flash[:alert] = t("two_factor_auth.flash.error_token")
|
||||
redirect_to confirm_two_factor_authentication_path
|
||||
end
|
||||
end
|
||||
|
||||
def recovery_codes
|
||||
@recovery_codes = current_user.generate_otp_backup_codes!
|
||||
current_user.save!
|
||||
end
|
||||
|
||||
def destroy
|
||||
if current_user.valid_password?(params[:two_factor_authentication][:password])
|
||||
current_user.otp_required_for_login = false
|
||||
current_user.save!
|
||||
flash[:notice] = t("two_factor_auth.flash.success_deactivation")
|
||||
else
|
||||
flash[:alert] = t("users.destroy.wrong_password")
|
||||
end
|
||||
redirect_to two_factor_authentication_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verify_otp_required
|
||||
redirect_to two_factor_authentication_path if current_user.otp_required_for_login?
|
||||
end
|
||||
end
|
||||
@@ -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,
|
||||
@@ -155,7 +143,14 @@ class UsersController < ApplicationController
|
||||
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]
|
||||
@@ -175,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
|
||||
@@ -204,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
|
||||
@@ -234,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)
|
||||
|
||||
@@ -72,4 +72,9 @@ module ApplicationHelper
|
||||
buf << [nonced_javascript_tag("$.fx.off = true;")] if Rails.env.test?
|
||||
buf.join("\n").html_safe
|
||||
end
|
||||
|
||||
def qrcode_uri
|
||||
label = current_user.username
|
||||
current_user.otp_provisioning_uri(label, issuer: AppConfig.environment.url)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,7 +33,9 @@ class OpenGraphCache < ApplicationRecord
|
||||
end
|
||||
|
||||
def fetch_and_save_opengraph_data!
|
||||
object = OpenGraphReader.fetch!(self.url)
|
||||
uri = URI.parse(url.start_with?("http") ? url : "http://#{url}")
|
||||
uri.normalize!
|
||||
object = OpenGraphReader.fetch!(uri)
|
||||
|
||||
return unless object
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user