Merge pull request #3107 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to ac039d5f1323c46062d004896996f50549bfa38b
This commit is contained in:
commit
94c644983e
16
Gemfile.lock
16
Gemfile.lock
@ -116,7 +116,7 @@ GEM
|
|||||||
base64 (0.3.0)
|
base64 (0.3.0)
|
||||||
bcp47_spec (0.2.1)
|
bcp47_spec (0.2.1)
|
||||||
bcrypt (3.1.20)
|
bcrypt (3.1.20)
|
||||||
benchmark (0.4.0)
|
benchmark (0.4.1)
|
||||||
better_errors (2.10.1)
|
better_errors (2.10.1)
|
||||||
erubi (>= 1.0.0)
|
erubi (>= 1.0.0)
|
||||||
rack (>= 0.9.0)
|
rack (>= 0.9.0)
|
||||||
@ -708,7 +708,7 @@ GEM
|
|||||||
link_header (~> 0.0, >= 0.0.8)
|
link_header (~> 0.0, >= 0.0.8)
|
||||||
rdf-normalize (0.7.0)
|
rdf-normalize (0.7.0)
|
||||||
rdf (~> 3.3)
|
rdf (~> 3.3)
|
||||||
rdoc (6.14.0)
|
rdoc (6.14.1)
|
||||||
erb
|
erb
|
||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
redcarpet (3.6.1)
|
redcarpet (3.6.1)
|
||||||
@ -737,17 +737,17 @@ GEM
|
|||||||
rspec-core (~> 3.13.0)
|
rspec-core (~> 3.13.0)
|
||||||
rspec-expectations (~> 3.13.0)
|
rspec-expectations (~> 3.13.0)
|
||||||
rspec-mocks (~> 3.13.0)
|
rspec-mocks (~> 3.13.0)
|
||||||
rspec-core (3.13.3)
|
rspec-core (3.13.4)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-expectations (3.13.4)
|
rspec-expectations (3.13.5)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-github (3.0.0)
|
rspec-github (3.0.0)
|
||||||
rspec-core (~> 3.0)
|
rspec-core (~> 3.0)
|
||||||
rspec-mocks (3.13.4)
|
rspec-mocks (3.13.5)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-rails (8.0.0)
|
rspec-rails (8.0.1)
|
||||||
actionpack (>= 7.2)
|
actionpack (>= 7.2)
|
||||||
activesupport (>= 7.2)
|
activesupport (>= 7.2)
|
||||||
railties (>= 7.2)
|
railties (>= 7.2)
|
||||||
@ -760,7 +760,7 @@ GEM
|
|||||||
rspec-expectations (~> 3.0)
|
rspec-expectations (~> 3.0)
|
||||||
rspec-mocks (~> 3.0)
|
rspec-mocks (~> 3.0)
|
||||||
sidekiq (>= 5, < 9)
|
sidekiq (>= 5, < 9)
|
||||||
rspec-support (3.13.3)
|
rspec-support (3.13.4)
|
||||||
rubocop (1.76.2)
|
rubocop (1.76.2)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (~> 3.17.0.2)
|
language_server-protocol (~> 3.17.0.2)
|
||||||
@ -940,7 +940,7 @@ GEM
|
|||||||
xorcist (1.1.3)
|
xorcist (1.1.3)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
zeitwerk (2.7.2)
|
zeitwerk (2.7.3)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|||||||
@ -15,8 +15,9 @@ class Api::V1::Instances::TermsOfServicesController < Api::V1::Instances::BaseCo
|
|||||||
if params[:date].present?
|
if params[:date].present?
|
||||||
TermsOfService.published.find_by!(effective_date: params[:date])
|
TermsOfService.published.find_by!(effective_date: params[:date])
|
||||||
else
|
else
|
||||||
TermsOfService.live.first || TermsOfService.published.first! # For the case when none of the published terms have become effective yet
|
TermsOfService.current
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
not_found if @terms_of_service.nil?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -377,7 +377,11 @@ class Status extends ImmutablePureComponent {
|
|||||||
if (newTab) {
|
if (newTab) {
|
||||||
window.open(path, '_blank', 'noopener');
|
window.open(path, '_blank', 'noopener');
|
||||||
} else {
|
} else {
|
||||||
history.push(path);
|
if (history.location.pathname.replace('/deck/', '/') === path) {
|
||||||
|
history.replace(path);
|
||||||
|
} else {
|
||||||
|
history.push(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1244,6 +1244,7 @@ body > [data-popper-placement] {
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
letter-spacing: 0.25px;
|
letter-spacing: 0.25px;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 4;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -1322,6 +1323,7 @@ body > [data-popper-placement] {
|
|||||||
letter-spacing: 0.25px;
|
letter-spacing: 0.25px;
|
||||||
padding-top: 0 !important;
|
padding-top: 0 !important;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 4;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
max-height: 4 * 20px;
|
max-height: 4 * 20px;
|
||||||
@ -2166,6 +2168,7 @@ body > [data-popper-placement] {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 1;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
@ -3189,7 +3192,7 @@ a.account__display-name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
$sidebar-width: 285px;
|
$sidebar-width: 285px;
|
||||||
|
|
||||||
.columns-area__panels__main {
|
.columns-area__panels__main {
|
||||||
@ -3389,7 +3392,7 @@ a.account__display-name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
.columns-area__panels__pane--compositional {
|
.columns-area__panels__pane--compositional {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -3630,19 +3633,19 @@ a.account__display-name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (height <= 930px - 56px) {
|
@media screen and (height <= (930px - 56px)) {
|
||||||
&__portal .trends__item:nth-child(n + 4) {
|
&__portal .trends__item:nth-child(n + 4) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (height <= 930px - (56px * 2)) {
|
@media screen and (height <= (930px - 56px * 2)) {
|
||||||
&__portal .trends__item:nth-child(n + 3) {
|
&__portal .trends__item:nth-child(n + 3) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (height <= 930px - (56px * 3)) {
|
@media screen and (height <= (930px - 56px * 3)) {
|
||||||
&__portal {
|
&__portal {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -4198,6 +4201,7 @@ a.status-card {
|
|||||||
.status-card.expanded .status-card__title {
|
.status-card.expanded .status-card__title {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 2;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
@ -6390,6 +6394,7 @@ a.status-card {
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
color: $dark-text-color;
|
color: $dark-text-color;
|
||||||
|
line-clamp: 4;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
max-height: 4 * 22px;
|
max-height: 4 * 22px;
|
||||||
@ -8021,7 +8026,7 @@ img.modal-warning {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
}
|
}
|
||||||
@ -8429,7 +8434,7 @@ noscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fallback for older browsers with no container queries support
|
// Fallback for older browsers with no container queries support
|
||||||
@media screen and (max-width: 372px + 55px) {
|
@media screen and (max-width: (372px + 55px)) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8898,7 +8903,7 @@ noscript {
|
|||||||
width: 124px;
|
width: 124px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
@media screen and (max-width: 124px + 300px) {
|
@media screen and (max-width: (124px + 300px)) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8908,7 +8913,7 @@ noscript {
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@media screen and (max-width: 124px + 300px) {
|
@media screen and (max-width: (124px + 300px)) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9001,7 +9006,6 @@ noscript {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
vertical-align: bottom;
|
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9037,6 +9041,7 @@ noscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker-dropdown {
|
.emoji-picker-dropdown {
|
||||||
|
display: flex;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9268,7 +9273,7 @@ noscript {
|
|||||||
.layout-single-column .explore__search-header {
|
.layout-single-column .explore__search-header {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9666,7 +9671,7 @@ noscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
&__choices {
|
&__choices {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@ -11216,6 +11221,7 @@ noscript {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 2;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
max-height: 2 * 20px;
|
max-height: 2 * 20px;
|
||||||
|
|||||||
@ -301,7 +301,11 @@ class Status extends ImmutablePureComponent {
|
|||||||
if (newTab) {
|
if (newTab) {
|
||||||
window.open(path, '_blank', 'noopener');
|
window.open(path, '_blank', 'noopener');
|
||||||
} else {
|
} else {
|
||||||
history.push(path);
|
if (history.location.pathname.replace('/deck/', '/') === path) {
|
||||||
|
history.replace(path);
|
||||||
|
} else {
|
||||||
|
history.push(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1185,6 +1185,7 @@ body > [data-popper-placement] {
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
letter-spacing: 0.25px;
|
letter-spacing: 0.25px;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 4;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -1263,6 +1264,7 @@ body > [data-popper-placement] {
|
|||||||
letter-spacing: 0.25px;
|
letter-spacing: 0.25px;
|
||||||
padding-top: 0 !important;
|
padding-top: 0 !important;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 4;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
max-height: 4 * 20px;
|
max-height: 4 * 20px;
|
||||||
@ -2100,6 +2102,7 @@ body > [data-popper-placement] {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 1;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
@ -3124,7 +3127,7 @@ a.account__display-name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
$sidebar-width: 285px;
|
$sidebar-width: 285px;
|
||||||
|
|
||||||
.columns-area__panels__main {
|
.columns-area__panels__main {
|
||||||
@ -3324,7 +3327,7 @@ a.account__display-name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
.columns-area__panels__pane--compositional {
|
.columns-area__panels__pane--compositional {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -3565,19 +3568,19 @@ a.account__display-name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (height <= 930px - 56px) {
|
@media screen and (height <= (930px - 56px)) {
|
||||||
&__portal .trends__item:nth-child(n + 4) {
|
&__portal .trends__item:nth-child(n + 4) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (height <= 930px - (56px * 2)) {
|
@media screen and (height <= (930px - 56px * 2)) {
|
||||||
&__portal .trends__item:nth-child(n + 3) {
|
&__portal .trends__item:nth-child(n + 3) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (height <= 930px - (56px * 3)) {
|
@media screen and (height <= (930px - 56px * 3)) {
|
||||||
&__portal {
|
&__portal {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -4110,6 +4113,7 @@ a.status-card {
|
|||||||
.status-card.expanded .status-card__title {
|
.status-card.expanded .status-card__title {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 2;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
@ -6153,6 +6157,7 @@ a.status-card {
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
color: $dark-text-color;
|
color: $dark-text-color;
|
||||||
|
line-clamp: 4;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
max-height: 4 * 22px;
|
max-height: 4 * 22px;
|
||||||
@ -7717,7 +7722,7 @@ a.status-card {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
}
|
}
|
||||||
@ -8126,7 +8131,7 @@ noscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fallback for older browsers with no container queries support
|
// Fallback for older browsers with no container queries support
|
||||||
@media screen and (max-width: 372px + 55px) {
|
@media screen and (max-width: (372px + 55px)) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8595,7 +8600,7 @@ noscript {
|
|||||||
width: 124px;
|
width: 124px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
@media screen and (max-width: 124px + 300px) {
|
@media screen and (max-width: (124px + 300px)) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8605,7 +8610,7 @@ noscript {
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@media screen and (max-width: 124px + 300px) {
|
@media screen and (max-width: (124px + 300px)) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8698,7 +8703,6 @@ noscript {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
vertical-align: bottom;
|
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8734,6 +8738,7 @@ noscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker-dropdown {
|
.emoji-picker-dropdown {
|
||||||
|
display: flex;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8959,7 +8964,7 @@ noscript {
|
|||||||
.layout-single-column .explore__search-header {
|
.layout-single-column .explore__search-header {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9357,7 +9362,7 @@ noscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: ($no-gap-breakpoint - 1px)) {
|
||||||
&__choices {
|
&__choices {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@ -10902,6 +10907,7 @@ noscript {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
line-clamp: 2;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
max-height: 2 * 20px;
|
max-height: 2 * 20px;
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
class TermsOfService < ApplicationRecord
|
class TermsOfService < ApplicationRecord
|
||||||
scope :published, -> { where.not(published_at: nil).order(Arel.sql('coalesce(effective_date, published_at) DESC')) }
|
scope :published, -> { where.not(published_at: nil).order(Arel.sql('coalesce(effective_date, published_at) DESC')) }
|
||||||
scope :live, -> { published.where('effective_date IS NULL OR effective_date < now()').limit(1) }
|
scope :live, -> { published.where('effective_date IS NULL OR effective_date < now()').limit(1) }
|
||||||
|
scope :upcoming, -> { published.reorder(effective_date: :asc).where('effective_date IS NOT NULL AND effective_date > now()').limit(1) }
|
||||||
scope :draft, -> { where(published_at: nil).order(id: :desc).limit(1) }
|
scope :draft, -> { where(published_at: nil).order(id: :desc).limit(1) }
|
||||||
|
|
||||||
validates :text, presence: true
|
validates :text, presence: true
|
||||||
@ -26,6 +27,10 @@ class TermsOfService < ApplicationRecord
|
|||||||
|
|
||||||
NOTIFICATION_ACTIVITY_CUTOFF = 1.year.freeze
|
NOTIFICATION_ACTIVITY_CUTOFF = 1.year.freeze
|
||||||
|
|
||||||
|
def self.current
|
||||||
|
live.first || upcoming.first # For the case when none of the published terms have become effective yet
|
||||||
|
end
|
||||||
|
|
||||||
def published?
|
def published?
|
||||||
published_at.present?
|
published_at.present?
|
||||||
end
|
end
|
||||||
|
|||||||
@ -21,5 +21,5 @@ class WebauthnCredential < ApplicationRecord
|
|||||||
validates :external_id, uniqueness: true
|
validates :external_id, uniqueness: true
|
||||||
validates :nickname, uniqueness: { scope: :user_id }
|
validates :nickname, uniqueness: { scope: :user_id }
|
||||||
validates :sign_count,
|
validates :sign_count,
|
||||||
numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: SIGN_COUNT_LIMIT - 1 }
|
numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than: SIGN_COUNT_LIMIT }
|
||||||
end
|
end
|
||||||
|
|||||||
@ -25,12 +25,15 @@ class Webhook < ApplicationRecord
|
|||||||
status.updated
|
status.updated
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
|
SECRET_LENGTH_MIN = 12
|
||||||
|
SECRET_SIZE = 20
|
||||||
|
|
||||||
attr_writer :current_account
|
attr_writer :current_account
|
||||||
|
|
||||||
scope :enabled, -> { where(enabled: true) }
|
scope :enabled, -> { where(enabled: true) }
|
||||||
|
|
||||||
validates :url, presence: true, url: true
|
validates :url, presence: true, url: true
|
||||||
validates :secret, presence: true, length: { minimum: 12 }
|
validates :secret, presence: true, length: { minimum: SECRET_LENGTH_MIN }
|
||||||
validates :events, presence: true
|
validates :events, presence: true
|
||||||
|
|
||||||
validate :events_validation_error, if: :invalid_events?
|
validate :events_validation_error, if: :invalid_events?
|
||||||
@ -41,7 +44,7 @@ class Webhook < ApplicationRecord
|
|||||||
before_validation :generate_secret
|
before_validation :generate_secret
|
||||||
|
|
||||||
def rotate_secret!
|
def rotate_secret!
|
||||||
update!(secret: SecureRandom.hex(20))
|
update!(secret: random_secret)
|
||||||
end
|
end
|
||||||
|
|
||||||
def enable!
|
def enable!
|
||||||
@ -93,6 +96,10 @@ class Webhook < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def generate_secret
|
def generate_secret
|
||||||
self.secret = SecureRandom.hex(20) if secret.blank?
|
self.secret = random_secret if secret.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
def random_secret
|
||||||
|
SecureRandom.hex(SECRET_SIZE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -127,7 +127,7 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||||||
trends_as_landing_page: Setting.trends_as_landing_page,
|
trends_as_landing_page: Setting.trends_as_landing_page,
|
||||||
trends_enabled: Setting.trends,
|
trends_enabled: Setting.trends,
|
||||||
version: instance_presenter.version,
|
version: instance_presenter.version,
|
||||||
terms_of_service_enabled: TermsOfService.live.exists?,
|
terms_of_service_enabled: TermsOfService.current.present?,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
|||||||
status: object.status_page_url,
|
status: object.status_page_url,
|
||||||
about: about_url,
|
about: about_url,
|
||||||
privacy_policy: privacy_policy_url,
|
privacy_policy: privacy_policy_url,
|
||||||
terms_of_service: TermsOfService.live.exists? ? terms_of_service_url : nil,
|
terms_of_service: TermsOfService.current.present? ? terms_of_service_url : nil,
|
||||||
},
|
},
|
||||||
|
|
||||||
vapid: {
|
vapid: {
|
||||||
|
|||||||
@ -24,4 +24,55 @@ RSpec.describe TermsOfService do
|
|||||||
expect(subject.pluck(:id)).to match_array(user_before.id)
|
expect(subject.pluck(:id)).to match_array(user_before.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '::current' do
|
||||||
|
context 'when no terms exist' do
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(described_class.current).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when only unpublished terms exist' do
|
||||||
|
before do
|
||||||
|
yesterday = Date.yesterday
|
||||||
|
travel_to yesterday do
|
||||||
|
Fabricate(:terms_of_service, published_at: nil, effective_date: yesterday)
|
||||||
|
end
|
||||||
|
Fabricate(:terms_of_service, published_at: nil, effective_date: Date.tomorrow)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(described_class.current).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when both effective and future terms exist' do
|
||||||
|
let!(:effective_terms) do
|
||||||
|
yesterday = Date.yesterday
|
||||||
|
travel_to yesterday do
|
||||||
|
Fabricate(:terms_of_service, effective_date: yesterday)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
Fabricate(:terms_of_service, effective_date: Date.tomorrow)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the effective terms' do
|
||||||
|
expect(described_class.current).to eq effective_terms
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when only future terms exist' do
|
||||||
|
let!(:upcoming_terms) { Fabricate(:terms_of_service, effective_date: Date.tomorrow) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Fabricate(:terms_of_service, effective_date: 10.days.since)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the terms that are upcoming next' do
|
||||||
|
expect(described_class.current).to eq upcoming_terms
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -14,6 +14,6 @@ RSpec.describe WebauthnCredential do
|
|||||||
it { is_expected.to validate_uniqueness_of(:external_id) }
|
it { is_expected.to validate_uniqueness_of(:external_id) }
|
||||||
it { is_expected.to validate_uniqueness_of(:nickname).scoped_to(:user_id) }
|
it { is_expected.to validate_uniqueness_of(:nickname).scoped_to(:user_id) }
|
||||||
|
|
||||||
it { is_expected.to validate_numericality_of(:sign_count).only_integer.is_greater_than_or_equal_to(0).is_less_than_or_equal_to(described_class::SIGN_COUNT_LIMIT - 1) }
|
it { is_expected.to validate_numericality_of(:sign_count).only_integer.is_greater_than_or_equal_to(0).is_less_than(described_class::SIGN_COUNT_LIMIT) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -8,6 +8,8 @@ RSpec.describe Webhook do
|
|||||||
describe 'Validations' do
|
describe 'Validations' do
|
||||||
subject { Fabricate.build :webhook }
|
subject { Fabricate.build :webhook }
|
||||||
|
|
||||||
|
it { is_expected.to validate_length_of(:secret).is_at_least(described_class::SECRET_LENGTH_MIN) }
|
||||||
|
|
||||||
it { is_expected.to validate_presence_of(:events) }
|
it { is_expected.to validate_presence_of(:events) }
|
||||||
|
|
||||||
it { is_expected.to_not allow_values([], %w(account.invalid)).for(:events) }
|
it { is_expected.to_not allow_values([], %w(account.invalid)).for(:events) }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user