Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cc432bbc4 | ||
|
|
dafae9818d | ||
|
|
9fe1619db9 | ||
|
|
da70aca28e | ||
|
|
6f531d140b | ||
|
|
f66a786029 | ||
|
|
d97903a358 | ||
|
|
93897134ca | ||
|
|
a6b59cd1a3 | ||
|
|
f64af6473f | ||
|
|
ac49c7932d | ||
|
|
61dcb686a8 | ||
|
|
9381a7d9d5 | ||
|
|
a5c6c748e0 | ||
|
|
36b5703796 | ||
|
|
ff6b8a6443 | ||
|
|
6b76a6212d | ||
|
|
33ee347c99 | ||
|
|
0306e3e9be | ||
|
|
357f9298bd | ||
|
|
f7c46fc113 | ||
|
|
74c39fada0 | ||
|
|
f02411da40 | ||
|
|
a568e3ca8e | ||
|
|
3b440bd5af | ||
|
|
39f27b6cf3 | ||
|
|
721234230c | ||
|
|
566ace2d64 | ||
|
|
092f1df9d0 | ||
|
|
844616e950 | ||
|
|
40871caa4b | ||
|
|
cdf8b92fea | ||
|
|
0074cad44f | ||
|
|
4a0a19fe54 | ||
|
|
338bff8b93 | ||
|
|
b88fcd53f7 | ||
|
|
ca7e6a6d2e | ||
|
|
f0cd957c7a | ||
|
|
64fc8d2b07 | ||
|
|
fd385e256d |
1
.babelrc
1
.babelrc
@@ -4,6 +4,7 @@
|
|||||||
[
|
[
|
||||||
"env",
|
"env",
|
||||||
{
|
{
|
||||||
|
"exclude": ["transform-async-to-generator", "transform-regenerator"],
|
||||||
"loose": true,
|
"loose": true,
|
||||||
"modules": false,
|
"modules": false,
|
||||||
"targets": {
|
"targets": {
|
||||||
|
|||||||
@@ -155,8 +155,8 @@ STREAMING_CLUSTER_NUM=1
|
|||||||
# The pam environment variable "email" is provided by:
|
# The pam environment variable "email" is provided by:
|
||||||
# https://github.com/devkral/pam_email_extractor
|
# https://github.com/devkral/pam_email_extractor
|
||||||
# PAM_ENABLED=true
|
# PAM_ENABLED=true
|
||||||
# Fallback Suffix for email address generation (nil by default)
|
# Fallback email domain for email address generation (LOCAL_DOMAIN by default)
|
||||||
# PAM_DEFAULT_SUFFIX=pam
|
# PAM_EMAIL_DOMAIN=example.com
|
||||||
# Name of the pam service (pam "auth" section is evaluated)
|
# Name of the pam service (pam "auth" section is evaluated)
|
||||||
# PAM_DEFAULT_SERVICE=rpam
|
# PAM_DEFAULT_SERVICE=rpam
|
||||||
# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
|
# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
|
||||||
|
|||||||
15
Dockerfile
15
Dockerfile
@@ -1,4 +1,4 @@
|
|||||||
FROM ruby:2.5.0-alpine3.7
|
FROM ruby:2.4.3-alpine3.6
|
||||||
|
|
||||||
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
||||||
description="Your self-hosted, globally interconnected microblogging community"
|
description="Your self-hosted, globally interconnected microblogging community"
|
||||||
@@ -9,6 +9,8 @@ ARG GID=991
|
|||||||
ENV RAILS_SERVE_STATIC_FILES=true \
|
ENV RAILS_SERVE_STATIC_FILES=true \
|
||||||
RAILS_ENV=production NODE_ENV=production
|
RAILS_ENV=production NODE_ENV=production
|
||||||
|
|
||||||
|
ARG YARN_VERSION=1.3.2
|
||||||
|
ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
|
||||||
ARG LIBICONV_VERSION=1.15
|
ARG LIBICONV_VERSION=1.15
|
||||||
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
||||||
|
|
||||||
@@ -30,17 +32,24 @@ RUN apk -U upgrade \
|
|||||||
ca-certificates \
|
ca-certificates \
|
||||||
ffmpeg \
|
ffmpeg \
|
||||||
file \
|
file \
|
||||||
|
git \
|
||||||
icu-libs \
|
icu-libs \
|
||||||
imagemagick \
|
imagemagick \
|
||||||
libidn \
|
libidn \
|
||||||
libpq \
|
libpq \
|
||||||
nodejs \
|
nodejs \
|
||||||
|
nodejs-npm \
|
||||||
protobuf \
|
protobuf \
|
||||||
tini \
|
tini \
|
||||||
tzdata \
|
tzdata \
|
||||||
yarn \
|
|
||||||
&& update-ca-certificates \
|
&& update-ca-certificates \
|
||||||
&& mkdir -p /tmp/src \
|
&& mkdir -p /tmp/src /opt \
|
||||||
|
&& wget -O yarn.tar.gz "https://github.com/yarnpkg/yarn/releases/download/v$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
|
||||||
|
&& echo "$YARN_DOWNLOAD_SHA256 *yarn.tar.gz" | sha256sum -c - \
|
||||||
|
&& tar -xzf yarn.tar.gz -C /tmp/src \
|
||||||
|
&& rm yarn.tar.gz \
|
||||||
|
&& mv /tmp/src/yarn-v$YARN_VERSION /opt/yarn \
|
||||||
|
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
|
||||||
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
||||||
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
||||||
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
||||||
|
|||||||
6
Gemfile
6
Gemfile
@@ -32,7 +32,9 @@ gem 'cld3', '~> 3.2.0'
|
|||||||
gem 'devise', '~> 4.4'
|
gem 'devise', '~> 4.4'
|
||||||
gem 'devise-two-factor', '~> 3.0'
|
gem 'devise-two-factor', '~> 3.0'
|
||||||
|
|
||||||
gem 'devise_pam_authenticatable2', '~> 8.0', install_if: -> { ENV['PAM_ENABLED'] == 'true' }
|
group :pam_authentication, optional: true do
|
||||||
|
gem 'devise_pam_authenticatable2', '~> 9.0'
|
||||||
|
end
|
||||||
gem 'net-ldap', '~> 0.10'
|
gem 'net-ldap', '~> 0.10'
|
||||||
gem 'omniauth-cas', '~> 1.1'
|
gem 'omniauth-cas', '~> 1.1'
|
||||||
gem 'omniauth-saml', '~> 1.10'
|
gem 'omniauth-saml', '~> 1.10'
|
||||||
@@ -69,7 +71,7 @@ gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
|||||||
gem 'rqrcode', '~> 0.10'
|
gem 'rqrcode', '~> 0.10'
|
||||||
gem 'ruby-oembed', '~> 0.12', require: 'oembed'
|
gem 'ruby-oembed', '~> 0.12', require: 'oembed'
|
||||||
gem 'ruby-progressbar', '~> 1.4'
|
gem 'ruby-progressbar', '~> 1.4'
|
||||||
gem 'sanitize', '~> 4.4'
|
gem 'sanitize', '~> 4.6.4'
|
||||||
gem 'sidekiq', '~> 5.0'
|
gem 'sidekiq', '~> 5.0'
|
||||||
gem 'sidekiq-scheduler', '~> 2.1'
|
gem 'sidekiq-scheduler', '~> 2.1'
|
||||||
gem 'sidekiq-unique-jobs', '~> 5.0'
|
gem 'sidekiq-unique-jobs', '~> 5.0'
|
||||||
|
|||||||
16
Gemfile.lock
16
Gemfile.lock
@@ -141,7 +141,7 @@ GEM
|
|||||||
devise (~> 4.0)
|
devise (~> 4.0)
|
||||||
railties (< 5.2)
|
railties (< 5.2)
|
||||||
rotp (~> 2.0)
|
rotp (~> 2.0)
|
||||||
devise_pam_authenticatable2 (8.0.1)
|
devise_pam_authenticatable2 (9.0.0)
|
||||||
devise (>= 4.0.0)
|
devise (>= 4.0.0)
|
||||||
rpam2 (~> 3.0)
|
rpam2 (~> 3.0)
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.3)
|
||||||
@@ -288,7 +288,7 @@ GEM
|
|||||||
activesupport (>= 4, < 5.2)
|
activesupport (>= 4, < 5.2)
|
||||||
railties (>= 4, < 5.2)
|
railties (>= 4, < 5.2)
|
||||||
request_store (~> 1.0)
|
request_store (~> 1.0)
|
||||||
loofah (2.1.1)
|
loofah (2.2.1)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.7.0)
|
mail (2.7.0)
|
||||||
@@ -316,9 +316,9 @@ GEM
|
|||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (4.2.0)
|
net-ssh (4.2.0)
|
||||||
nio4r (2.1.0)
|
nio4r (2.1.0)
|
||||||
nokogiri (1.8.1)
|
nokogiri (1.8.2)
|
||||||
mini_portile2 (~> 2.3.0)
|
mini_portile2 (~> 2.3.0)
|
||||||
nokogumbo (1.4.13)
|
nokogumbo (1.5.0)
|
||||||
nokogiri
|
nokogiri
|
||||||
nsa (0.2.4)
|
nsa (0.2.4)
|
||||||
activesupport (>= 4.2, < 6)
|
activesupport (>= 4.2, < 6)
|
||||||
@@ -496,10 +496,10 @@ GEM
|
|||||||
rufus-scheduler (3.4.2)
|
rufus-scheduler (3.4.2)
|
||||||
et-orbi (~> 1.0)
|
et-orbi (~> 1.0)
|
||||||
safe_yaml (1.0.4)
|
safe_yaml (1.0.4)
|
||||||
sanitize (4.5.0)
|
sanitize (4.6.4)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.4.4)
|
nokogiri (>= 1.4.4)
|
||||||
nokogumbo (~> 1.4.1)
|
nokogumbo (~> 1.4)
|
||||||
sass (3.5.3)
|
sass (3.5.3)
|
||||||
sass-listen (~> 4.0.0)
|
sass-listen (~> 4.0.0)
|
||||||
sass-listen (4.0.0)
|
sass-listen (4.0.0)
|
||||||
@@ -631,7 +631,7 @@ DEPENDENCIES
|
|||||||
climate_control (~> 0.2)
|
climate_control (~> 0.2)
|
||||||
devise (~> 4.4)
|
devise (~> 4.4)
|
||||||
devise-two-factor (~> 3.0)
|
devise-two-factor (~> 3.0)
|
||||||
devise_pam_authenticatable2 (~> 8.0)
|
devise_pam_authenticatable2 (~> 9.0)
|
||||||
doorkeeper (~> 4.2)
|
doorkeeper (~> 4.2)
|
||||||
dotenv-rails (~> 2.2)
|
dotenv-rails (~> 2.2)
|
||||||
fabrication (~> 2.18)
|
fabrication (~> 2.18)
|
||||||
@@ -699,7 +699,7 @@ DEPENDENCIES
|
|||||||
rubocop
|
rubocop
|
||||||
ruby-oembed (~> 0.12)
|
ruby-oembed (~> 0.12)
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
sanitize (~> 4.4)
|
sanitize (~> 4.6.4)
|
||||||
scss_lint (~> 0.55)
|
scss_lint (~> 0.55)
|
||||||
sidekiq (~> 5.0)
|
sidekiq (~> 5.0)
|
||||||
sidekiq-bulk (~> 0.1.1)
|
sidekiq-bulk (~> 0.1.1)
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ module Localized
|
|||||||
end
|
end
|
||||||
|
|
||||||
def default_locale
|
def default_locale
|
||||||
request_locale || I18n.default_locale
|
if ENV['DEFAULT_LOCALE'].present?
|
||||||
|
I18n.default_locale
|
||||||
|
else
|
||||||
|
request_locale || I18n.default_locale
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def request_locale
|
def request_locale
|
||||||
|
|||||||
@@ -29,6 +29,35 @@ module StreamEntriesHelper
|
|||||||
[prepend_str, account.note].join(' · ')
|
[prepend_str, account.note].join(' · ')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def media_summary(status)
|
||||||
|
attachments = { image: 0, video: 0 }
|
||||||
|
|
||||||
|
status.media_attachments.each do |media|
|
||||||
|
if media.video?
|
||||||
|
attachments[:video] += 1
|
||||||
|
else
|
||||||
|
attachments[:image] += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
text = attachments.to_a.reject { |_, value| value.zero? }.map { |key, value| t("statuses.attached.#{key}", count: value) }.join(' · ')
|
||||||
|
|
||||||
|
return if text.blank?
|
||||||
|
|
||||||
|
t('statuses.attached.description', attached: text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def status_text_summary(status)
|
||||||
|
return if status.spoiler_text.blank?
|
||||||
|
t('statuses.content_warning', warning: status.spoiler_text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def status_description(status)
|
||||||
|
components = [[media_summary(status), status_text_summary(status)].reject(&:blank?).join(' · ')]
|
||||||
|
components << status.text if status.spoiler_text.blank?
|
||||||
|
components.reject(&:blank?).join("\n\n")
|
||||||
|
end
|
||||||
|
|
||||||
def stream_link_target
|
def stream_link_target
|
||||||
embedded_view? ? '_blank' : nil
|
embedded_view? ? '_blank' : nil
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import api from '../api';
|
import api from '../api';
|
||||||
|
import { CancelToken } from 'axios';
|
||||||
import { throttle } from 'lodash';
|
import { throttle } from 'lodash';
|
||||||
import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light';
|
import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light';
|
||||||
import { tagHistory } from '../settings';
|
import { tagHistory } from '../settings';
|
||||||
@@ -11,6 +12,8 @@ import {
|
|||||||
refreshPublicTimeline,
|
refreshPublicTimeline,
|
||||||
} from './timelines';
|
} from './timelines';
|
||||||
|
|
||||||
|
let cancelFetchComposeSuggestionsAccounts;
|
||||||
|
|
||||||
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
|
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
|
||||||
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
|
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
|
||||||
export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
|
export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
|
||||||
@@ -257,13 +260,22 @@ export function undoUploadCompose(media_id) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function clearComposeSuggestions() {
|
export function clearComposeSuggestions() {
|
||||||
|
if (cancelFetchComposeSuggestionsAccounts) {
|
||||||
|
cancelFetchComposeSuggestionsAccounts();
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUGGESTIONS_CLEAR,
|
type: COMPOSE_SUGGESTIONS_CLEAR,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => {
|
const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => {
|
||||||
|
if (cancelFetchComposeSuggestionsAccounts) {
|
||||||
|
cancelFetchComposeSuggestionsAccounts();
|
||||||
|
}
|
||||||
api(getState).get('/api/v1/accounts/search', {
|
api(getState).get('/api/v1/accounts/search', {
|
||||||
|
cancelToken: new CancelToken(cancel => {
|
||||||
|
cancelFetchComposeSuggestionsAccounts = cancel;
|
||||||
|
}),
|
||||||
params: {
|
params: {
|
||||||
q: token.slice(1),
|
q: token.slice(1),
|
||||||
resolve: false,
|
resolve: false,
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default class Compose extends React.PureComponent {
|
|||||||
<ComposeFormContainer />
|
<ComposeFormContainer />
|
||||||
{multiColumn && (
|
{multiColumn && (
|
||||||
<div className='drawer__inner__mastodon'>
|
<div className='drawer__inner__mastodon'>
|
||||||
<img alt='' src={elephantUIPlane} />
|
<img alt='' draggable='false' src={elephantUIPlane} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ const componentMap = {
|
|||||||
'LIST': ListTimeline,
|
'LIST': ListTimeline,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shouldHideFAB = path => path.match(/^\/statuses\//);
|
||||||
|
|
||||||
@component => injectIntl(component, { withRef: true })
|
@component => injectIntl(component, { withRef: true })
|
||||||
export default class ColumnsArea extends ImmutablePureComponent {
|
export default class ColumnsArea extends ImmutablePureComponent {
|
||||||
|
|
||||||
@@ -153,7 +155,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||||||
this.pendingIndex = null;
|
this.pendingIndex = null;
|
||||||
|
|
||||||
if (singleColumn) {
|
if (singleColumn) {
|
||||||
const floatingActionButton = this.context.router.history.location.pathname === '/statuses/new' ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button'><i className='fa fa-pencil' /></Link>;
|
const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button'><i className='fa fa-pencil' /></Link>;
|
||||||
|
|
||||||
return columnIndex !== -1 ? [
|
return columnIndex !== -1 ? [
|
||||||
<ReactSwipeableViews key='content' index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }}>
|
<ReactSwipeableViews key='content' index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }}>
|
||||||
|
|||||||
@@ -60,10 +60,10 @@
|
|||||||
"compose_form.placeholder": "فيمَ تفكّر؟",
|
"compose_form.placeholder": "فيمَ تفكّر؟",
|
||||||
"compose_form.publish": "بوّق",
|
"compose_form.publish": "بوّق",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.sensitive.marked": "Media is marked as sensitive",
|
"compose_form.sensitive.marked": "لقد تم تحديد هذه الصورة كحساسة",
|
||||||
"compose_form.sensitive.unmarked": "Media is not marked as sensitive",
|
"compose_form.sensitive.unmarked": "Media is not marked as sensitive",
|
||||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
"compose_form.spoiler.marked": "إنّ النص مخفي وراء تحذير",
|
||||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
"compose_form.spoiler.unmarked": "النص غير مخفي",
|
||||||
"compose_form.spoiler_placeholder": "تنبيه عن المحتوى",
|
"compose_form.spoiler_placeholder": "تنبيه عن المحتوى",
|
||||||
"confirmation_modal.cancel": "إلغاء",
|
"confirmation_modal.cancel": "إلغاء",
|
||||||
"confirmations.block.confirm": "حجب",
|
"confirmations.block.confirm": "حجب",
|
||||||
@@ -254,9 +254,9 @@
|
|||||||
"status.sensitive_warning": "محتوى حساس",
|
"status.sensitive_warning": "محتوى حساس",
|
||||||
"status.share": "مشاركة",
|
"status.share": "مشاركة",
|
||||||
"status.show_less": "إعرض أقلّ",
|
"status.show_less": "إعرض أقلّ",
|
||||||
"status.show_less_all": "Show less for all",
|
"status.show_less_all": "طي الكل",
|
||||||
"status.show_more": "أظهر المزيد",
|
"status.show_more": "أظهر المزيد",
|
||||||
"status.show_more_all": "Show more for all",
|
"status.show_more_all": "توسيع الكل",
|
||||||
"status.unmute_conversation": "فك الكتم عن المحادثة",
|
"status.unmute_conversation": "فك الكتم عن المحادثة",
|
||||||
"status.unpin": "فك التدبيس من الملف الشخصي",
|
"status.unpin": "فك التدبيس من الملف الشخصي",
|
||||||
"tabs_bar.federated_timeline": "الموحَّد",
|
"tabs_bar.federated_timeline": "الموحَّد",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}",
|
"account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}",
|
||||||
"account.blocked": "Estetty",
|
"account.blocked": "Estetty",
|
||||||
"account.disclaimer_full": "Alla olevat käyttäjän profiilitiedot saattavat olla epätäydellisiä.",
|
"account.disclaimer_full": "Alla olevat käyttäjän profiilitiedot saattavat olla epätäydellisiä.",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Verkko-osoite piilotettu",
|
||||||
"account.edit_profile": "Muokkaa",
|
"account.edit_profile": "Muokkaa",
|
||||||
"account.follow": "Seuraa",
|
"account.follow": "Seuraa",
|
||||||
"account.followers": "Seuraajia",
|
"account.followers": "Seuraajia",
|
||||||
@@ -60,10 +60,10 @@
|
|||||||
"compose_form.placeholder": "Mitä sinulla on mielessä?",
|
"compose_form.placeholder": "Mitä sinulla on mielessä?",
|
||||||
"compose_form.publish": "Toot",
|
"compose_form.publish": "Toot",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.sensitive.marked": "Media is marked as sensitive",
|
"compose_form.sensitive.marked": "Media on merkitty arkaluontoiseksi",
|
||||||
"compose_form.sensitive.unmarked": "Media is not marked as sensitive",
|
"compose_form.sensitive.unmarked": "Mediaa ei ole merkitty arkaluontoiseksi",
|
||||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
"compose_form.spoiler.marked": "Teksti on piilotettu varoituksen taakse",
|
||||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
"compose_form.spoiler.unmarked": "Teksti ei ole piilotettu",
|
||||||
"compose_form.spoiler_placeholder": "Content warning",
|
"compose_form.spoiler_placeholder": "Content warning",
|
||||||
"confirmation_modal.cancel": "Peruuta",
|
"confirmation_modal.cancel": "Peruuta",
|
||||||
"confirmations.block.confirm": "Estä",
|
"confirmations.block.confirm": "Estä",
|
||||||
@@ -182,13 +182,13 @@
|
|||||||
"onboarding.page_four.notifications": "Ilmoitukset-sarake näyttää sinulle, kun joku on viestii kanssasi.",
|
"onboarding.page_four.notifications": "Ilmoitukset-sarake näyttää sinulle, kun joku on viestii kanssasi.",
|
||||||
"onboarding.page_one.federation": "Mastodon on yhteisöpalvelu, joka toimii monen itsenäisen palvelimen muodostamassa verkossa. Me kutsumme näitä palvelimia instansseiksi.",
|
"onboarding.page_one.federation": "Mastodon on yhteisöpalvelu, joka toimii monen itsenäisen palvelimen muodostamassa verkossa. Me kutsumme näitä palvelimia instansseiksi.",
|
||||||
"onboarding.page_one.full_handle": "Koko käyttäjänimesi",
|
"onboarding.page_one.full_handle": "Koko käyttäjänimesi",
|
||||||
"onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
|
"onboarding.page_one.handle_hint": "Tämä on se, mitä voisit ehdottaa ystäviäsi etsimään.",
|
||||||
"onboarding.page_one.welcome": "Tervetuloa Mastodoniin!",
|
"onboarding.page_one.welcome": "Tervetuloa Mastodoniin!",
|
||||||
"onboarding.page_six.admin": "Instanssisi ylläpitäjä on {admin}.",
|
"onboarding.page_six.admin": "Instanssisi ylläpitäjä on {admin}.",
|
||||||
"onboarding.page_six.almost_done": "Melkein valmista...",
|
"onboarding.page_six.almost_done": "Melkein valmista...",
|
||||||
"onboarding.page_six.appetoot": "Bon Appetööt!",
|
"onboarding.page_six.appetoot": "Bon Appetööt!",
|
||||||
"onboarding.page_six.apps_available": "{apps} on saatavilla iOS:lle, Androidille ja muille alustoille.",
|
"onboarding.page_six.apps_available": "{apps} on saatavilla iOS:lle, Androidille ja muille alustoille.",
|
||||||
"onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
|
"onboarding.page_six.github": "Mastodon on ilmainen, vapaan lähdekoodin ohjelma. Voit raportoida bugeja, pyytää ominaisuuksia tai osallistua kehittämiseen GitHub-palvelussa: {github}.",
|
||||||
"onboarding.page_six.guidelines": "yhteisön säännöt",
|
"onboarding.page_six.guidelines": "yhteisön säännöt",
|
||||||
"onboarding.page_six.read_guidelines": "Ole hyvä ja lue {domain}:n {guidelines}!",
|
"onboarding.page_six.read_guidelines": "Ole hyvä ja lue {domain}:n {guidelines}!",
|
||||||
"onboarding.page_six.various_app": "mobiilisovellukset",
|
"onboarding.page_six.various_app": "mobiilisovellukset",
|
||||||
@@ -254,12 +254,12 @@
|
|||||||
"status.sensitive_warning": "Arkaluontoista sisältöä",
|
"status.sensitive_warning": "Arkaluontoista sisältöä",
|
||||||
"status.share": "Jaa",
|
"status.share": "Jaa",
|
||||||
"status.show_less": "Näytä vähemmän",
|
"status.show_less": "Näytä vähemmän",
|
||||||
"status.show_less_all": "Show less for all",
|
"status.show_less_all": "Näytä vähemmän kaikista",
|
||||||
"status.show_more": "Näytä lisää",
|
"status.show_more": "Näytä lisää",
|
||||||
"status.show_more_all": "Show more for all",
|
"status.show_more_all": "Näytä enemmän kaikista",
|
||||||
"status.unmute_conversation": "Poista mykistys keskustelulta",
|
"status.unmute_conversation": "Poista mykistys keskustelulta",
|
||||||
"status.unpin": "Irrota profiilista",
|
"status.unpin": "Irrota profiilista",
|
||||||
"tabs_bar.federated_timeline": "Federated",
|
"tabs_bar.federated_timeline": "Yleinen",
|
||||||
"tabs_bar.home": "Koti",
|
"tabs_bar.home": "Koti",
|
||||||
"tabs_bar.local_timeline": "Paikallinen",
|
"tabs_bar.local_timeline": "Paikallinen",
|
||||||
"tabs_bar.notifications": "Ilmoitukset",
|
"tabs_bar.notifications": "Ilmoitukset",
|
||||||
|
|||||||
@@ -60,10 +60,10 @@
|
|||||||
"compose_form.placeholder": "Co Ci chodzi po głowie?",
|
"compose_form.placeholder": "Co Ci chodzi po głowie?",
|
||||||
"compose_form.publish": "Wyślij",
|
"compose_form.publish": "Wyślij",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.sensitive.marked": "Media is marked as sensitive",
|
"compose_form.sensitive.marked": "Zawartość multimedia jest oznaczona jako wrażliwa",
|
||||||
"compose_form.sensitive.unmarked": "Media is not marked as sensitive",
|
"compose_form.sensitive.unmarked": "Zawartość multimedialna nie jest oznaczona jako wrażliwa",
|
||||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
"compose_form.spoiler.marked": "Tekst jest ukryty za ostrzeżeniem",
|
||||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
"compose_form.spoiler.unmarked": "Tekst nie jest ukryty",
|
||||||
"compose_form.spoiler_placeholder": "Wprowadź swoje ostrzeżenie o zawartości",
|
"compose_form.spoiler_placeholder": "Wprowadź swoje ostrzeżenie o zawartości",
|
||||||
"confirmation_modal.cancel": "Anuluj",
|
"confirmation_modal.cancel": "Anuluj",
|
||||||
"confirmations.block.confirm": "Zablokuj",
|
"confirmations.block.confirm": "Zablokuj",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"account.muted": "Utíšený/á",
|
"account.muted": "Utíšený/á",
|
||||||
"account.posts": "Hlášky",
|
"account.posts": "Hlášky",
|
||||||
"account.posts_with_replies": "Príspevky s odpoveďami",
|
"account.posts_with_replies": "Príspevky s odpoveďami",
|
||||||
"account.report": "Nahlásiť @{name}",
|
"account.report": "Nahlás @{name}",
|
||||||
"account.requested": "Čaká na schválenie. Kliknite pre zrušenie žiadosti",
|
"account.requested": "Čaká na schválenie. Kliknite pre zrušenie žiadosti",
|
||||||
"account.share": "Zdieľať @{name} profil",
|
"account.share": "Zdieľať @{name} profil",
|
||||||
"account.show_reblogs": "Zobraziť povýšenia od @{name}",
|
"account.show_reblogs": "Zobraziť povýšenia od @{name}",
|
||||||
@@ -35,13 +35,13 @@
|
|||||||
"bundle_modal_error.close": "Zatvoriť",
|
"bundle_modal_error.close": "Zatvoriť",
|
||||||
"bundle_modal_error.message": "Nastala chyba pri načítaní tohto komponentu.",
|
"bundle_modal_error.message": "Nastala chyba pri načítaní tohto komponentu.",
|
||||||
"bundle_modal_error.retry": "Skúsiť znova",
|
"bundle_modal_error.retry": "Skúsiť znova",
|
||||||
"column.blocks": "Blokovaní používatelia",
|
"column.blocks": "Blokovaní užívatelia",
|
||||||
"column.community": "Lokálna časová os",
|
"column.community": "Lokálna časová os",
|
||||||
"column.favourites": "Obľúbené",
|
"column.favourites": "Obľúbené",
|
||||||
"column.follow_requests": "Žiadosti o sledovaní",
|
"column.follow_requests": "Žiadosti o sledovaní",
|
||||||
"column.home": "Domov",
|
"column.home": "Domov",
|
||||||
"column.lists": "Zoznamy",
|
"column.lists": "Zoznamy",
|
||||||
"column.mutes": "Ignorovaní používatelia",
|
"column.mutes": "Ignorovaní užívatelia",
|
||||||
"column.notifications": "Notifikácie",
|
"column.notifications": "Notifikácie",
|
||||||
"column.pins": "Pripnuté toots",
|
"column.pins": "Pripnuté toots",
|
||||||
"column.public": "Federovaná časová os",
|
"column.public": "Federovaná časová os",
|
||||||
@@ -50,20 +50,20 @@
|
|||||||
"column_header.moveLeft_settings": "Presunúť stĺpec doľava",
|
"column_header.moveLeft_settings": "Presunúť stĺpec doľava",
|
||||||
"column_header.moveRight_settings": "Presunúť stĺpec doprava",
|
"column_header.moveRight_settings": "Presunúť stĺpec doprava",
|
||||||
"column_header.pin": "Pripnúť",
|
"column_header.pin": "Pripnúť",
|
||||||
"column_header.show_settings": "Ukázať nastavenia",
|
"column_header.show_settings": "Ukáž nastavenia",
|
||||||
"column_header.unpin": "Odopnúť",
|
"column_header.unpin": "Odopnúť",
|
||||||
"column_subheading.navigation": "Navigácia",
|
"column_subheading.navigation": "Navigácia",
|
||||||
"column_subheading.settings": "Nastavenia",
|
"column_subheading.settings": "Nastavenia",
|
||||||
"compose_form.hashtag_warning": "Tento toot nebude zobrazený pod žiadným haštagom lebo nieje listovaný. Iba verejné toots môžu byť nájdené podľa haštagu.",
|
"compose_form.hashtag_warning": "Tento toot nebude zobrazený pod žiadným haštagom lebo nieje listovaný. Iba verejné tooty môžu byť nájdené podľa haštagu.",
|
||||||
"compose_form.lock_disclaimer": "Váš účet nie je zamknutý. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
|
"compose_form.lock_disclaimer": "Váš účet nie je zamknutý. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
|
||||||
"compose_form.lock_disclaimer.lock": "zamknutý",
|
"compose_form.lock_disclaimer.lock": "zamknutý",
|
||||||
"compose_form.placeholder": "Na čo myslíš?",
|
"compose_form.placeholder": "Na čo myslíš?",
|
||||||
"compose_form.publish": "Toot",
|
"compose_form.publish": "Toot",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.sensitive.marked": "Media is marked as sensitive",
|
"compose_form.sensitive.marked": "Médiálny obsah je označený ako chúlostivý",
|
||||||
"compose_form.sensitive.unmarked": "Media is not marked as sensitive",
|
"compose_form.sensitive.unmarked": "Médiálny obsah nieje označený ako chúlostivý",
|
||||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
"compose_form.spoiler.marked": "Text je ukrytý za varovaním",
|
||||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
"compose_form.spoiler.unmarked": "Text nieje ukrytý",
|
||||||
"compose_form.spoiler_placeholder": "Sem napíšte vaše varovanie",
|
"compose_form.spoiler_placeholder": "Sem napíšte vaše varovanie",
|
||||||
"confirmation_modal.cancel": "Zrušiť",
|
"confirmation_modal.cancel": "Zrušiť",
|
||||||
"confirmations.block.confirm": "Blokovať",
|
"confirmations.block.confirm": "Blokovať",
|
||||||
@@ -101,14 +101,14 @@
|
|||||||
"empty_column.list": "Tento zoznam je ešte prázdny. Keď ale členovia tohoto zoznamu napíšu nové správy, tak tie sa objavia priamo tu.",
|
"empty_column.list": "Tento zoznam je ešte prázdny. Keď ale členovia tohoto zoznamu napíšu nové správy, tak tie sa objavia priamo tu.",
|
||||||
"empty_column.notifications": "Nemáte ešte žiadne notifikácie. Napíšte niekomu, následujte niekoho a komunikujte s ostatnými aby diskusia mohla začať.",
|
"empty_column.notifications": "Nemáte ešte žiadne notifikácie. Napíšte niekomu, následujte niekoho a komunikujte s ostatnými aby diskusia mohla začať.",
|
||||||
"empty_column.public": "Ešte tu nič nie je. Napíšte niečo verejne alebo začnite sledovať používateľov z iných Mastodon serverov aby tu niečo pribudlo",
|
"empty_column.public": "Ešte tu nič nie je. Napíšte niečo verejne alebo začnite sledovať používateľov z iných Mastodon serverov aby tu niečo pribudlo",
|
||||||
"follow_request.authorize": "Povoliť prístup",
|
"follow_request.authorize": "Povoľ prístup",
|
||||||
"follow_request.reject": "Odmietnúť",
|
"follow_request.reject": "Odmietni",
|
||||||
"getting_started.appsshort": "Aplikácie",
|
"getting_started.appsshort": "Aplikácie",
|
||||||
"getting_started.faq": "FAQ",
|
"getting_started.faq": "Časté otázky",
|
||||||
"getting_started.heading": "Začíname",
|
"getting_started.heading": "Začni tu",
|
||||||
"getting_started.open_source_notice": "Mastodon má otvorený kód. Nahlásiť chyby, alebo prispievať vlastným kódom môžete na GitHube v {github}.",
|
"getting_started.open_source_notice": "Mastodon má otvorený kód. Nahlásiť chyby, alebo prispievať vlastným kódom môžete na GitHube v {github}.",
|
||||||
"getting_started.userguide": "Používateľská príručka",
|
"getting_started.userguide": "Používateľská príručka",
|
||||||
"home.column_settings.advanced": "Rozšírené",
|
"home.column_settings.advanced": "Pokročilé",
|
||||||
"home.column_settings.basic": "Základné",
|
"home.column_settings.basic": "Základné",
|
||||||
"home.column_settings.filter_regex": "Filtrovať použitím regulárnych výrazov",
|
"home.column_settings.filter_regex": "Filtrovať použitím regulárnych výrazov",
|
||||||
"home.column_settings.show_reblogs": "Zobraziť povýšené",
|
"home.column_settings.show_reblogs": "Zobraziť povýšené",
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
"missing_indicator.label": "Nenájdené",
|
"missing_indicator.label": "Nenájdené",
|
||||||
"missing_indicator.sublabel": "Tento zdroj sa nepodarilo nájsť",
|
"missing_indicator.sublabel": "Tento zdroj sa nepodarilo nájsť",
|
||||||
"mute_modal.hide_notifications": "Skryť notifikácie od tohoto užívateľa?",
|
"mute_modal.hide_notifications": "Skryť notifikácie od tohoto užívateľa?",
|
||||||
"navigation_bar.blocks": "Blokovaní používatelia",
|
"navigation_bar.blocks": "Blokovaní užívatelia",
|
||||||
"navigation_bar.community_timeline": "Lokálna časová os",
|
"navigation_bar.community_timeline": "Lokálna časová os",
|
||||||
"navigation_bar.edit_profile": "Upraviť profil",
|
"navigation_bar.edit_profile": "Upraviť profil",
|
||||||
"navigation_bar.favourites": "Obľúbené",
|
"navigation_bar.favourites": "Obľúbené",
|
||||||
@@ -156,9 +156,9 @@
|
|||||||
"navigation_bar.keyboard_shortcuts": "Klávesové skratky",
|
"navigation_bar.keyboard_shortcuts": "Klávesové skratky",
|
||||||
"navigation_bar.lists": "Zoznamy",
|
"navigation_bar.lists": "Zoznamy",
|
||||||
"navigation_bar.logout": "Odhlásiť",
|
"navigation_bar.logout": "Odhlásiť",
|
||||||
"navigation_bar.mutes": "Ignorovaní používatelia",
|
"navigation_bar.mutes": "Ignorovaní užívatelia",
|
||||||
"navigation_bar.pins": "Pripnuté toots",
|
"navigation_bar.pins": "Pripnuté toots",
|
||||||
"navigation_bar.preferences": "Možnosti",
|
"navigation_bar.preferences": "Voľby",
|
||||||
"navigation_bar.public_timeline": "Federovaná časová os",
|
"navigation_bar.public_timeline": "Federovaná časová os",
|
||||||
"notification.favourite": "{name} sa páči tvoj status",
|
"notification.favourite": "{name} sa páči tvoj status",
|
||||||
"notification.follow": "{name} ťa začal/a následovať",
|
"notification.follow": "{name} ťa začal/a následovať",
|
||||||
@@ -254,9 +254,9 @@
|
|||||||
"status.sensitive_warning": "Chúlostivý obsah",
|
"status.sensitive_warning": "Chúlostivý obsah",
|
||||||
"status.share": "Zdieľať",
|
"status.share": "Zdieľať",
|
||||||
"status.show_less": "Zobraz menej",
|
"status.show_less": "Zobraz menej",
|
||||||
"status.show_less_all": "Show less for all",
|
"status.show_less_all": "Všetkým ukáž menej",
|
||||||
"status.show_more": "Zobraz viac",
|
"status.show_more": "Zobraz viac",
|
||||||
"status.show_more_all": "Show more for all",
|
"status.show_more_all": "Všetkým ukáž viac",
|
||||||
"status.unmute_conversation": "Prestať ignorovať konverzáciu",
|
"status.unmute_conversation": "Prestať ignorovať konverzáciu",
|
||||||
"status.unpin": "Odopnúť z profilu",
|
"status.unpin": "Odopnúť z profilu",
|
||||||
"tabs_bar.federated_timeline": "Federovaná",
|
"tabs_bar.federated_timeline": "Federovaná",
|
||||||
|
|||||||
@@ -60,10 +60,10 @@
|
|||||||
"compose_form.placeholder": "Vad funderar du på?",
|
"compose_form.placeholder": "Vad funderar du på?",
|
||||||
"compose_form.publish": "Toot",
|
"compose_form.publish": "Toot",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.sensitive.marked": "Media is marked as sensitive",
|
"compose_form.sensitive.marked": "Media har markerats som känsligt",
|
||||||
"compose_form.sensitive.unmarked": "Media is not marked as sensitive",
|
"compose_form.sensitive.unmarked": "Media har inte markerats som känsligt",
|
||||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
"compose_form.spoiler.marked": "Texten har dolts bakom en varning",
|
||||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
"compose_form.spoiler.unmarked": "Texten är inte dold",
|
||||||
"compose_form.spoiler_placeholder": "Skriv din varning här",
|
"compose_form.spoiler_placeholder": "Skriv din varning här",
|
||||||
"confirmation_modal.cancel": "Ångra",
|
"confirmation_modal.cancel": "Ångra",
|
||||||
"confirmations.block.confirm": "Blockera",
|
"confirmations.block.confirm": "Blockera",
|
||||||
@@ -254,9 +254,9 @@
|
|||||||
"status.sensitive_warning": "Känsligt innehåll",
|
"status.sensitive_warning": "Känsligt innehåll",
|
||||||
"status.share": "Dela",
|
"status.share": "Dela",
|
||||||
"status.show_less": "Visa mindre",
|
"status.show_less": "Visa mindre",
|
||||||
"status.show_less_all": "Show less for all",
|
"status.show_less_all": "Visa mindre för alla",
|
||||||
"status.show_more": "Visa mer",
|
"status.show_more": "Visa mer",
|
||||||
"status.show_more_all": "Show more for all",
|
"status.show_more_all": "Visa mer för alla",
|
||||||
"status.unmute_conversation": "Öppna konversation",
|
"status.unmute_conversation": "Öppna konversation",
|
||||||
"status.unpin": "Ångra fäst i profil",
|
"status.unpin": "Ångra fäst i profil",
|
||||||
"tabs_bar.federated_timeline": "Förenad",
|
"tabs_bar.federated_timeline": "Förenad",
|
||||||
|
|||||||
@@ -1,10 +1,48 @@
|
|||||||
import './web_push_notifications';
|
import './web_push_notifications';
|
||||||
|
|
||||||
|
function openCache() {
|
||||||
|
return caches.open('mastodon-web');
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchRoot() {
|
||||||
|
return fetch('/', { credentials: 'include' });
|
||||||
|
}
|
||||||
|
|
||||||
// Cause a new version of a registered Service Worker to replace an existing one
|
// Cause a new version of a registered Service Worker to replace an existing one
|
||||||
// that is already installed, and replace the currently active worker on open pages.
|
// that is already installed, and replace the currently active worker on open pages.
|
||||||
self.addEventListener('install', function(event) {
|
self.addEventListener('install', function(event) {
|
||||||
event.waitUntil(self.skipWaiting());
|
event.waitUntil(Promise.all([openCache(), fetchRoot()]).then(([cache, root]) => cache.put('/', root)));
|
||||||
});
|
});
|
||||||
self.addEventListener('activate', function(event) {
|
self.addEventListener('activate', function(event) {
|
||||||
event.waitUntil(self.clients.claim());
|
event.waitUntil(self.clients.claim());
|
||||||
});
|
});
|
||||||
|
self.addEventListener('fetch', function(event) {
|
||||||
|
const url = new URL(event.request.url);
|
||||||
|
|
||||||
|
if (url.pathname.startsWith('/web/')) {
|
||||||
|
const asyncResponse = fetchRoot();
|
||||||
|
const asyncCache = openCache();
|
||||||
|
|
||||||
|
event.respondWith(asyncResponse.then(async response => {
|
||||||
|
if (response.ok) {
|
||||||
|
const cache = await asyncCache;
|
||||||
|
await cache.put('/', response);
|
||||||
|
return response.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw null;
|
||||||
|
}).catch(() => caches.match('/')));
|
||||||
|
} else if (url.pathname === '/auth/sign_out') {
|
||||||
|
const asyncResponse = fetch(event.request);
|
||||||
|
const asyncCache = openCache();
|
||||||
|
|
||||||
|
event.respondWith(asyncResponse.then(async response => {
|
||||||
|
if (response.ok || response.type === 'opaqueredirect') {
|
||||||
|
const cache = await asyncCache;
|
||||||
|
await cache.delete('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -440,6 +440,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 60px 0;
|
padding: 60px 0;
|
||||||
padding-top: 55px;
|
padding-top: 55px;
|
||||||
|
margin: 0 auto;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1842,6 +1842,9 @@
|
|||||||
object-position: bottom left;
|
object-position: bottom left;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
user-drag: none;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||||||
visibility: visibility_from_audience,
|
visibility: visibility_from_audience,
|
||||||
thread: replied_to_status,
|
thread: replied_to_status,
|
||||||
conversation: conversation_from_uri(@object['conversation']),
|
conversation: conversation_from_uri(@object['conversation']),
|
||||||
media_attachments: process_attachments.take(4),
|
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
|
|||||||
visibility: visibility_scope,
|
visibility: visibility_scope,
|
||||||
conversation: find_or_create_conversation,
|
conversation: find_or_create_conversation,
|
||||||
thread: thread? ? find_status(thread.first) || find_activitypub_status(thread.first, thread.second) : nil,
|
thread: thread? ? find_status(thread.first) || find_activitypub_status(thread.first, thread.second) : nil,
|
||||||
media_attachments: media_attachments
|
media_attachment_ids: media_attachments.map(&:id)
|
||||||
)
|
)
|
||||||
|
|
||||||
save_mentions(status)
|
save_mentions(status)
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ class OStatus::AtomSerializer
|
|||||||
append_element(entry, 'summary', status.spoiler_text, 'xml:lang': status.language) if status.spoiler_text?
|
append_element(entry, 'summary', status.spoiler_text, 'xml:lang': status.language) if status.spoiler_text?
|
||||||
append_element(entry, 'content', Formatter.instance.format(status).to_str, type: 'html', 'xml:lang': status.language)
|
append_element(entry, 'content', Formatter.instance.format(status).to_str, type: 'html', 'xml:lang': status.language)
|
||||||
|
|
||||||
status.mentions.each do |mentioned|
|
status.mentions.order(:id).each do |mentioned|
|
||||||
append_element(entry, 'link', nil, rel: :mentioned, 'ostatus:object-type': OStatus::TagManager::TYPES[:person], href: OStatus::TagManager.instance.uri_for(mentioned.account))
|
append_element(entry, 'link', nil, rel: :mentioned, 'ostatus:object-type': OStatus::TagManager::TYPES[:person], href: OStatus::TagManager.instance.uri_for(mentioned.account))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -94,9 +94,16 @@ class Request
|
|||||||
class Socket < TCPSocket
|
class Socket < TCPSocket
|
||||||
class << self
|
class << self
|
||||||
def open(host, *args)
|
def open(host, *args)
|
||||||
address = IPSocket.getaddress(host)
|
outer_e = nil
|
||||||
raise Mastodon::HostValidationError if PrivateAddressCheck.private_address? IPAddr.new(address)
|
Addrinfo.foreach(host, nil, nil, :SOCK_STREAM) do |address|
|
||||||
super address, *args
|
begin
|
||||||
|
raise Mastodon::HostValidationError if PrivateAddressCheck.private_address? IPAddr.new(address.ip_address)
|
||||||
|
return super address.ip_address, *args
|
||||||
|
rescue => e
|
||||||
|
outer_e = e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
raise outer_e if outer_e
|
||||||
end
|
end
|
||||||
|
|
||||||
alias new open
|
alias new open
|
||||||
|
|||||||
@@ -47,7 +47,8 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
class Account < ApplicationRecord
|
class Account < ApplicationRecord
|
||||||
MENTION_RE = /(?<=^|[^\/[:word:]])@(([a-z0-9_]+)(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
|
USERNAME_RE = /[a-z0-9_]+([a-z0-9_\.]+[a-z0-9_]+)?/i
|
||||||
|
MENTION_RE = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
|
||||||
|
|
||||||
include AccountAvatar
|
include AccountAvatar
|
||||||
include AccountFinderConcern
|
include AccountFinderConcern
|
||||||
@@ -68,7 +69,8 @@ class Account < ApplicationRecord
|
|||||||
validates :username, uniqueness: { scope: :domain, case_sensitive: true }, if: -> { !local? && will_save_change_to_username? }
|
validates :username, uniqueness: { scope: :domain, case_sensitive: true }, if: -> { !local? && will_save_change_to_username? }
|
||||||
|
|
||||||
# Local user validations
|
# Local user validations
|
||||||
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? }
|
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? }
|
||||||
|
validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? }
|
||||||
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
|
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
|
||||||
validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? }
|
validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? }
|
||||||
validates :note, length: { maximum: 160 }, if: -> { local? && will_save_change_to_note? }
|
validates :note, length: { maximum: 160 }, if: -> { local? && will_save_change_to_note? }
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ module Remotable
|
|||||||
send("#{attachment_name}_file_name=", basename + extname)
|
send("#{attachment_name}_file_name=", basename + extname)
|
||||||
|
|
||||||
self[attribute_name] = url if has_attribute?(attribute_name)
|
self[attribute_name] = url if has_attribute?(attribute_name)
|
||||||
rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError => e
|
rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError => e
|
||||||
Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}"
|
Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}"
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ class User < ApplicationRecord
|
|||||||
devise :registerable, :recoverable, :rememberable, :trackable, :validatable,
|
devise :registerable, :recoverable, :rememberable, :trackable, :validatable,
|
||||||
:confirmable
|
:confirmable
|
||||||
|
|
||||||
|
devise :pam_authenticatable if ENV['PAM_ENABLED'] == 'true'
|
||||||
|
|
||||||
devise :omniauthable
|
devise :omniauthable
|
||||||
|
|
||||||
belongs_to :account, inverse_of: :user
|
belongs_to :account, inverse_of: :user
|
||||||
@@ -96,7 +98,7 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
def pam_conflict?
|
def pam_conflict?
|
||||||
return false unless Devise.pam_authentication
|
return false unless Devise.pam_authentication
|
||||||
encrypted_password.present? && is_pam_account?
|
encrypted_password.present? && pam_managed_user?
|
||||||
end
|
end
|
||||||
|
|
||||||
def pam_get_name
|
def pam_get_name
|
||||||
@@ -267,22 +269,22 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.pam_get_user(attributes = {})
|
def self.pam_get_user(attributes = {})
|
||||||
if attributes[:email]
|
return nil unless attributes[:email]
|
||||||
resource =
|
resource =
|
||||||
if Devise.check_at_sign && !attributes[:email].index('@')
|
if Devise.check_at_sign && !attributes[:email].index('@')
|
||||||
joins(:account).find_by(accounts: { username: attributes[:email] })
|
joins(:account).find_by(accounts: { username: attributes[:email] })
|
||||||
else
|
else
|
||||||
find_by(email: attributes[:email])
|
find_by(email: attributes[:email])
|
||||||
end
|
end
|
||||||
|
|
||||||
if resource.blank?
|
if resource.blank?
|
||||||
resource = new(email: attributes[:email])
|
resource = new(email: attributes[:email])
|
||||||
if Devise.check_at_sign && !resource[:email].index('@')
|
if Devise.check_at_sign && !resource[:email].index('@')
|
||||||
resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}"
|
resource[:email] = Rpam2.getenv(resource.find_pam_service, attributes[:email], attributes[:password], 'email', false)
|
||||||
end
|
resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}" unless resource[:email]
|
||||||
end
|
end
|
||||||
resource
|
|
||||||
end
|
end
|
||||||
|
resource
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.ldap_get_user(attributes = {})
|
def self.ldap_get_user(attributes = {})
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def virtual_tags
|
def virtual_tags
|
||||||
object.mentions + object.tags + object.emojis
|
object.mentions.to_a.sort_by(&:id) + object.tags + object.emojis
|
||||||
end
|
end
|
||||||
|
|
||||||
def atom_uri
|
def atom_uri
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||||||
belongs_to :account, serializer: REST::AccountSerializer
|
belongs_to :account, serializer: REST::AccountSerializer
|
||||||
|
|
||||||
has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
|
has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
|
||||||
has_many :mentions
|
has_many :ordered_mentions, key: :mentions
|
||||||
has_many :tags
|
has_many :tags
|
||||||
has_many :emojis, serializer: REST::CustomEmojiSerializer
|
has_many :emojis, serializer: REST::CustomEmojiSerializer
|
||||||
|
|
||||||
@@ -86,6 +86,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||||||
%w(public unlisted).include?(object.visibility)
|
%w(public unlisted).include?(object.visibility)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ordered_mentions
|
||||||
|
object.mentions.to_a.sort_by(&:id)
|
||||||
|
end
|
||||||
|
|
||||||
class ApplicationSerializer < ActiveModel::Serializer
|
class ApplicationSerializer < ActiveModel::Serializer
|
||||||
attributes :name, :website
|
attributes :name, :website
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||||||
|
|
||||||
RedisLock.acquire(lock_options) do |lock|
|
RedisLock.acquire(lock_options) do |lock|
|
||||||
if lock.acquired?
|
if lock.acquired?
|
||||||
@account = Account.find_by(uri: @uri)
|
@account = Account.find_remote(@username, @domain)
|
||||||
@old_public_key = @account&.public_key
|
@old_public_key = @account&.public_key
|
||||||
@old_protocol = @account&.protocol
|
@old_protocol = @account&.protocol
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class BackupService < BaseService
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
archive_filename = ['archive', Time.now.utc.strftime('%Y%m%d%H%M%S'), SecureRandom.hex(2)].join('-') + '.tar.gz'
|
archive_filename = ['archive', Time.now.utc.strftime('%Y%m%d%H%M%S'), SecureRandom.hex(16)].join('-') + '.tar.gz'
|
||||||
|
|
||||||
@backup.dump = ActionDispatch::Http::UploadedFile.new(tempfile: tmp_file, filename: archive_filename)
|
@backup.dump = ActionDispatch::Http::UploadedFile.new(tempfile: tmp_file, filename: archive_filename)
|
||||||
@backup.processed = true
|
@backup.processed = true
|
||||||
|
|||||||
14
app/validators/unique_username_validator.rb
Normal file
14
app/validators/unique_username_validator.rb
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class UniqueUsernameValidator < ActiveModel::Validator
|
||||||
|
def validate(account)
|
||||||
|
return if account.username.nil?
|
||||||
|
|
||||||
|
normalized_username = account.username.downcase.delete('.')
|
||||||
|
|
||||||
|
scope = Account.where(domain: nil, username: normalized_username)
|
||||||
|
scope = scope.where.not(id: account.id) if account.persisted?
|
||||||
|
|
||||||
|
account.errors.add(:username, :taken) if scope.exists?
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
= opengraph 'og:url', url
|
= opengraph 'og:url', url
|
||||||
= opengraph 'og:site_name', site_title
|
= opengraph 'og:site_name', site_title
|
||||||
= opengraph 'og:title', [yield(:page_title).strip.presence, site_title].compact.join(' - ')
|
= opengraph 'og:title', yield(:page_title).strip
|
||||||
= opengraph 'og:description', account_description(account)
|
= opengraph 'og:description', account_description(account)
|
||||||
= opengraph 'og:image', full_asset_url(account.avatar.url(:original))
|
= opengraph 'og:image', full_asset_url(account.avatar.url(:original))
|
||||||
= opengraph 'og:image:width', '120'
|
= opengraph 'og:image:width', '120'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
- content_for :page_title do
|
- content_for :page_title do
|
||||||
= "#{display_name(@account)} (@#{@account.username})"
|
= "#{display_name(@account)} (@#{@account.local_username_and_domain})"
|
||||||
|
|
||||||
- content_for :header_tags do
|
- content_for :header_tags do
|
||||||
%meta{ name: 'description', content: account_description(@account) }/
|
%meta{ name: 'description', content: account_description(@account) }/
|
||||||
|
|||||||
@@ -24,6 +24,11 @@
|
|||||||
%bdi= display_name(status.account)
|
%bdi= display_name(status.account)
|
||||||
= "@#{status.account.acct}"
|
= "@#{status.account.acct}"
|
||||||
|
|
||||||
|
- if status.spoiler_text?
|
||||||
|
%div{ dir: rtl_status?(status) ? 'rtl' : 'ltr' }
|
||||||
|
%p
|
||||||
|
= Formatter.instance.format_spoiler(status)
|
||||||
|
|
||||||
%div{ dir: rtl_status?(status) ? 'rtl' : 'ltr' }
|
%div{ dir: rtl_status?(status) ? 'rtl' : 'ltr' }
|
||||||
= Formatter.instance.format(status)
|
= Formatter.instance.format(status)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<% if status.spoiler_text? %>
|
||||||
|
<%= raw status.spoiler_text %>
|
||||||
|
----
|
||||||
|
|
||||||
|
<% end %>
|
||||||
<%= raw Formatter.instance.plaintext(status) %>
|
<%= raw Formatter.instance.plaintext(status) %>
|
||||||
|
|
||||||
<%= raw t('application_mailer.view')%> <%= web_url("statuses/#{status.id}") %>
|
<%= raw t('application_mailer.view')%> <%= web_url("statuses/#{status.id}") %>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
= opengraph 'og:description', [activity.spoiler_text, activity.text].reject(&:blank?).join("\n\n")
|
= opengraph 'og:description', status_description(activity)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
- if activity.is_a?(Status) && activity.media_attachments.any?
|
- if activity.is_a?(Status) && activity.non_sensitive_with_media?
|
||||||
- player_card = false
|
- player_card = false
|
||||||
- activity.media_attachments.each do |media|
|
- activity.media_attachments.each do |media|
|
||||||
- if media.image?
|
- if media.image?
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
= opengraph 'og:site_name', site_title
|
= opengraph 'og:site_name', site_title
|
||||||
= opengraph 'og:type', 'article'
|
= opengraph 'og:type', 'article'
|
||||||
= opengraph 'og:title', "#{@account.display_name.presence || @account.username} on #{site_hostname}"
|
= opengraph 'og:title', "#{display_name(@account)} (@#{@account.local_username_and_domain})"
|
||||||
= opengraph 'og:url', account_stream_entry_url(@account, @stream_entry)
|
= opengraph 'og:url', short_account_status_url(@account, @stream_entry)
|
||||||
|
|
||||||
= render 'stream_entries/og_description', activity: @stream_entry.activity
|
= render 'stream_entries/og_description', activity: @stream_entry.activity
|
||||||
= render 'stream_entries/og_image', activity: @stream_entry.activity, account: @account
|
= render 'stream_entries/og_image', activity: @stream_entry.activity, account: @account
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
%table.input{ align: 'center', cellspacing: 0, cellpadding: 0 }
|
%table.input{ align: 'center', cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td= @resource.unconfirmed_email
|
%td= @resource.try(:unconfirmed_email) ? @resource.unconfirmed_email : @resource.email
|
||||||
|
|
||||||
%table.email-table{ cellspacing: 0, cellpadding: 0 }
|
%table.email-table{ cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
<%= t 'devise.mailer.email_changed.explanation' %>
|
<%= t 'devise.mailer.email_changed.explanation' %>
|
||||||
|
|
||||||
<%= @resource.unconfirmed_email %>
|
<%= @resource.try(:unconfirmed_email) ? @resource.unconfirmed_email : @resource.email %>
|
||||||
|
|
||||||
<%= t 'devise.mailer.email_changed.extra' %>
|
<%= t 'devise.mailer.email_changed.extra' %>
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ data.db:
|
|||||||
command: |
|
command: |
|
||||||
PGPASSWORD=${DATA_DB_PASS} pg_dump -U ${DATA_DB_USER} -w -Fc -O gonano |
|
PGPASSWORD=${DATA_DB_PASS} pg_dump -U ${DATA_DB_USER} -w -Fc -O gonano |
|
||||||
gzip |
|
gzip |
|
||||||
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).sql.gz --data-binary @- &&
|
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).sql.gz -X POST -T - >&2
|
||||||
curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
|
curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
|
||||||
sed 's/,/\n/g' |
|
sed 's/,/\n/g' |
|
||||||
grep ${HOSTNAME} |
|
grep ${HOSTNAME} |
|
||||||
@@ -215,7 +215,7 @@ data.redis:
|
|||||||
- id: backup
|
- id: backup
|
||||||
schedule: '0 3 * * *'
|
schedule: '0 3 * * *'
|
||||||
command: |
|
command: |
|
||||||
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).rdb --data-binary @/data/var/db/redis/dump.rdb &&
|
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).rdb -X POST -T /data/var/db/redis/dump.rdb >&2
|
||||||
curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
|
curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
|
||||||
sed 's/,/\n/g' |
|
sed 's/,/\n/g' |
|
||||||
grep ${HOSTNAME} |
|
grep ${HOSTNAME} |
|
||||||
@@ -236,7 +236,7 @@ data.storage:
|
|||||||
schedule: '0 3 * * *'
|
schedule: '0 3 * * *'
|
||||||
command: |
|
command: |
|
||||||
tar cz -C /data/var/db/unfs/ . |
|
tar cz -C /data/var/db/unfs/ . |
|
||||||
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).tgz --data-binary @- &&
|
curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).tgz -X POST -T - >&2
|
||||||
curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
|
curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
|
||||||
sed 's/,/\n/g' |
|
sed 's/,/\n/g' |
|
||||||
grep ${HOSTNAME} |
|
grep ${HOSTNAME} |
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ require_relative '../lib/devise/ldap_authenticatable'
|
|||||||
|
|
||||||
Dotenv::Railtie.load
|
Dotenv::Railtie.load
|
||||||
|
|
||||||
|
Bundler.require(:pam_authentication) if ENV['PAM_ENABLED'] == 'true'
|
||||||
|
|
||||||
require_relative '../lib/mastodon/redis_config'
|
require_relative '../lib/mastodon/redis_config'
|
||||||
|
|
||||||
module Mastodon
|
module Mastodon
|
||||||
@@ -74,9 +76,7 @@ module Mastodon
|
|||||||
]
|
]
|
||||||
|
|
||||||
config.i18n.default_locale = ENV['DEFAULT_LOCALE']&.to_sym
|
config.i18n.default_locale = ENV['DEFAULT_LOCALE']&.to_sym
|
||||||
if config.i18n.available_locales.include?(config.i18n.default_locale)
|
unless config.i18n.available_locales.include?(config.i18n.default_locale)
|
||||||
config.i18n.fallbacks = [:en]
|
|
||||||
else
|
|
||||||
config.i18n.default_locale = :en
|
config.i18n.default_locale = :en
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ Rails.application.configure do
|
|||||||
# config.action_mailer.raise_delivery_errors = false
|
# config.action_mailer.raise_delivery_errors = false
|
||||||
|
|
||||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||||
# the I18n.default_locale when a translation cannot be found).
|
# English when a translation cannot be found).
|
||||||
config.i18n.fallbacks = true
|
config.i18n.fallbacks = [:en]
|
||||||
|
|
||||||
# Send deprecation notices to registered listeners.
|
# Send deprecation notices to registered listeners.
|
||||||
config.active_support.deprecation = :notify
|
config.active_support.deprecation = :notify
|
||||||
|
|||||||
@@ -62,3 +62,4 @@ ignore_unused:
|
|||||||
- 'errors.429'
|
- 'errors.429'
|
||||||
- 'admin.accounts.roles.*'
|
- 'admin.accounts.roles.*'
|
||||||
- 'admin.action_logs.actions.*'
|
- 'admin.action_logs.actions.*'
|
||||||
|
- 'statuses.attached.*'
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ module Devise
|
|||||||
@@ldap_bind_dn = nil
|
@@ldap_bind_dn = nil
|
||||||
mattr_accessor :ldap_password
|
mattr_accessor :ldap_password
|
||||||
@@ldap_password = nil
|
@@ldap_password = nil
|
||||||
|
mattr_accessor :ldap_tls_no_verify
|
||||||
|
@@ldap_tls_no_verify = false
|
||||||
|
|
||||||
class Strategies::PamAuthenticatable
|
class Strategies::PamAuthenticatable
|
||||||
def valid?
|
def valid?
|
||||||
@@ -342,7 +344,7 @@ Devise.setup do |config|
|
|||||||
config.usernamefield = nil
|
config.usernamefield = nil
|
||||||
config.emailfield = 'email'
|
config.emailfield = 'email'
|
||||||
config.check_at_sign = true
|
config.check_at_sign = true
|
||||||
config.pam_default_suffix = ENV.fetch('PAM_DEFAULT_SUFFIX') { nil }
|
config.pam_default_suffix = ENV.fetch('PAM_EMAIL_DOMAIN') { ENV['LOCAL_DOMAIN'] }
|
||||||
config.pam_default_service = ENV.fetch('PAM_DEFAULT_SERVICE') { 'rpam' }
|
config.pam_default_service = ENV.fetch('PAM_DEFAULT_SERVICE') { 'rpam' }
|
||||||
config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE') { nil }
|
config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE') { nil }
|
||||||
end
|
end
|
||||||
@@ -357,5 +359,6 @@ Devise.setup do |config|
|
|||||||
config.ldap_bind_dn = ENV.fetch('LDAP_BIND_DN')
|
config.ldap_bind_dn = ENV.fetch('LDAP_BIND_DN')
|
||||||
config.ldap_password = ENV.fetch('LDAP_PASSWORD')
|
config.ldap_password = ENV.fetch('LDAP_PASSWORD')
|
||||||
config.ldap_uid = ENV.fetch('LDAP_UID', 'cn')
|
config.ldap_uid = ENV.fetch('LDAP_UID', 'cn')
|
||||||
|
config.ldap_tls_no_verify = ENV['LDAP_TLS_NO_VERIFY'] == 'true'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -513,6 +513,8 @@ ar:
|
|||||||
over_character_limit: تم تجاوز حد الـ %{max} حرف المسموح بها
|
over_character_limit: تم تجاوز حد الـ %{max} حرف المسموح بها
|
||||||
pin_errors:
|
pin_errors:
|
||||||
ownership: لا يمكن تدبيس تبويق نشره شخص آخر
|
ownership: لا يمكن تدبيس تبويق نشره شخص آخر
|
||||||
|
private: لا يمكن تثبيت تبويق لم يُنشر للعامة
|
||||||
|
reblog: لا يمكن تثبيت ترقية
|
||||||
show_more: أظهر المزيد
|
show_more: أظهر المزيد
|
||||||
title: '%{name} : "%{quote}"'
|
title: '%{name} : "%{quote}"'
|
||||||
visibilities:
|
visibilities:
|
||||||
@@ -524,6 +526,7 @@ ar:
|
|||||||
unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة
|
unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة
|
||||||
stream_entries:
|
stream_entries:
|
||||||
click_to_show: إضغط للعرض
|
click_to_show: إضغط للعرض
|
||||||
|
pinned: تبويق مثبّت
|
||||||
reblogged: رقى
|
reblogged: رقى
|
||||||
sensitive_content: محتوى حساس
|
sensitive_content: محتوى حساس
|
||||||
terms:
|
terms:
|
||||||
|
|||||||
@@ -634,6 +634,15 @@ en:
|
|||||||
two_factor_authentication: Two-factor Auth
|
two_factor_authentication: Two-factor Auth
|
||||||
your_apps: Your applications
|
your_apps: Your applications
|
||||||
statuses:
|
statuses:
|
||||||
|
attached:
|
||||||
|
description: 'Attached: %{attached}'
|
||||||
|
image:
|
||||||
|
one: "%{count} image"
|
||||||
|
other: "%{count} images"
|
||||||
|
video:
|
||||||
|
one: "%{count} video"
|
||||||
|
other: "%{count} videos"
|
||||||
|
content_warning: 'Content warning: %{warning}'
|
||||||
open_in_web: Open in web
|
open_in_web: Open in web
|
||||||
over_character_limit: character limit of %{max} exceeded
|
over_character_limit: character limit of %{max} exceeded
|
||||||
pin_errors:
|
pin_errors:
|
||||||
|
|||||||
@@ -275,6 +275,7 @@ es:
|
|||||||
username: Nombre de usuario
|
username: Nombre de usuario
|
||||||
hero:
|
hero:
|
||||||
desc_html: Mostrado en la página principal. Recomendable al menos 600x100px. Por defecto se establece a la miniatura de la instancia
|
desc_html: Mostrado en la página principal. Recomendable al menos 600x100px. Por defecto se establece a la miniatura de la instancia
|
||||||
|
title: Imagen de portada
|
||||||
peers_api_enabled:
|
peers_api_enabled:
|
||||||
desc_html: Nombres de dominio que esta instancia ha encontrado en el fediverso
|
desc_html: Nombres de dominio que esta instancia ha encontrado en el fediverso
|
||||||
title: Publicar lista de instancias descubiertas
|
title: Publicar lista de instancias descubiertas
|
||||||
|
|||||||
@@ -4,13 +4,19 @@ fi:
|
|||||||
hints:
|
hints:
|
||||||
defaults:
|
defaults:
|
||||||
avatar: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 400x400px
|
avatar: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 400x400px
|
||||||
digest: Lähetetään vain pitkän poissaolon jälkeen, ja vain jos olet vastaanottanut yksityisviestejä poissaolosi aikana.
|
digest: Lähetetään vain pitkän poissaolon jälkeen, ja vain jos olet vastaanottanut yksityisviestejä poissaolosi aikana
|
||||||
display_name: Korkeintaan 30 merkkiä
|
display_name: Korkeintaan 30 merkkiä
|
||||||
header: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 700x335px
|
header: PNG, GIF tai JPG. Korkeintaan 2MB. Skaalataan kokoon 700x335px
|
||||||
locked: Vaatii sinun manuaalisesti hyväksymään seuraajat, ja asettaa julkaisujen yksityisyyden vain seuraajille
|
locked: Vaatii sinua manuaalisesti hyväksymään seuraajat
|
||||||
note: Korkeintaan 160 merkkiä
|
note: Korkeintaan 160 merkkiä
|
||||||
|
setting_noindex: Vaikuttaa julkiseen profiiliisi ja statuspäivityksiisi
|
||||||
|
setting_theme: Vaikuttaa siihen, miltä Mastodon näyttää kun olet kirjautuneena milllä tahansa laitteella.
|
||||||
imports:
|
imports:
|
||||||
data: CSV tiedosto tuotu toiselta Mastodon palvelimelta
|
data: CSV tiedosto, joka on tuotu toiselta Mastodon-palvelimelta
|
||||||
|
sessions:
|
||||||
|
otp: Syötä kaksivaiheisen tunnistuksen koodi puhelimestasi tai käytä yhtä palautuskoodeistasi.
|
||||||
|
user:
|
||||||
|
filtered_languages: Valitut kielet suodatetaan julkisilta aikajanoilta
|
||||||
labels:
|
labels:
|
||||||
defaults:
|
defaults:
|
||||||
avatar: Profiilikuva
|
avatar: Profiilikuva
|
||||||
@@ -18,22 +24,37 @@ fi:
|
|||||||
confirm_password: Varmista salasana
|
confirm_password: Varmista salasana
|
||||||
current_password: Nykyinen salasana
|
current_password: Nykyinen salasana
|
||||||
data: Data
|
data: Data
|
||||||
display_name: Näykyvä nimi
|
display_name: Nimimerkki
|
||||||
email: Sähköpostiosoite
|
email: Sähköpostiosoite
|
||||||
header: Otsake
|
expires_in: Vanhentuu
|
||||||
|
filtered_languages: Suodatetut kielet
|
||||||
|
header: Otsakekuva
|
||||||
locale: Kieli
|
locale: Kieli
|
||||||
locked: Tee tilistä yksityinen
|
locked: Tee tilistä yksityinen
|
||||||
max_uses: Max käyttökerrat
|
max_uses: Max käyttökerrat
|
||||||
new_password: Uusi salasana
|
new_password: Uusi salasana
|
||||||
note: Bio
|
note: Kuvaus
|
||||||
otp_attempt: Kaksivaiheinen koodi
|
otp_attempt: Kaksivaiheinen koodi
|
||||||
password: Salasana
|
password: Salasana
|
||||||
|
setting_auto_play_gif: Animoitujen GIFfien automaattitoisto
|
||||||
|
setting_boost_modal: Näytä vahvistusikkuna ennen boostausta
|
||||||
setting_default_privacy: Julkaisun yksityisyys
|
setting_default_privacy: Julkaisun yksityisyys
|
||||||
|
setting_default_sensitive: Merkitse media aina arkaluontoiseksi
|
||||||
|
setting_delete_modal: Näytä vahvistusikkuna ennen töötin poistamista
|
||||||
|
setting_display_sensitive_media: Näytä aina arkaluontoiseksi merkitty media
|
||||||
|
setting_noindex: Jättäydy pois hakukoneindeksoinnista
|
||||||
|
setting_reduce_motion: Vähennä liikettä animaatioissa
|
||||||
|
setting_system_font_ui: Käytä käyttöjärjestelmän oletusfonttia
|
||||||
|
setting_theme: Sivuston teema
|
||||||
|
setting_unfollow_modal: Näytä vahvistusikkuna ennen seuraamisen lopettamista
|
||||||
|
severity: Vakavuusaste
|
||||||
type: Tuontityyppi
|
type: Tuontityyppi
|
||||||
username: Käyttäjänimi
|
username: Käyttäjänimi
|
||||||
|
username_or_email: Käyttäjänimi tai sähköposti
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: Estä ilmoitukset käyttäjiltä jotka eivät seuraa sinua
|
must_be_follower: Estä ilmoitukset käyttäjiltä, jotka eivät seuraa sinua
|
||||||
must_be_following: Estä ilmoitukset käyttäjiltä joita et seuraa
|
must_be_following: Estä ilmoitukset käyttäjiltä, joita et seuraa
|
||||||
|
must_be_following_dm: Estä suorat viestit ihmisiltä, joita et seuraa
|
||||||
notification_emails:
|
notification_emails:
|
||||||
digest: Lähetä koosteviestejä sähköpostilla
|
digest: Lähetä koosteviestejä sähköpostilla
|
||||||
favourite: Lähetä sähköposti, kun joku tykkää statuksestasi
|
favourite: Lähetä sähköposti, kun joku tykkää statuksestasi
|
||||||
@@ -44,5 +65,5 @@ fi:
|
|||||||
'no': Ei
|
'no': Ei
|
||||||
required:
|
required:
|
||||||
mark: "*"
|
mark: "*"
|
||||||
text: vaaditaan
|
text: pakollinen tieto
|
||||||
'yes': Kyllä
|
'yes': Kyllä
|
||||||
|
|||||||
@@ -593,7 +593,7 @@ sk:
|
|||||||
title: Sezóna
|
title: Sezóna
|
||||||
settings:
|
settings:
|
||||||
authorized_apps: Autorizované aplikácie
|
authorized_apps: Autorizované aplikácie
|
||||||
back: Naspäť na stránku
|
back: Späť do Mastodonu
|
||||||
delete: Zmazanie účtu
|
delete: Zmazanie účtu
|
||||||
development: Vývoj
|
development: Vývoj
|
||||||
edit_profile: Upraviť profil
|
edit_profile: Upraviť profil
|
||||||
@@ -630,8 +630,15 @@ sk:
|
|||||||
title: Podmienky užívania, a pravidlá o súkromí pre %{instance}
|
title: Podmienky užívania, a pravidlá o súkromí pre %{instance}
|
||||||
two_factor_authentication:
|
two_factor_authentication:
|
||||||
enable: Povoliť
|
enable: Povoliť
|
||||||
|
enabled: Dvoj-faktorové overovanie je povolené
|
||||||
|
enabled_success: Dvoj-faktorové overovanie bolo úspešne povolené
|
||||||
generate_recovery_codes: Vygeneruj zálohové kódy
|
generate_recovery_codes: Vygeneruj zálohové kódy
|
||||||
|
lost_recovery_codes: Zálohové kódy ti umožnia dostať sa k svojmu účtu ak stratíš telefón. Pokiaľ si stratila svoje zálohové kódy, môžeš si ich tu znovu vygenerovať. Tvoje staré zálohové kódy budú zneplatnené.
|
||||||
|
manual_instructions: 'Pokiaľ nemôžeš oskenovať daný QR kód, a potrebuješ ho zadať ručne, tu je tajomstvo v textovom formáte:'
|
||||||
|
recovery_codes: Zálohuj kódy pre obnovu
|
||||||
|
recovery_codes_regenerated: Zálohové kódy boli úspešne zvova vygenerované
|
||||||
setup: Nastavenie
|
setup: Nastavenie
|
||||||
|
wrong_code: Zadaný kód bol neplatný. Je serverový čas a čas na zariadení správny?
|
||||||
user_mailer:
|
user_mailer:
|
||||||
backup_ready:
|
backup_ready:
|
||||||
explanation: Vyžiadal/a si si úplnú zálohu tvojho Mastodon účtu. Táto záloha je teraz pripravená na stiahnutie!
|
explanation: Vyžiadal/a si si úplnú zálohu tvojho Mastodon účtu. Táto záloha je teraz pripravená na stiahnutie!
|
||||||
@@ -639,12 +646,17 @@ sk:
|
|||||||
title: Odber archívu
|
title: Odber archívu
|
||||||
welcome:
|
welcome:
|
||||||
edit_profile_action: Nastav profil
|
edit_profile_action: Nastav profil
|
||||||
|
edit_profile_step: Profil si môžeš prispôsobiť nahratím portrétu a hlavičky, môžeš upraviť svoje meno a viac. Pokiaľ chceš preverovať nových následovateľov predtým než ťa budú môcť sledovať, môžeš uzamknúť svoj účet.
|
||||||
explanation: Tu nájdeš nejaké tipy do začiatku
|
explanation: Tu nájdeš nejaké tipy do začiatku
|
||||||
final_action: Začni prispievať
|
final_action: Začni prispievať
|
||||||
final_step: 'Začnite písať! Aj bez následovníkov budú vaše verejné správy videné ostatnými, napríklad na lokálnej osi a pod haštagmi. Môžete sa ostatným predstaviť pod haštagom #introductions.'
|
final_step: 'Začnite písať! Aj bez následovníkov budú vaše verejné správy videné ostatnými, napríklad na lokálnej osi a pod haštagmi. Môžete sa ostatným predstaviť pod haštagom #introductions.'
|
||||||
full_handle: Adresa tvojho profilu v celom formáte
|
full_handle: Adresa tvojho profilu v celom formáte
|
||||||
|
full_handle_hint: Toto je čo musíš dať vedieť svojím priateľom aby ti mohli posielať správy, alebo ťa následovať z inej instancie.
|
||||||
review_preferences_action: Zmeniť nastavenia
|
review_preferences_action: Zmeniť nastavenia
|
||||||
subject: Vitaj na Mastodone
|
subject: Vitaj na Mastodone
|
||||||
|
tip_bridge_html: Ak prichádzaš z Twitteru, môžeš svojích priateľov nájsť na Mastodone pomocou tzv. <a href="%{bridge_url}">mostíkovej aplikácie</a>. Ale tá funguje iba ak ju aj oni niekedy použili!
|
||||||
|
tip_federated_timeline: Federovaná os zobrazuje sieť Mastodonu až po jej hranice. Ale zahŕňa iba ľúdí ktorých ostatní okolo teba sledujú, takže predsa nieje úplne celistvá.
|
||||||
|
tip_following: Správcu servera následuješ automaticky. Môžeš ale nájsť mnoho iných zaujímavých ľudí ak prezrieš tak lokálnu, ako aj globálne federovanú os.
|
||||||
tip_local_timeline: Lokálna os je celkový pohľad na aktivitu užívateľov %{instance}. Toto sú tvoji najbližší susedia!
|
tip_local_timeline: Lokálna os je celkový pohľad na aktivitu užívateľov %{instance}. Toto sú tvoji najbližší susedia!
|
||||||
tip_mobile_webapp: Pokiaľ ti prehliadač ponúkne možnosť pridať Mastodon na tvoju obrazovku, môžeš potom dostávať notifikácie skoro ako z natívnej aplikácie!
|
tip_mobile_webapp: Pokiaľ ti prehliadač ponúkne možnosť pridať Mastodon na tvoju obrazovku, môžeš potom dostávať notifikácie skoro ako z natívnej aplikácie!
|
||||||
tips: Tipy
|
tips: Tipy
|
||||||
|
|||||||
@@ -1,49 +1,53 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
if ENV['LDAP_ENABLED'] == 'true'
|
require 'net/ldap'
|
||||||
require 'net/ldap'
|
require 'devise/strategies/authenticatable'
|
||||||
require 'devise/strategies/authenticatable'
|
|
||||||
|
|
||||||
module Devise
|
module Devise
|
||||||
module Strategies
|
module Strategies
|
||||||
class LdapAuthenticatable < Authenticatable
|
class LdapAuthenticatable < Authenticatable
|
||||||
def authenticate!
|
def authenticate!
|
||||||
if params[:user]
|
if params[:user]
|
||||||
ldap = Net::LDAP.new(
|
ldap = Net::LDAP.new(
|
||||||
host: Devise.ldap_host,
|
host: Devise.ldap_host,
|
||||||
port: Devise.ldap_port,
|
port: Devise.ldap_port,
|
||||||
base: Devise.ldap_base,
|
base: Devise.ldap_base,
|
||||||
encryption: {
|
encryption: {
|
||||||
method: Devise.ldap_method,
|
method: Devise.ldap_method,
|
||||||
tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS,
|
tls_options: tls_options,
|
||||||
},
|
},
|
||||||
auth: {
|
auth: {
|
||||||
method: :simple,
|
method: :simple,
|
||||||
username: Devise.ldap_bind_dn,
|
username: Devise.ldap_bind_dn,
|
||||||
password: Devise.ldap_password,
|
password: Devise.ldap_password,
|
||||||
},
|
},
|
||||||
connect_timeout: 10
|
connect_timeout: 10
|
||||||
)
|
)
|
||||||
|
|
||||||
if (user_info = ldap.bind_as(base: Devise.ldap_base, filter: "(#{Devise.ldap_uid}=#{email})", password: password))
|
if (user_info = ldap.bind_as(base: Devise.ldap_base, filter: "(#{Devise.ldap_uid}=#{email})", password: password))
|
||||||
user = User.ldap_get_user(user_info.first)
|
user = User.ldap_get_user(user_info.first)
|
||||||
success!(user)
|
success!(user)
|
||||||
else
|
else
|
||||||
return fail(:invalid_login)
|
return fail(:invalid_login)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def email
|
def email
|
||||||
params[:user][:email]
|
params[:user][:email]
|
||||||
end
|
end
|
||||||
|
|
||||||
def password
|
def password
|
||||||
params[:user][:password]
|
params[:user][:password]
|
||||||
|
end
|
||||||
|
|
||||||
|
def tls_options
|
||||||
|
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.tap do |options|
|
||||||
|
options[:verify_mode] = OpenSSL::SSL::VERIFY_NONE if Devise.ldap_tls_no_verify
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module Mastodon
|
|||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
1
|
2
|
||||||
end
|
end
|
||||||
|
|
||||||
def pre
|
def pre
|
||||||
|
|||||||
@@ -472,7 +472,7 @@ namespace :mastodon do
|
|||||||
|
|
||||||
if user.save
|
if user.save
|
||||||
prompt.ok 'User created and confirmation mail sent to the user\'s email address.'
|
prompt.ok 'User created and confirmation mail sent to the user\'s email address.'
|
||||||
prompt.ok "Here is the random password generated for the user: #{password}"
|
prompt.ok "Here is the random password generated for the user: #{user.password}"
|
||||||
else
|
else
|
||||||
prompt.warn 'User was not created because of the following errors:'
|
prompt.warn 'User was not created because of the following errors:'
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ describe Request do
|
|||||||
expect(a_request(:get, 'http://example.com')).to have_been_made.once
|
expect(a_request(:get, 'http://example.com')).to have_been_made.once
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'executes a HTTP request when the first address is private' do
|
||||||
|
allow(Addrinfo).to receive(:foreach).with('example.com', nil, nil, :SOCK_STREAM)
|
||||||
|
.and_yield(Addrinfo.new(["AF_INET", 0, "example.com", "0.0.0.0"], :PF_INET, :SOCK_STREAM))
|
||||||
|
.and_yield(Addrinfo.new(["AF_INET6", 0, "example.com", "2001:4860:4860::8844"], :PF_INET6, :SOCK_STREAM))
|
||||||
|
expect(a_request(:get, 'http://example.com')).to have_been_made.once
|
||||||
|
end
|
||||||
|
|
||||||
it 'sets headers' do
|
it 'sets headers' do
|
||||||
expect(a_request(:get, 'http://example.com').with(headers: subject.headers)).to have_been_made
|
expect(a_request(:get, 'http://example.com').with(headers: subject.headers)).to have_been_made
|
||||||
end
|
end
|
||||||
@@ -61,7 +68,9 @@ describe Request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'raises Mastodon::ValidationError' do
|
it 'raises Mastodon::ValidationError' do
|
||||||
allow(IPSocket).to receive(:getaddress).with('example.com').and_return('0.0.0.0')
|
allow(Addrinfo).to receive(:foreach).with('example.com', nil, nil, :SOCK_STREAM)
|
||||||
|
.and_yield(Addrinfo.new(["AF_INET", 0, "example.com", "0.0.0.0"], :PF_INET, :SOCK_STREAM))
|
||||||
|
.and_yield(Addrinfo.new(["AF_INET6", 0, "example.com", "2001:db8::face"], :PF_INET6, :SOCK_STREAM))
|
||||||
expect{ subject.perform }.to raise_error Mastodon::ValidationError
|
expect{ subject.perform }.to raise_error Mastodon::ValidationError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user