diff options
99 files changed, 869 insertions, 1517 deletions
diff --git a/.dockerignore b/.dockerignore index 5cd3b179a..5fb9861de 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,3 +11,4 @@ vendor/bundle *~ postgres redis +elasticsearch diff --git a/.gitignore b/.gitignore index 38ebc934f..51e47bb52 100644 --- a/.gitignore +++ b/.gitignore @@ -36,9 +36,10 @@ config/deploy/* .vscode/ .idea/ -# Ignore postgres + redis volume optionally created by docker-compose +# Ignore postgres + redis + elasticsearch volume optionally created by docker-compose postgres redis +elasticsearch # Ignore Apple files .DS_Store diff --git a/Gemfile b/Gemfile index 9ab7e046c..03ffd49ec 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,7 @@ gem 'devise-two-factor', '~> 3.0' group :pam_authentication, optional: true do gem 'devise_pam_authenticatable2', '~> 9.0' end + gem 'net-ldap', '~> 0.10' gem 'omniauth-cas', '~> 1.1' gem 'omniauth-saml', '~> 1.10' @@ -81,6 +82,7 @@ gem 'sidekiq-bulk', '~>0.1.1' gem 'simple-navigation', '~> 4.0' gem 'simple_form', '~> 3.4' gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie' +gem 'stoplight', '~> 2.1.3' gem 'strong_migrations' gem 'tty-command' gem 'tty-prompt' diff --git a/Gemfile.lock b/Gemfile.lock index be623923a..c92b40d6c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -553,6 +553,7 @@ GEM net-scp (>= 1.1.2) net-ssh (>= 2.8.0) statsd-ruby (1.2.1) + stoplight (2.1.3) streamio-ffmpeg (3.0.2) multi_json (~> 1.8) strong_migrations (0.1.9) @@ -721,6 +722,7 @@ DEPENDENCIES simple_form (~> 3.4) simplecov (~> 0.14) sprockets-rails (~> 3.2) + stoplight (~> 2.1.3) streamio-ffmpeg (~> 3.0) strong_migrations tty-command diff --git a/app/controllers/admin/change_emails_controller.rb b/app/controllers/admin/change_emails_controller.rb new file mode 100644 index 000000000..a689d3a53 --- /dev/null +++ b/app/controllers/admin/change_emails_controller.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Admin + class ChangeEmailsController < BaseController + before_action :set_account + before_action :require_local_account! + + def show + authorize @user, :change_email? + end + + def update + authorize @user, :change_email? + + new_email = resource_params.fetch(:unconfirmed_email) + + if new_email != @user.email + @user.update!( + unconfirmed_email: new_email, + # Regenerate the confirmation token: + confirmation_token: nil + ) + + log_action :change_email, @user + + @user.send_confirmation_instructions + end + + redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.change_email.changed_msg') + end + + private + + def set_account + @account = Account.find(params[:account_id]) + @user = @account.user + end + + def require_local_account! + redirect_to admin_account_path(@account.id) unless @account.local? && @account.user.present? + end + + def resource_params + params.require(:user).permit( + :unconfirmed_email + ) + end + end +end diff --git a/app/controllers/admin/report_notes_controller.rb b/app/controllers/admin/report_notes_controller.rb index ef8c0f469..bcb3f2026 100644 --- a/app/controllers/admin/report_notes_controller.rb +++ b/app/controllers/admin/report_notes_controller.rb @@ -8,19 +8,26 @@ module Admin authorize ReportNote, :create? @report_note = current_account.report_notes.new(resource_params) + @report = @report_note.report if @report_note.save if params[:create_and_resolve] - @report_note.report.update!(action_taken: true, action_taken_by_account_id: current_account.id) - log_action :resolve, @report_note.report + @report.resolve!(current_account) + log_action :resolve, @report redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg') - else - redirect_to admin_report_path(@report_note.report_id), notice: I18n.t('admin.report_notes.created_msg') + return end + + if params[:create_and_unresolve] + @report.unresolve! + log_action :reopen, @report + end + + redirect_to admin_report_path(@report), notice: I18n.t('admin.report_notes.created_msg') else - @report = @report_note.report @report_notes = @report.notes.latest + @report_history = @report.history @form = Form::StatusBatch.new render template: 'admin/reports/show' diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index fc3785e3b..a4ae9507d 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -13,6 +13,7 @@ module Admin authorize @report, :show? @report_note = @report.notes.new @report_notes = @report.notes.latest + @report_history = @report.history @form = Form::StatusBatch.new end @@ -38,36 +39,33 @@ module Admin @report.update!(assigned_account_id: nil) log_action :unassigned, @report when 'reopen' - @report.update!(action_taken: false, action_taken_by_account_id: nil) + @report.unresolve! log_action :reopen, @report when 'resolve' - @report.update!(action_taken_by_current_attributes) + @report.resolve!(current_account) log_action :resolve, @report when 'suspend' Admin::SuspensionWorker.perform_async(@report.target_account.id) + log_action :resolve, @report log_action :suspend, @report.target_account + resolve_all_target_account_reports - @report.reload when 'silence' @report.target_account.update!(silenced: true) + log_action :resolve, @report log_action :silence, @report.target_account + resolve_all_target_account_reports - @report.reload else raise ActiveRecord::RecordNotFound end - end - - def action_taken_by_current_attributes - { action_taken: true, action_taken_by_account_id: current_account.id } + @report.reload end def resolve_all_target_account_reports - unresolved_reports_for_target_account.update_all( - action_taken_by_current_attributes - ) + unresolved_reports_for_target_account.update_all(action_taken: true, action_taken_by_account_id: current_account.id) end def unresolved_reports_for_target_account diff --git a/app/controllers/admin/statuses_controller.rb b/app/controllers/admin/statuses_controller.rb index 5d4325f57..d5787acfb 100644 --- a/app/controllers/admin/statuses_controller.rb +++ b/app/controllers/admin/statuses_controller.rb @@ -12,7 +12,7 @@ module Admin def index authorize :status, :index? - @statuses = @account.statuses + @statuses = @account.statuses.where(visibility: [:public, :unlisted]) if params[:media] account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).distinct diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb index 68af22529..062d490a7 100644 --- a/app/controllers/api/v1/accounts/credentials_controller.rb +++ b/app/controllers/api/v1/accounts/credentials_controller.rb @@ -13,6 +13,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController def update @account = current_account UpdateAccountService.new.call(@account, account_params, raise_error: true) + UserSettingsDecorator.new(current_user).update(user_settings_params) if user_settings_params ActivityPub::UpdateDistributionWorker.perform_async(@account.id) render json: @account, serializer: REST::CredentialAccountSerializer end @@ -22,4 +23,15 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController def account_params params.permit(:display_name, :note, :avatar, :header, :locked) end + + def user_settings_params + return nil unless params.key?(:source) + + source_params = params.require(:source) + + { + 'setting_default_privacy' => source_params.fetch(:privacy, @account.user.setting_default_privacy), + 'setting_default_sensitive' => source_params.fetch(:sensitive, @account.user.setting_default_sensitive), + } + end end diff --git a/app/controllers/concerns/remote_account_controller_concern.rb b/app/controllers/concerns/remote_account_controller_concern.rb new file mode 100644 index 000000000..e17910642 --- /dev/null +++ b/app/controllers/concerns/remote_account_controller_concern.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module RemoteAccountControllerConcern + extend ActiveSupport::Concern + + included do + layout 'public' + before_action :set_account + before_action :check_account_suspension + end + + private + + def set_account + @account = Account.find_remote!(params[:acct]) + end + + def check_account_suspension + gone if @account.suspended? + end +end diff --git a/app/controllers/remote_unfollows.rb b/app/controllers/remote_unfollows.rb new file mode 100644 index 000000000..af5943363 --- /dev/null +++ b/app/controllers/remote_unfollows.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +class RemoteUnfollowsController < ApplicationController + layout 'modal' + + before_action :authenticate_user! + before_action :set_body_classes + + def create + @account = unfollow_attempt.try(:target_account) + + if @account.nil? + render :error + else + render :success + end + rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError + render :error + end + + private + + def unfollow_attempt + username, domain = acct_without_prefix.split('@') + UnfollowService.new.call(current_account, Account.find_remote!(username, domain)) + end + + def acct_without_prefix + acct_params.gsub(/\Aacct:/, '') + end + + def acct_params + params.fetch(:acct, '') + end + + def set_body_classes + @body_classes = 'modal-layout' + end +end diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb index 7c26c0b05..4c663211e 100644 --- a/app/helpers/admin/action_logs_helper.rb +++ b/app/helpers/admin/action_logs_helper.rb @@ -45,6 +45,8 @@ module Admin::ActionLogsHelper log.recorded_changes.slice('domain', 'visible_in_picker') elsif log.target_type == 'User' && [:promote, :demote].include?(log.action) log.recorded_changes.slice('moderator', 'admin') + elsif log.target_type == 'User' && [:change_email].include?(log.action) + log.recorded_changes.slice('email', 'unconfirmed_email') elsif log.target_type == 'DomainBlock' log.recorded_changes.slice('severity', 'reject_media') elsif log.target_type == 'Status' && log.action == :update @@ -84,7 +86,7 @@ module Admin::ActionLogsHelper 'positive' when :create opposite_verbs?(log) ? 'negative' : 'positive' - when :update, :reset_password, :disable_2fa, :memorialize + when :update, :reset_password, :disable_2fa, :memorialize, :change_email 'neutral' when :demote, :silence, :disable, :suspend, :remove_avatar, :reopen 'negative' diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js index ed8094e78..684cd797b 100644 --- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js +++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.js @@ -35,9 +35,9 @@ export default class DetailedStatus extends ImmutablePureComponent { e.stopPropagation(); } - // handleOpenVideo = startTime => { - // this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), startTime); - // } + handleOpenVideo = startTime => { + this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), startTime); + } render () { const status = this.props.status.get('reblog') ? this.props.status.get('reblog') : this.props.status; @@ -53,13 +53,15 @@ export default class DetailedStatus extends ImmutablePureComponent { if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { media = <AttachmentList media={status.get('media_attachments')} />; } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { + const video = status.getIn(['media_attachments', 0]); media = ( <Video + preview={video.get('preview_url')} + src={video.get('url')} sensitive={status.get('sensitive')} - media={status.getIn(['media_attachments', 0])} letterbox={settings.getIn(['media', 'letterbox'])} fullwidth={settings.getIn(['media', 'fullwidth'])} - onOpenVideo={this.props.onOpenVideo} + onOpenVideo={this.handleOpenVideo} autoplay /> ); diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index f9245e134..3146a343d 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -135,6 +135,11 @@ border: 0; background: transparent; border-bottom: 1px solid $ui-base-color; + + &.section-break { + margin: 30px 0; + border-bottom: 2px solid $ui-base-lighter-color; + } } .muted-hint { @@ -336,6 +341,36 @@ } } +.report-note__comment { + margin-bottom: 20px; +} + +.report-note__form { + margin-bottom: 20px; + + .report-note__textarea { + box-sizing: border-box; + border: 0; + padding: 7px 4px; + margin-bottom: 10px; + font-size: 16px; + color: $ui-base-color; + display: block; + width: 100%; + outline: 0; + font-family: inherit; + resize: vertical; + } + + .report-note__buttons { + text-align: right; + } + + .report-note__button { + margin: 0 0 5px 5px; + } +} + .batch-form-box { display: flex; flex-wrap: wrap; diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js index 28ae56763..c9e4afcfc 100644 --- a/app/javascript/mastodon/actions/accounts.js +++ b/app/javascript/mastodon/actions/accounts.js @@ -1,5 +1,5 @@ import api, { getLinks } from '../api'; -import asyncDB from '../storage/db'; +import openDB from '../storage/db'; import { importAccount, importFetchedAccount, importFetchedAccounts } from './importer'; export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST'; @@ -94,12 +94,15 @@ export function fetchAccount(id) { dispatch(fetchAccountRequest(id)); - asyncDB.then(db => getFromDB( + openDB().then(db => getFromDB( dispatch, getState, db.transaction('accounts', 'read').objectStore('accounts').index('id'), id - )).catch(() => api(getState).get(`/api/v1/accounts/${id}`).then(response => { + ).then(() => db.close(), error => { + db.close(); + throw error; + })).catch(() => api(getState).get(`/api/v1/accounts/${id}`).then(response => { dispatch(importFetchedAccount(response.data)); })).then(() => { dispatch(fetchAccountSuccess()); diff --git a/app/javascript/mastodon/actions/custom_emojis.js b/app/javascript/mastodon/actions/custom_emojis.js new file mode 100644 index 000000000..aa37bc423 --- /dev/null +++ b/app/javascript/mastodon/actions/custom_emojis.js @@ -0,0 +1,37 @@ +import api from '../api'; + +export const CUSTOM_EMOJIS_FETCH_REQUEST = 'CUSTOM_EMOJIS_FETCH_REQUEST'; +export const CUSTOM_EMOJIS_FETCH_SUCCESS = 'CUSTOM_EMOJIS_FETCH_SUCCESS'; +export const CUSTOM_EMOJIS_FETCH_FAIL = 'CUSTOM_EMOJIS_FETCH_FAIL'; + +export function fetchCustomEmojis() { + return (dispatch, getState) => { + dispatch(fetchCustomEmojisRequest()); + + api(getState).get('/api/v1/custom_emojis').then(response => { + dispatch(fetchCustomEmojisSuccess(response.data)); + }).catch(error => { + dispatch(fetchCustomEmojisFail(error)); + }); + }; +}; + +export function fetchCustomEmojisRequest() { + return { + type: CUSTOM_EMOJIS_FETCH_REQUEST, + }; +}; + +export function fetchCustomEmojisSuccess(custom_emojis) { + return { + type: CUSTOM_EMOJIS_FETCH_SUCCESS, + custom_emojis, + }; +}; + +export function fetchCustomEmojisFail(error) { + return { + type: CUSTOM_EMOJIS_FETCH_FAIL, + error, + }; +}; diff --git a/app/javascript/mastodon/actions/importer/index.js b/app/javascript/mastodon/actions/importer/index.js index e671d417c..5b18cbc1d 100644 --- a/app/javascript/mastodon/actions/importer/index.js +++ b/app/javascript/mastodon/actions/importer/index.js @@ -1,3 +1,4 @@ +import { autoPlayGif } from '../../initial_state'; import { putAccounts, putStatuses } from '../../storage/modifier'; import { normalizeAccount, normalizeStatus } from './normalizer'; @@ -44,7 +45,7 @@ export function importFetchedAccounts(accounts) { } accounts.forEach(processAccount); - putAccounts(normalAccounts); + putAccounts(normalAccounts, !autoPlayGif); return importAccounts(normalAccounts); } diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index d28aef880..849cb4f5a 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -1,5 +1,5 @@ import api from '../api'; -import asyncDB from '../storage/db'; +import openDB from '../storage/db'; import { evictStatus } from '../storage/modifier'; import { deleteFromTimelines } from './timelines'; @@ -92,12 +92,17 @@ export function fetchStatus(id) { dispatch(fetchStatusRequest(id, skipLoading)); - asyncDB.then(db => { + openDB().then(db => { const transaction = db.transaction(['accounts', 'statuses'], 'read'); const accountIndex = transaction.objectStore('accounts').index('id'); const index = transaction.objectStore('statuses').index('id'); - return getFromDB(dispatch, getState, accountIndex, index, id); + return getFromDB(dispatch, getState, accountIndex, index, id).then(() => { + db.close(); + }, error => { + db.close(); + throw error; + }); }).then(() => { dispatch(fetchStatusSuccess(skipLoading)); }, () => api(getState).get(`/api/v1/statuses/${id}`).then(response => { diff --git a/app/javascript/mastodon/components/load_gap.js b/app/javascript/mastodon/components/load_gap.js new file mode 100644 index 000000000..012303ae1 --- /dev/null +++ b/app/javascript/mastodon/components/load_gap.js @@ -0,0 +1,33 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { injectIntl, defineMessages } from 'react-intl'; + +const messages = defineMessages({ + load_more: { id: 'status.load_more', defaultMessage: 'Load more' }, +}); + +@injectIntl +export default class LoadGap extends React.PureComponent { + + static propTypes = { + disabled: PropTypes.bool, + maxId: PropTypes.string, + onClick: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + }; + + handleClick = () => { + this.props.onClick(this.props.maxId); + } + + render () { + const { disabled, intl } = this.props; + + return ( + <button className='load-more load-gap' disabled={disabled} onClick={this.handleClick} aria-label={intl.formatMessage(messages.load_more)}> + <i className='fa fa-ellipsis-h' /> + </button> + ); + } + +} diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index a918a94f8..6129b3f1e 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -31,6 +31,8 @@ export default class Status extends ImmutablePureComponent { onFavourite: PropTypes.func, onReblog: PropTypes.func, onDelete: PropTypes.func, + onDirect: PropTypes.func, + onMention: PropTypes.func, onPin: PropTypes.func, onOpenMedia: PropTypes.func, onOpenVideo: PropTypes.func, diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js index e036dc1da..10f34b0c7 100644 --- a/app/javascript/mastodon/components/status_action_bar.js +++ b/app/javascript/mastodon/components/status_action_bar.js @@ -9,6 +9,7 @@ import { me } from '../initial_state'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, + direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, block: { id: 'account.block', defaultMessage: 'Block @{name}' }, @@ -41,6 +42,7 @@ export default class StatusActionBar extends ImmutablePureComponent { onFavourite: PropTypes.func, onReblog: PropTypes.func, onDelete: PropTypes.func, + onDirect: PropTypes.func, onMention: PropTypes.func, onMute: PropTypes.func, onBlock: PropTypes.func, @@ -92,6 +94,10 @@ export default class StatusActionBar extends ImmutablePureComponent { this.props.onMention(this.props.status.get('account'), this.context.router.history); } + handleDirectClick = () => { + this.props.onDirect(this.props.status.get('account'), this.context.router.history); + } + handleMuteClick = () => { this.props.onMute(this.props.status.get('account')); } @@ -149,6 +155,7 @@ export default class StatusActionBar extends ImmutablePureComponent { menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); } else { menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick }); + menu.push({ text: intl.formatMessage(messages.direct, { name: status.getIn(['account', 'username']) }), action: this.handleDirectClick }); menu.push(null); menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick }); menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick }); diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js index 8c2673f30..c98d4564e 100644 --- a/app/javascript/mastodon/components/status_list.js +++ b/app/javascript/mastodon/components/status_list.js @@ -4,28 +4,10 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import StatusContainer from '../containers/status_container'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import LoadMore from './load_more'; +import LoadGap from './load_gap'; import ScrollableList from './scrollable_list'; import { FormattedMessage } from 'react-intl'; -class LoadGap extends ImmutablePureComponent { - - static propTypes = { - disabled: PropTypes.bool, - maxId: PropTypes.string, - onClick: PropTypes.func.isRequired, - }; - - handleClick = () => { - this.props.onClick(this.props.maxId); - } - - render () { - return <LoadMore onClick={this.handleClick} disabled={this.props.disabled} />; - } - -} - export default class StatusList extends ImmutablePureComponent { static propTypes = { diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js index d1710445b..b29898d3b 100644 --- a/app/javascript/mastodon/containers/mastodon.js +++ b/app/javascript/mastodon/containers/mastodon.js @@ -6,6 +6,7 @@ import { showOnboardingOnce } from '../actions/onboarding'; import { BrowserRouter, Route } from 'react-router-dom'; import { ScrollContext } from 'react-router-scroll-4'; import UI from '../features/ui'; +import { fetchCustomEmojis } from '../actions/custom_emojis'; import { hydrateStore } from '../actions/store'; import { connectUserStream } from '../actions/streaming'; import { IntlProvider, addLocaleData } from 'react-intl'; @@ -19,6 +20,9 @@ export const store = configureStore(); const hydrateAction = hydrateStore(initialState); store.dispatch(hydrateAction); +// load custom emojis +store.dispatch(fetchCustomEmojis()); + export default class Mastodon extends React.PureComponent { static propTypes = { diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js index 4579bd132..f22509edf 100644 --- a/app/javascript/mastodon/containers/status_container.js +++ b/app/javascript/mastodon/containers/status_container.js @@ -5,6 +5,7 @@ import { makeGetStatus } from '../selectors'; import { replyCompose, mentionCompose, + directCompose, } from '../actions/compose'; import { reblog, @@ -102,6 +103,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } }, + onDirect (account, router) { + dispatch(directCompose(account, router)); + }, + onMention (account, router) { dispatch(mentionCompose(account, router)); }, diff --git a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js index e6a535a5d..5ec937a39 100644 --- a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js @@ -38,7 +38,8 @@ const getFrequentlyUsedEmojis = createSelector([ .toArray(); if (emojis.length < DEFAULTS.length) { - emojis = emojis.concat(DEFAULTS.slice(0, DEFAULTS.length - emojis.length)); + let uniqueDefaults = DEFAULTS.filter(emoji => !emojis.includes(emoji)); + emojis = emojis.concat(uniqueDefaults.slice(0, DEFAULTS.length - emojis.length)); } return emojis; diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js index d5cd854db..67f0e7981 100644 --- a/app/javascript/mastodon/features/compose/index.js +++ b/app/javascript/mastodon/features/compose/index.js @@ -24,9 +24,9 @@ const messages = defineMessages({ logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }, }); -const mapStateToProps = state => ({ +const mapStateToProps = (state, ownProps) => ({ columns: state.getIn(['settings', 'columns']), - showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']), + showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage, }); @connect(mapStateToProps) @@ -38,6 +38,7 @@ export default class Compose extends React.PureComponent { columns: ImmutablePropTypes.list.isRequired, multiColumn: PropTypes.bool, showSearch: PropTypes.bool, + isSearchPage: PropTypes.bool, intl: PropTypes.object.isRequired, }; @@ -58,7 +59,7 @@ export default class Compose extends React.PureComponent { } render () { - const { multiColumn, showSearch, intl } = this.props; + const { multiColumn, showSearch, isSearchPage, intl } = this.props; let header = ''; @@ -89,7 +90,7 @@ export default class Compose extends React.PureComponent { <div className='drawer'> {header} - <SearchContainer /> + {(multiColumn || isSearchPage) && <SearchContainer /> } <div className='drawer__pager'> <div className='drawer__inner' onFocus={this.onFocus}> @@ -102,7 +103,7 @@ export default class Compose extends React.PureComponent { )} </div> - <Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}> + <Motion defaultStyle={{ x: isSearchPage ? 0 : -100 }} style={{ x: spring(showSearch || isSearchPage ? 0 : -100, { stiffness: 210, damping: 20 }) }}> {({ x }) => ( <div className='drawer__inner darker' style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}> <SearchResultsContainer /> diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js index 9a6fb45c8..94a46b833 100644 --- a/app/javascript/mastodon/features/notifications/index.js +++ b/app/javascript/mastodon/features/notifications/index.js @@ -13,7 +13,7 @@ import { createSelector } from 'reselect'; import { List as ImmutableList } from 'immutable'; import { debounce } from 'lodash'; import ScrollableList from '../../components/scrollable_list'; -import LoadMore from '../../components/load_more'; +import LoadGap from '../../components/load_gap'; const messages = defineMessages({ title: { id: 'column.notifications', defaultMessage: 'Notifications' }, @@ -24,24 +24,6 @@ const getNotifications = createSelector([ state => state.getIn(['notifications', 'items']), ], (excludedTypes, notifications) => notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type')))); -class LoadGap extends React.PureComponent { - - static propTypes = { - disabled: PropTypes.bool, - maxId: PropTypes.string, - onClick: PropTypes.func.isRequired, - }; - - handleClick = () => { - this.props.onClick(this.props.maxId); - } - - render () { - return <LoadMore onClick={this.handleClick} disabled={this.props.disabled} />; - } - -} - const mapStateToProps = state => ({ notifications: getNotifications(state), isLoading: state.getIn(['notifications', 'isLoading'], true), diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js index 13cc10c9c..4aa6b08f2 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.js +++ b/app/javascript/mastodon/features/status/components/action_bar.js @@ -8,6 +8,7 @@ import { me } from '../../../initial_state'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, + direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, reply: { id: 'status.reply', defaultMessage: 'Reply' }, reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, @@ -37,6 +38,7 @@ export default class ActionBar extends React.PureComponent { onReblog: PropTypes.func.isRequired, onFavourite: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, + onDirect: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, onMute: PropTypes.func, onMuteConversation: PropTypes.func, @@ -63,6 +65,10 @@ export default class ActionBar extends React.PureComponent { this.props.onDelete(this.props.status); } + handleDirectClick = () => { + this.props.onDirect(this.props.status.get('account'), this.context.router.history); + } + handleMentionClick = () => { this.props.onMention(this.props.status.get('account'), this.context.router.history); } @@ -108,6 +114,7 @@ export default class ActionBar extends React.PureComponent { if (publicStatus) { menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed }); + menu.push(null); } if (me === status.getIn(['account', 'id'])) { @@ -121,6 +128,7 @@ export default class ActionBar extends React.PureComponent { menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); } else { menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick }); + menu.push({ text: intl.formatMessage(messages.direct, { name: status.getIn(['account', 'username']) }), action: this.handleDirectClick }); menu.push(null); menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick }); menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick }); diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index 2f482b292..55eff0823 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -19,6 +19,7 @@ import { import { replyCompose, mentionCompose, + directCompose, } from '../../actions/compose'; import { blockAccount } from '../../actions/accounts'; import { @@ -148,6 +149,10 @@ export default class Status extends ImmutablePureComponent { } } + handleDirectClick = (account, router) => { + this.props.dispatch(directCompose(account, router)); + } + handleMentionClick = (account, router) => { this.props.dispatch(mentionCompose(account, router)); } @@ -379,6 +384,7 @@ export default class Status extends ImmutablePureComponent { onFavourite={this.handleFavouriteClick} onReblog={this.handleReblogClick} onDelete={this.handleDeleteClick} + onDirect={this.handleDirectClick} onMention={this.handleMentionClick} onMute={this.handleMuteClick} onMuteConversation={this.handleConversationMuteClick} diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js index dba3be98b..ed6de6f39 100644 --- a/app/javascript/mastodon/features/ui/components/tabs_bar.js +++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js @@ -8,6 +8,7 @@ import { isUserTouching } from '../../../is_mobile'; export const links = [ <NavLink className='tabs-bar__link primary' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><i className='fa fa-fw fa-home' /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>, <NavLink className='tabs-bar__link primary' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><i className='fa fa-fw fa-bell' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>, + <NavLink className='tabs-bar__link primary' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><i className='fa fa-fw fa-search' /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>, <NavLink className='tabs-bar__link secondary' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><i className='fa fa-fw fa-users' /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>, <NavLink className='tabs-bar__link secondary' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><i className='fa fa-fw fa-globe' /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>, diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 8894eb4e6..8b905fa1d 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -146,6 +146,8 @@ class SwitchingColumnsArea extends React.PureComponent { <WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} /> <WrappedRoute path='/pinned' component={PinnedStatuses} content={children} /> + <WrappedRoute path='/search' component={Compose} content={children} componentParams={{ isSearchPage: true }} /> + <WrappedRoute path='/statuses/new' component={Compose} content={children} /> <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} /> <WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} /> diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index dd249adf1..6f81db13e 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -198,6 +198,10 @@ "id": "status.delete" }, { + "defaultMessage": "Direct message @{name}", + "id": "status.direct" + }, + { "defaultMessage": "Mention @{name}", "id": "status.mention" }, @@ -1371,6 +1375,10 @@ "id": "status.delete" }, { + "defaultMessage": "Direct message @{name}", + "id": "status.direct" + }, + { "defaultMessage": "Mention @{name}", "id": "status.mention" }, @@ -1731,6 +1739,10 @@ "id": "tabs_bar.notifications" }, { + "defaultMessage": "Search", + "id": "tabs_bar.search" + }, + { "defaultMessage": "Local", "id": "tabs_bar.local_timeline" }, diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index afc0fce3d..4802ddfd1 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -247,6 +247,7 @@ "status.block": "Block @{name}", "status.cannot_reblog": "This post cannot be boosted", "status.delete": "Delete", + "status.direct": "Direct message @{name}", "status.embed": "Embed", "status.favourite": "Favourite", "status.load_more": "Load more", @@ -276,6 +277,7 @@ "tabs_bar.home": "Home", "tabs_bar.local_timeline": "Local", "tabs_bar.notifications": "Notifications", + "tabs_bar.search": "Search", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Drag & drop to upload", "upload_button.label": "Add media", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index c0877262f..82b7070b8 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -276,6 +276,7 @@ "tabs_bar.home": "Strona główna", "tabs_bar.local_timeline": "Lokalne", "tabs_bar.notifications": "Powiadomienia", + "tabs_bar.search": "Szukaj", "ui.beforeunload": "Utracisz tworzony wpis, jeżeli opuścisz Mastodona.", "upload_area.title": "Przeciągnij i upuść aby wysłać", "upload_button.label": "Dodaj zawartość multimedialną", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index b056ec8bd..4cd2e0643 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -189,7 +189,7 @@ "onboarding.page_one.federation": "Mastodon é uma rede de servidores independentes que se juntam para fazer uma grande rede social. Nós chamamos estes servidores de instâncias.", "onboarding.page_one.full_handle": "Seu nome de usuário completo", "onboarding.page_one.handle_hint": "Isso é o que você diz aos seus amigos para que eles possam te mandar mensagens ou te seguir a partir de outra instância.", - "onboarding.page_one.welcome": "Seja bem-vindo(a) ao Mastodon!", + "onboarding.page_one.welcome": "Boas-vindas ao Mastodon!", "onboarding.page_six.admin": "O administrador de sua instância é {admin}.", "onboarding.page_six.almost_done": "Quase acabando...", "onboarding.page_six.appetoot": "Bom Apetoot!", diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json index 65983000c..7a404eaba 100644 --- a/app/javascript/mastodon/locales/pt.json +++ b/app/javascript/mastodon/locales/pt.json @@ -189,7 +189,7 @@ "onboarding.page_one.federation": "Mastodon é uma rede de servidores independentes ligados entre si para fazer uma grande rede social. Nós chamamos instâncias a estes servidores.", "onboarding.page_one.full_handle": "O teu nome de utilizador completo", "onboarding.page_one.handle_hint": "Isto é o que dizes aos teus amigos para pesquisar.", - "onboarding.page_one.welcome": "Bem-vindo(a) ao Mastodon!", + "onboarding.page_one.welcome": "Boas-vindas ao Mastodon!", "onboarding.page_six.admin": "O administrador da tua instância é {admin}.", "onboarding.page_six.almost_done": "Quase pronto...", "onboarding.page_six.appetoot": "Bon Appetoot!", diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 1f4177585..87049ea79 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -259,16 +259,18 @@ export default function compose(state = initialState, action) { case COMPOSE_UPLOAD_PROGRESS: return state.set('progress', Math.round((action.loaded / action.total) * 100)); case COMPOSE_MENTION: - return state - .update('text', text => `${text}@${action.account.get('acct')} `) - .set('focusDate', new Date()) - .set('idempotencyKey', uuid()); + return state.withMutations(map => { + map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' ')); + map.set('focusDate', new Date()); + map.set('idempotencyKey', uuid()); + }); case COMPOSE_DIRECT: - return state - .update('text', text => `@${action.account.get('acct')} `) - .set('privacy', 'direct') - .set('focusDate', new Date()) - .set('idempotencyKey', uuid()); + return state.withMutations(map => { + map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' ')); + map.set('privacy', 'direct'); + map.set('focusDate', new Date()); + map.set('idempotencyKey', uuid()); + }); case COMPOSE_SUGGESTIONS_CLEAR: return state.update('suggestions', ImmutableList(), list => list.clear()).set('suggestion_token', null); case COMPOSE_SUGGESTIONS_READY: diff --git a/app/javascript/mastodon/reducers/custom_emojis.js b/app/javascript/mastodon/reducers/custom_emojis.js index 307bcc7dc..d2c801ade 100644 --- a/app/javascript/mastodon/reducers/custom_emojis.js +++ b/app/javascript/mastodon/reducers/custom_emojis.js @@ -1,16 +1,15 @@ -import { List as ImmutableList } from 'immutable'; -import { STORE_HYDRATE } from '../actions/store'; +import { List as ImmutableList, fromJS as ConvertToImmutable } from 'immutable'; +import { CUSTOM_EMOJIS_FETCH_SUCCESS } from '../actions/custom_emojis'; import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light'; import { buildCustomEmojis } from '../features/emoji/emoji'; -const initialState = ImmutableList(); +const initialState = ImmutableList([]); export default function custom_emojis(state = initialState, action) { - switch(action.type) { - case STORE_HYDRATE: - emojiSearch('', { custom: buildCustomEmojis(action.state.get('custom_emojis', [])) }); - return action.state.get('custom_emojis'); - default: - return state; + if(action.type === CUSTOM_EMOJIS_FETCH_SUCCESS) { + state = ConvertToImmutable(action.custom_emojis); + emojiSearch('', { custom: buildCustomEmojis(state) }); } + + return state; }; diff --git a/app/javascript/mastodon/service_worker/entry.js b/app/javascript/mastodon/service_worker/entry.js index 160c3fbf2..ba54ae996 100644 --- a/app/javascript/mastodon/service_worker/entry.js +++ b/app/javascript/mastodon/service_worker/entry.js @@ -1,3 +1,4 @@ +import { freeStorage } from '../storage/modifier'; import './web_push_notifications'; function openSystemCache() { @@ -42,8 +43,10 @@ self.addEventListener('fetch', function(event) { event.respondWith(asyncResponse.then(async response => { if (response.ok || response.type === 'opaqueredirect') { - const cache = await asyncCache; - await cache.delete('/'); + await Promise.all([ + asyncCache.then(cache => cache.delete('/')), + indexedDB.deleteDatabase('mastodon'), + ]); } return response; @@ -56,7 +59,11 @@ self.addEventListener('fetch', function(event) { const fetched = await fetch(event.request); if (fetched.ok) { - await cache.put(event.request.url, fetched.clone()); + try { + await cache.put(event.request.url, fetched.clone()); + } finally { + freeStorage(); + } } return fetched; diff --git a/app/javascript/mastodon/storage/db.js b/app/javascript/mastodon/storage/db.js index e08fc3f3d..377a792a7 100644 --- a/app/javascript/mastodon/storage/db.js +++ b/app/javascript/mastodon/storage/db.js @@ -1,15 +1,14 @@ -import { me } from '../initial_state'; - -export default new Promise((resolve, reject) => { +export default () => new Promise((resolve, reject) => { + // ServiceWorker is required to synchronize the login state. // Microsoft Edge 17 does not support getAll according to: // Catalog of standard and vendor APIs across browsers - Microsoft Edge Development // https://developer.microsoft.com/en-us/microsoft-edge/platform/catalog/?q=specName%3Aindexeddb - if (!me || !('getAll' in IDBObjectStore.prototype)) { + if (!('caches' in self && 'getAll' in IDBObjectStore.prototype)) { reject(); return; } - const request = indexedDB.open('mastodon:' + me); + const request = indexedDB.open('mastodon'); request.onerror = reject; request.onsuccess = ({ target }) => resolve(target.result); diff --git a/app/javascript/mastodon/storage/modifier.js b/app/javascript/mastodon/storage/modifier.js index 4773d07a9..c2ed6f807 100644 --- a/app/javascript/mastodon/storage/modifier.js +++ b/app/javascript/mastodon/storage/modifier.js @@ -1,13 +1,14 @@ -import asyncDB from './db'; -import { autoPlayGif } from '../initial_state'; +import openDB from './db'; const accountAssetKeys = ['avatar', 'avatar_static', 'header', 'header_static']; -const avatarKey = autoPlayGif ? 'avatar' : 'avatar_static'; -const limit = 1024; +const storageMargin = 8388608; +const storeLimit = 1024; -// ServiceWorker and Cache API is not available on iOS 11 -// https://webkit.org/status/#specification-service-workers -const asyncCache = window.caches ? caches.open('mastodon-system') : Promise.reject(); +function openCache() { + // ServiceWorker and Cache API is not available on iOS 11 + // https://webkit.org/status/#specification-service-workers + return self.caches ? caches.open('mastodon-system') : Promise.reject(); +} function printErrorIfAvailable(error) { if (error) { @@ -16,7 +17,7 @@ function printErrorIfAvailable(error) { } function put(name, objects, onupdate, oncreate) { - return asyncDB.then(db => new Promise((resolve, reject) => { + return openDB().then(db => (new Promise((resolve, reject) => { const putTransaction = db.transaction(name, 'readwrite'); const putStore = putTransaction.objectStore(name); const putIndex = putStore.index('id'); @@ -53,7 +54,7 @@ function put(name, objects, onupdate, oncreate) { const count = readStore.count(); count.onsuccess = () => { - const excess = count.result - limit; + const excess = count.result - storeLimit; if (excess > 0) { const retrieval = readStore.getAll(null, excess); @@ -69,11 +70,17 @@ function put(name, objects, onupdate, oncreate) { }; putTransaction.onerror = reject; + })).then(resolved => { + db.close(); + return resolved; + }, error => { + db.close(); + throw error; })); } function evictAccountsByRecords(records) { - asyncDB.then(db => { + return openDB().then(db => { const transaction = db.transaction(['accounts', 'statuses'], 'readwrite'); const accounts = transaction.objectStore('accounts'); const accountsIdIndex = accounts.index('id'); @@ -83,7 +90,7 @@ function evictAccountsByRecords(records) { function evict(toEvict) { toEvict.forEach(record => { - asyncCache + openCache() .then(cache => accountAssetKeys.forEach(key => cache.delete(records[key]))) .catch(printErrorIfAvailable); @@ -98,6 +105,8 @@ function evictAccountsByRecords(records) { } evict(records); + + db.close(); }).catch(printErrorIfAvailable); } @@ -106,8 +115,9 @@ export function evictStatus(id) { } export function evictStatuses(ids) { - asyncDB.then(db => { - const store = db.transaction('statuses', 'readwrite').objectStore('statuses'); + return openDB().then(db => { + const transaction = db.transaction('statuses', 'readwrite'); + const store = transaction.objectStore('statuses'); const idIndex = store.index('id'); const reblogIndex = store.index('reblog'); @@ -118,14 +128,17 @@ export function evictStatuses(ids) { idIndex.getKey(id).onsuccess = ({ target }) => target.result && store.delete(target.result); }); + + db.close(); }).catch(printErrorIfAvailable); } function evictStatusesByRecords(records) { - evictStatuses(records.map(({ id }) => id)); + return evictStatuses(records.map(({ id }) => id)); } -export function putAccounts(records) { +export function putAccounts(records, avatarStatic) { + const avatarKey = avatarStatic ? 'avatar_static' : 'avatar'; const newURLs = []; put('accounts', records, (newRecord, oldKey, store, oncomplete) => { @@ -135,7 +148,7 @@ export function putAccounts(records) { const oldURL = target.result[key]; if (newURL !== oldURL) { - asyncCache + openCache() .then(cache => cache.delete(oldURL)) .catch(printErrorIfAvailable); } @@ -153,11 +166,12 @@ export function putAccounts(records) { }, (newRecord, oncomplete) => { newURLs.push(newRecord[avatarKey]); oncomplete(); - }).then(records => { - evictAccountsByRecords(records); - asyncCache - .then(cache => cache.addAll(newURLs)) - .catch(printErrorIfAvailable); + }).then(records => Promise.all([ + evictAccountsByRecords(records), + openCache().then(cache => cache.addAll(newURLs)), + ])).then(freeStorage, error => { + freeStorage(); + throw error; }).catch(printErrorIfAvailable); } @@ -166,3 +180,27 @@ export function putStatuses(records) { .then(evictStatusesByRecords) .catch(printErrorIfAvailable); } + +export function freeStorage() { + return navigator.storage.estimate().then(({ quota, usage }) => { + if (usage + storageMargin < quota) { + return null; + } + + return openDB().then(db => new Promise((resolve, reject) => { + const retrieval = db.transaction('accounts', 'readonly').objectStore('accounts').getAll(null, 1); + + retrieval.onsuccess = () => { + if (retrieval.result.length > 0) { + resolve(evictAccountsByRecords(retrieval.result).then(freeStorage)); + } else { + resolve(caches.delete('mastodon-system')); + } + }; + + retrieval.onerror = reject; + + db.close(); + })); + }); +} diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss index 03211036c..034c35e8a 100644 --- a/app/javascript/styles/mastodon/about.scss +++ b/app/javascript/styles/mastodon/about.scss @@ -322,6 +322,11 @@ $small-breakpoint: 960px; border: 0; border-bottom: 1px solid rgba($ui-base-lighter-color, .6); margin: 20px 0; + + &.spacer { + height: 1px; + border: 0; + } } .container-alt { diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index e6bd0c717..6bd659030 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -145,6 +145,11 @@ border: 0; background: transparent; border-bottom: 1px solid $ui-base-color; + + &.section-break { + margin: 30px 0; + border-bottom: 2px solid $ui-base-lighter-color; + } } .muted-hint { @@ -330,6 +335,36 @@ } } +.report-note__comment { + margin-bottom: 20px; +} + +.report-note__form { + margin-bottom: 20px; + + .report-note__textarea { + box-sizing: border-box; + border: 0; + padding: 7px 4px; + margin-bottom: 10px; + font-size: 16px; + color: $ui-base-color; + display: block; + width: 100%; + outline: 0; + font-family: inherit; + resize: vertical; + } + + .report-note__buttons { + text-align: right; + } + + .report-note__button { + margin: 0 0 5px 5px; + } +} + .batch-form-box { display: flex; flex-wrap: wrap; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index c82a760c4..94e3089f8 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2455,6 +2455,10 @@ a.status-card { } } +.load-gap { + border-bottom: 1px solid lighten($ui-base-color, 8%); +} + .regeneration-indicator { text-align: center; font-size: 16px; diff --git a/app/lib/activitypub/activity/delete.rb b/app/lib/activitypub/activity/delete.rb index 5fa60a81c..3474d55d9 100644 --- a/app/lib/activitypub/activity/delete.rb +++ b/app/lib/activitypub/activity/delete.rb @@ -17,21 +17,25 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity end def delete_note - status = Status.find_by(uri: object_uri, account: @account) - status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present? + @status = Status.find_by(uri: object_uri, account: @account) + @status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present? delete_later!(object_uri) - return if status.nil? + return if @status.nil? - forward_for_reblogs(status) - delete_now!(status) + if @status.public_visibility? || @status.unlisted_visibility? + forward_for_reply + forward_for_reblogs + end + + delete_now! end - def forward_for_reblogs(status) + def forward_for_reblogs return if @json['signature'].blank? - rebloggers_ids = status.reblogs.includes(:account).references(:account).merge(Account.local).pluck(:account_id) + rebloggers_ids = @status.reblogs.includes(:account).references(:account).merge(Account.local).pluck(:account_id) inboxes = Account.where(id: ::Follow.where(target_account_id: rebloggers_ids).select(:account_id)).inboxes - [@account.preferred_inbox_url] ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url| @@ -39,8 +43,22 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity end end - def delete_now!(status) - RemoveStatusService.new.call(status) + def replied_to_status + return @replied_to_status if defined?(@replied_to_status) + @replied_to_status = @status.thread + end + + def reply_to_local? + !replied_to_status.nil? && replied_to_status.account.local? + end + + def forward_for_reply + return unless @json['signature'].present? && reply_to_local? + ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), replied_to_status.account_id, [@account.preferred_inbox_url]) + end + + def delete_now! + RemoveStatusService.new.call(@status) end def payload diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index c7afdacc2..78b3aa77c 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -93,7 +93,7 @@ class UserSettingsDecorator end def boolean_cast_setting(key) - settings[key] == '1' + ActiveModel::Type::Boolean.new.cast(settings[key]) end def coerced_settings(key) @@ -101,7 +101,7 @@ class UserSettingsDecorator end def coerce_values(params_hash) - params_hash.transform_values { |x| x == '1' } + params_hash.transform_values { |x| ActiveModel::Type::Boolean.new.cast(x) } end def change?(key) diff --git a/app/models/account.rb b/app/models/account.rb index 79d5bf742..31f3d5253 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -126,6 +126,7 @@ class Account < ApplicationRecord scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) } delegate :email, + :unconfirmed_email, :current_sign_in_ip, :current_sign_in_at, :confirmed?, diff --git a/app/models/admin/action_log.rb b/app/models/admin/action_log.rb index c437c8ee8..81f278e07 100644 --- a/app/models/admin/action_log.rb +++ b/app/models/admin/action_log.rb @@ -35,6 +35,11 @@ class Admin::ActionLog < ApplicationRecord self.recorded_changes = target.attributes when :update, :promote, :demote self.recorded_changes = target.previous_changes + when :change_email + self.recorded_changes = ActiveSupport::HashWithIndifferentAccess.new( + email: [target.email, nil], + unconfirmed_email: [nil, target.unconfirmed_email] + ) end end end diff --git a/app/models/concerns/status_threading_concern.rb b/app/models/concerns/status_threading_concern.rb index 65f8e112e..b539ba10e 100644 --- a/app/models/concerns/status_threading_concern.rb +++ b/app/models/concerns/status_threading_concern.rb @@ -15,16 +15,12 @@ module StatusThreadingConcern def ancestor_ids Rails.cache.fetch("ancestors:#{id}") do - ancestors_without_self.pluck(:id) + ancestor_statuses.pluck(:id) end end - def ancestors_without_self - ancestor_statuses - [self] - end - def ancestor_statuses - Status.find_by_sql([<<-SQL.squish, id: id]) + Status.find_by_sql([<<-SQL.squish, id: in_reply_to_id]) WITH RECURSIVE search_tree(id, in_reply_to_id, path) AS ( SELECT id, in_reply_to_id, ARRAY[id] @@ -43,11 +39,7 @@ module StatusThreadingConcern end def descendant_ids - descendants_without_self.pluck(:id) - end - - def descendants_without_self - descendant_statuses - [self] + descendant_statuses.pluck(:id) end def descendant_statuses @@ -56,7 +48,7 @@ module StatusThreadingConcern AS ( SELECT id, ARRAY[id] FROM statuses - WHERE id = :id + WHERE in_reply_to_id = :id UNION ALL SELECT statuses.id, path || statuses.id FROM search_tree diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb index 476178e86..1ec21d1a0 100644 --- a/app/models/custom_emoji.rb +++ b/app/models/custom_emoji.rb @@ -58,5 +58,9 @@ class CustomEmoji < ApplicationRecord where(shortcode: shortcodes, domain: domain, disabled: false) end + + def search(shortcode) + where('"custom_emojis"."shortcode" ILIKE ?', "%#{shortcode}%") + end end end diff --git a/app/models/custom_emoji_filter.rb b/app/models/custom_emoji_filter.rb index 2c09ed65c..c4bc310bb 100644 --- a/app/models/custom_emoji_filter.rb +++ b/app/models/custom_emoji_filter.rb @@ -28,7 +28,7 @@ class CustomEmojiFilter when 'by_domain' CustomEmoji.where(domain: value) when 'shortcode' - CustomEmoji.where(shortcode: value) + CustomEmoji.search(value) else raise "Unknown filter: #{key}" end diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 49c24ac01..3b16944ce 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -150,8 +150,9 @@ class MediaAttachment < ApplicationRecord 'pix_fmt' => 'yuv420p', 'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'', 'vsync' => 'cfr', - 'b:v' => '1300K', - 'maxrate' => '500K', + 'c:v' => 'h264', + 'b:v' => '500K', + 'maxrate' => '1300K', 'bufsize' => '1300K', 'crf' => 18, }, diff --git a/app/models/report.rb b/app/models/report.rb index f5b37cb6d..5b90c7bce 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -39,4 +39,50 @@ class Report < ApplicationRecord def media_attachments MediaAttachment.where(status_id: status_ids) end + + def assign_to_self!(current_account) + update!(assigned_account_id: current_account.id) + end + + def unassign! + update!(assigned_account_id: nil) + end + + def resolve!(acting_account) + update!(action_taken: true, action_taken_by_account_id: acting_account.id) + end + + def unresolve! + update!(action_taken: false, action_taken_by_account_id: nil) + end + + def unresolved? + !action_taken? + end + + def history + time_range = created_at..updated_at + + sql = [ + Admin::ActionLog.where( + target_type: 'Report', + target_id: id, + created_at: time_range + ).unscope(:order), + + Admin::ActionLog.where( + target_type: 'Account', + target_id: target_account_id, + created_at: time_range + ).unscope(:order), + + Admin::ActionLog.where( + target_type: 'Status', + target_id: status_ids, + created_at: time_range + ).unscope(:order), + ].map { |query| "(#{query.to_sql})" }.join(' UNION ALL ') + + Admin::ActionLog.from("(#{sql}) AS admin_action_logs") + end end diff --git a/app/models/report_note.rb b/app/models/report_note.rb index 3d12cf7b6..6d9dec80a 100644 --- a/app/models/report_note.rb +++ b/app/models/report_note.rb @@ -13,7 +13,7 @@ class ReportNote < ApplicationRecord belongs_to :account - belongs_to :report, inverse_of: :notes + belongs_to :report, inverse_of: :notes, touch: true scope :latest, -> { reorder('created_at ASC') } diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index aae207d06..dabdf707a 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -5,6 +5,10 @@ class UserPolicy < ApplicationPolicy staff? && !record.staff? end + def change_email? + staff? && !record.staff? + end + def disable_2fa? admin? && !record.staff? end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 74b4cba0c..fe03c044c 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -28,7 +28,7 @@ class PostStatusService < BaseService status = account.statuses.create!(text: text, media_attachments: media || [], thread: in_reply_to, - sensitive: options[:sensitive], + sensitive: (options[:sensitive].nil? ? account.user&.setting_default_sensitive : options[:sensitive]), spoiler_text: options[:spoiler_text] || '', visibility: options[:visibility] || account.user&.setting_default_privacy, language: LanguageDetector.instance.detect(text, account), diff --git a/app/views/accounts/_follow_button.html.haml b/app/views/accounts/_follow_button.html.haml index e476e0aff..96ae23234 100644 --- a/app/views/accounts/_follow_button.html.haml +++ b/app/views/accounts/_follow_button.html.haml @@ -8,16 +8,16 @@ - if user_signed_in? && current_account.id != account.id && !requested .controls - if following - = link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do + = link_to (account.local? ? account_unfollow_path(account) : remote_unfollow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do = fa_icon 'user-times' = t('accounts.unfollow') - else - = link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do + = link_to (account.local? ? account_follow_path(account) : authorize_follow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do = fa_icon 'user-plus' = t('accounts.follow') - elsif !user_signed_in? .controls .remote-follow - = link_to account_remote_follow_path(account), class: 'icon-button' do + = link_to (account.local? ? account_remote_follow_path(account) : "web+mastodon://follow?uri=#{account.uri}"), class: 'icon-button' do = fa_icon 'user-plus' = t('accounts.remote_follow') diff --git a/app/views/accounts/_follow_grid.html.haml b/app/views/accounts/_follow_grid.html.haml index 10fbfa546..a6d0ee817 100644 --- a/app/views/accounts/_follow_grid.html.haml +++ b/app/views/accounts/_follow_grid.html.haml @@ -2,6 +2,6 @@ - if accounts.empty? = render partial: 'accounts/nothing_here' - else - = render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: true + = render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: !user_signed_in? = paginate follows diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index fecfd6cc8..7312618ee 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -36,9 +36,13 @@ %th= t('admin.accounts.email') %td = @account.user_email - - if @account.user_confirmed? = fa_icon('check') + = table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(@account.id) if can?(:change_email, @account.user) + - if @account.user_unconfirmed_email.present? + %th= t('admin.accounts.unconfirmed_email') + %td + = @account.user_unconfirmed_email %tr %th= t('admin.accounts.login_status') %td diff --git a/app/views/admin/change_emails/show.html.haml b/app/views/admin/change_emails/show.html.haml new file mode 100644 index 000000000..a661b1ad6 --- /dev/null +++ b/app/views/admin/change_emails/show.html.haml @@ -0,0 +1,7 @@ +- content_for :page_title do + = t('admin.accounts.change_email.title', username: @account.acct) + += simple_form_for @user, url: admin_account_change_email_path(@account.id) do |f| + = f.input :email, wrapper: :with_label, disabled: true, label: t('admin.accounts.change_email.current_email') + = f.input :unconfirmed_email, wrapper: :with_label, label: t('admin.accounts.change_email.new_email') + = f.button :submit, class: "button", value: t('admin.accounts.change_email.submit') diff --git a/app/views/admin/report_notes/_report_note.html.haml b/app/views/admin/report_notes/_report_note.html.haml index 60ac5d0d5..1f621e0d3 100644 --- a/app/views/admin/report_notes/_report_note.html.haml +++ b/app/views/admin/report_notes/_report_note.html.haml @@ -1,11 +1,9 @@ -%tr - %td - %p - %strong= report_note.account.acct - on +%li + %h4 + = report_note.account.acct + %div{ style: 'float: right' } %time.formatted{ datetime: report_note.created_at.iso8601, title: l(report_note.created_at) } = l report_note.created_at = table_link_to 'trash', t('admin.reports.notes.delete'), admin_report_note_path(report_note), method: :delete if can?(:destroy, report_note) - %br/ - %br/ + %div{ class: 'report-note__comment' } = simple_format(h(report_note.content)) diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 12a52eb33..a0c1ca283 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -2,7 +2,7 @@ = t('admin.reports.report', id: @report.id) %div{ style: 'overflow: hidden; margin-bottom: 20px' } - - if !@report.action_taken? + - if @report.unresolved? %div{ style: 'float: right' } = link_to t('admin.reports.silence_account'), admin_report_path(@report, outcome: 'silence'), method: :put, class: 'button' = link_to t('admin.reports.suspend_account'), admin_report_path(@report, outcome: 'suspend'), method: :put, class: 'button' @@ -15,21 +15,28 @@ %table.table.inline-table %tbody %tr + %th= t('admin.reports.created_at') + %td{colspan: 2} + %time.formatted{ datetime: @report.created_at.iso8601 } + %tr %th= t('admin.reports.updated_at') %td{colspan: 2} %time.formatted{ datetime: @report.updated_at.iso8601 } %tr %th= t('admin.reports.status') - %td{colspan: 2} + %td - if @report.action_taken? = t('admin.reports.resolved') - = table_link_to 'envelope-open', t('admin.reports.reopen'), admin_report_path(@report, outcome: 'reopen'), method: :put - else = t('admin.reports.unresolved') + %td{style: "text-align: right; overflow: hidden;"} + - if @report.action_taken? + = table_link_to 'envelope-open', t('admin.reports.reopen'), admin_report_path(@report, outcome: 'reopen'), method: :put - if !@report.action_taken_by_account.nil? %tr %th= t('admin.reports.action_taken_by') - %td= @report.action_taken_by_account.acct + %td{colspan: 2} + = @report.action_taken_by_account.acct - else %tr %th= t('admin.reports.assigned') @@ -44,6 +51,8 @@ - if !@report.assigned_account.nil? = table_link_to 'trash', t('admin.reports.unassign'), admin_report_path(@report, outcome: 'unassign'), method: :put +%hr{ class: "section-break"}/ + .report-accounts .report-accounts__item %h3= t('admin.reports.reported_account') @@ -85,22 +94,28 @@ = link_to admin_report_reported_status_path(@report, status), method: :delete, class: 'icon-button trash-button', title: t('admin.reports.delete'), data: { confirm: t('admin.reports.are_you_sure') }, remote: true do = fa_icon 'trash' -%hr/ +%hr{ class: "section-break"}/ %h3= t('admin.reports.notes.label') - if @report_notes.length > 0 - .table-wrapper - %table.table - %thead - %tr - %th - %tbody - = render @report_notes + %ul + = render @report_notes -= simple_form_for @report_note, url: admin_report_notes_path do |f| +%h4= t('admin.reports.notes.new_label') += form_for @report_note, url: admin_report_notes_path, html: { class: 'report-note__form' } do |f| = render 'shared/error_messages', object: @report_note - = f.input :content + = f.text_area :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6, class: 'report-note__textarea' = f.hidden_field :report_id - = f.button :button, t('admin.reports.notes.create'), type: :submit - = f.button :button, t('admin.reports.notes.create_and_resolve'), type: :submit, name: :create_and_resolve + %div{ class: 'report-note__buttons' } + - if @report.unresolved? + = f.submit t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, class: 'button report-note__button' + - else + = f.submit t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, class: 'button report-note__button' + = f.submit t('admin.reports.notes.create'), class: 'button report-note__button' + +- if @report_history.length > 0 + %h3= t('admin.reports.history') + + %ul + = render @report_history diff --git a/app/views/remote_unfollows/_card.html.haml b/app/views/remote_unfollows/_card.html.haml new file mode 100644 index 000000000..e81e292ba --- /dev/null +++ b/app/views/remote_unfollows/_card.html.haml @@ -0,0 +1,13 @@ +.account-card + .detailed-status__display-name + %div + = image_tag account.avatar.url(:original), alt: '', width: 48, height: 48, class: 'avatar' + + %span.display-name + - account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account) + = link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do + %strong.emojify= display_name(account) + %span @#{account.acct} + + - if account.note? + .account__header__content.emojify= Formatter.instance.simplified_format(account) diff --git a/app/views/remote_unfollows/_post_follow_actions.html.haml b/app/views/remote_unfollows/_post_follow_actions.html.haml new file mode 100644 index 000000000..2a9c062e9 --- /dev/null +++ b/app/views/remote_unfollows/_post_follow_actions.html.haml @@ -0,0 +1,4 @@ +.post-follow-actions + %div= link_to t('authorize_follow.post_follow.web'), web_url("accounts/#{@account.id}"), class: 'button button--block' + %div= link_to t('authorize_follow.post_follow.return'), TagManager.instance.url_for(@account), class: 'button button--block' + %div= t('authorize_follow.post_follow.close') diff --git a/app/views/remote_unfollows/error.html.haml b/app/views/remote_unfollows/error.html.haml new file mode 100644 index 000000000..cb63f02be --- /dev/null +++ b/app/views/remote_unfollows/error.html.haml @@ -0,0 +1,3 @@ +.form-container + .flash-message#error_explanation + = t('remote_unfollow.error') diff --git a/app/views/remote_unfollows/success.html.haml b/app/views/remote_unfollows/success.html.haml new file mode 100644 index 000000000..aa3c838a0 --- /dev/null +++ b/app/views/remote_unfollows/success.html.haml @@ -0,0 +1,10 @@ +- content_for :page_title do + = t('remote_unfollow.title', acct: @account.acct) + +.form-container + .follow-prompt + %h2= t('remote_unfollow.unfollowed') + + = render 'card', account: @account + + = render 'post_follow_actions' diff --git a/app/workers/activitypub/delivery_worker.rb b/app/workers/activitypub/delivery_worker.rb index e6cfd0d07..adffd1d3b 100644 --- a/app/workers/activitypub/delivery_worker.rb +++ b/app/workers/activitypub/delivery_worker.rb @@ -12,9 +12,7 @@ class ActivityPub::DeliveryWorker @source_account = Account.find(source_account_id) @inbox_url = inbox_url - perform_request do |response| - raise Mastodon::UnexpectedResponseError, response unless response_successful? response - end + perform_request failure_tracker.track_success! rescue => e @@ -30,8 +28,14 @@ class ActivityPub::DeliveryWorker request.add_headers(HEADERS) end - def perform_request(&block) - build_request.perform(&block) + def perform_request + light = Stoplight(@inbox_url) do + build_request.perform do |response| + raise Mastodon::UnexpectedResponseError, response unless response_successful?(response) + end + end + + light.run end def response_successful?(response) diff --git a/app/workers/scheduler/ip_cleanup_scheduler.rb b/app/workers/scheduler/ip_cleanup_scheduler.rb index 9f1593c91..a33ca031e 100644 --- a/app/workers/scheduler/ip_cleanup_scheduler.rb +++ b/app/workers/scheduler/ip_cleanup_scheduler.rb @@ -4,8 +4,10 @@ require 'sidekiq-scheduler' class Scheduler::IpCleanupScheduler include Sidekiq::Worker + RETENTION_PERIOD = 1.year + def perform - time_ago = 5.years.ago + time_ago = RETENTION_PERIOD.ago SessionActivation.where('updated_at < ?', time_ago).destroy_all User.where('last_sign_in_at < ?', time_ago).update_all(last_sign_in_ip: nil) end diff --git a/config/initializers/rack_attack_logging.rb b/config/initializers/rack_attack_logging.rb new file mode 100644 index 000000000..2ddbfb99c --- /dev/null +++ b/config/initializers/rack_attack_logging.rb @@ -0,0 +1,4 @@ +ActiveSupport::Notifications.subscribe('rack.attack') do |_name, _start, _finish, _request_id, req| + next unless [:throttle, :blacklist].include? req.env['rack.attack.match_type'] + Rails.logger.info("Rate limit hit (#{req.env['rack.attack.match_type']}): #{req.ip} #{req.request_method} #{req.fullpath}") +end diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index f875fbd95..05c804100 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -namespace = ENV.fetch('REDIS_NAMESPACE') { nil } +namespace = ENV.fetch('REDIS_NAMESPACE') { nil } redis_params = { url: ENV['REDIS_URL'] } if namespace - redis_params [:namespace] = namespace + redis_params[:namespace] = namespace end Sidekiq.configure_server do |config| @@ -18,3 +18,5 @@ end Sidekiq.configure_client do |config| config.redis = redis_params end + +Sidekiq::Logging.logger.level = ::Logger::const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s) diff --git a/config/initializers/stoplight.rb b/config/initializers/stoplight.rb new file mode 100644 index 000000000..1bd4ee6e7 --- /dev/null +++ b/config/initializers/stoplight.rb @@ -0,0 +1,3 @@ +require 'stoplight' + +Stoplight::Light.default_data_store = Stoplight::DataStore::Redis.new(Redis.current) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 3da3cbe90..61daddc66 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -665,74 +665,6 @@ ca: reblogged: ha impulsat sensitive_content: Contingut sensible terms: - body_html: | - <h2>Política de privacitat</h2> - - <h3 id="collect">Quina informació recollim?</h3> - - <p>Recopilem informació teva quan et registres en aquesta instància i recopilem dades quan participes en el fòrum llegint, escrivint i avaluant el contingut aquí compartit.</p> - - <p>En registrar-te en aquesta instància, se't pot demanar que introduexis el teu nom i l'adreça de correu electrònic. També pots visitar el nostre lloc sense registrar-te. La teva adreça de correu electrònic es verificarà mitjançant un correu electrònic que conté un enllaç únic. Si es visita aquest enllaç, sabem que controles l'adreça de correu electrònic.</p> - - <p>Quan es registra i publica, registrem l'adreça IP de la qual es va originar la publicació. També podrem conservar els registres del servidor que inclouen l'adreça IP de cada sol·licitud al nostre servidor.</p> - - <h3 id="use">Per a què utilitzem la teva informació?</h3> - - <p>Qualsevol de la informació que recopilem de tu pot utilitzar-se d'una de les maneres següents:</p> - - <ul> - <li>Per a personalitzar la teva experiència — la teva informació ens ajuda a respondre millor a les teves necessitats individuals.</li> - <li>Per millorar el nostre lloc — ens esforcem contínuament per millorar les nostres ofertes de llocs basats en la informació i els comentaris que rebem de tu.</li> - <li>Per millorar el servei al client — la teva informació ens ajuda a respondre més eficaçment a les teves sol·licituds de servei al client i a les necessitats de suport.</li> - <li>Per enviar correus electrònics periòdics — l'adreça electrònica que proporcionis es pot utilitzar per enviar-te informació, notificacions que sol·licitis sobre canvis en temes o en resposta al teu nom d'usuari, respondre a les consultes i/o altres sol·licituds o preguntes.</li> - </ul> - - <h3 id="protect">Com protegim la teva informació?</h3> - - <p>Implementem diverses mesures de seguretat per mantenir la seguretat de la teva informació personal quan introdueixes, envies o accedeixes a la teva informació personal.</p> - - <h3 id="data-retention">Quina és la nostre política de retenció de dades?</h3> - - <p>Farem un esforç de bona fe per a:</p> - - <ul> - <li>Conserva els registres de servidor que continguin l'adreça IP de totes les sol·licituds a aquest servidor no més de 90 dies.</li> - <li>Conserva les adreces IP associades als usuaris registrats i les seves publicacions no més de 5 anys.</li> - </ul> - - <h3 id="cookies">Utilitzem galetes?</h3> - - <p>Sí. Les cookies són fitxers petits que un lloc o el proveïdor de serveis transfereix al disc dur del vostre ordinador a través del navegador web (si ho permet). Aquestes galetes permeten al lloc reconèixer el vostre navegador i, si teniu un compte registrat, associar-lo al vostre compte registrat.</p> - - <p>Utilitzem cookies per comprendre i desar les vostres preferències per a futures visites i compilar dades agregades sobre el trànsit del lloc i la interacció del lloc, de manera que podrem oferir millors experiències i eines del lloc en el futur. Podem contractar amb proveïdors de serveis de tercers per ajudar-nos a comprendre millor els visitants del nostre lloc. Aquests proveïdors de serveis no estan autoritzats a utilitzar la informació recollida en nom nostre, excepte per ajudar-nos a dur a terme i millorar el nostre negoci.</p> - - <h3 id="disclose">Publiquem informació al exterior?</h3> - - <p>No venem, comercialitzem ni transmetem a tercers la vostra informació d'identificació personal. Això no inclou tercers de confiança que ens ajudin a operar el nostre lloc, a dur a terme el nostre negoci o a fer-ho, sempre que aquestes parts acceptin mantenir confidencial aquesta informació. També podem publicar la vostra informació quan creiem que l'alliberament és apropiat per complir amb la llei, fer complir les polítiques del nostre lloc o protegir els nostres drets o altres drets, propietat o seguretat. No obstant això, la informació de visitant que no sigui personalment identificable es pot proporcionar a altres parts per a la comercialització, la publicitat o altres usos.</p> - - <h3 id="third-party">Vincles de tercers</h3> - - <p>De tant en tant, segons el nostre criteri, podem incloure o oferir productes o serveis de tercers al nostre lloc. Aquests llocs de tercers tenen polítiques de privadesa separades i independents. Per tant, no tenim responsabilitat ni responsabilitat civil pel contingut i les activitats d'aquests llocs enllaçats. No obstant això, busquem protegir la integritat del nostre lloc i donem la benvinguda a qualsevol comentari sobre aquests llocs.</p> - - <h3 id="coppa">Compliment de la Llei de protecció de la privacitat en línia dels nens</h3> - - <p>El nostre lloc, productes i serveis estan dirigits a persones que tenen almenys 13 anys. Si aquest servidor es troba als EUA, i teniu menys de 13 anys, segons els requisits de COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) no feu servir aquest lloc.</p> - - <h3 id="online">Només la política de privacitat en línia</h3> - - <p>Aquesta política de privacitat en línia només s'aplica a la informació recopilada a través del nostre lloc i no a la informació recopilada fora de línia.</p> - - <h3 id="consent">El vostre consentiment</h3> - - <p>En utilitzar el nostre lloc, accepta la política de privadesa del nostre lloc web.</p> - - <h3 id="changes">Canvis a la nostra política de privacitat</h3> - - <p>Si decidim canviar la nostra política de privadesa, publicarem aquests canvis en aquesta pàgina.</p> - - <p>Aquest document és CC-BY-SA. Es va actualitzar per última vegada el 31 de maig de 2013.</p> - - <p>Originalment adaptat a la <a href="https://github.com/discourse/discourse">política de privadesa del Discurs</a>.</p> title: "%{instance} Condicions del servei i política de privadesa" time: formats: diff --git a/config/locales/en.yml b/config/locales/en.yml index 9e24fd8a1..65ae9182f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -63,6 +63,13 @@ en: are_you_sure: Are you sure? avatar: Avatar by_domain: Domain + change_email: + changed_msg: Account email successfully changed! + current_email: Current Email + label: Change Email + new_email: New Email + submit: Change Email + title: Change Email for %{username} confirm: Confirm confirmed: Confirmed demote: Demote @@ -131,6 +138,7 @@ en: statuses: Statuses subscribe: Subscribe title: Accounts + unconfirmed_email: Unconfirmed E-mail undo_silenced: Undo silence undo_suspension: Undo suspension unsubscribe: Unsubscribe @@ -139,6 +147,7 @@ en: action_logs: actions: assigned_to_self_report: "%{name} assigned report %{target} to themselves" + change_email_user: "%{name} changed the e-mail address of user %{target}" confirm_user: "%{name} confirmed e-mail address of user %{target}" create_custom_emoji: "%{name} uploaded new emoji %{target}" create_domain_block: "%{name} blocked domain %{target}" @@ -247,8 +256,8 @@ en: title: Filter title: Invites report_notes: - created_msg: Moderation note successfully created! - destroyed_msg: Moderation note successfully destroyed! + created_msg: Report note successfully created! + destroyed_msg: Report note successfully deleted! reports: action_taken_by: Action taken by are_you_sure: Are you sure? @@ -257,15 +266,20 @@ en: comment: label: Report Comment none: None + created_at: Reported delete: Delete + history: Moderation History id: ID mark_as_resolved: Mark as resolved mark_as_unresolved: Mark as unresolved notes: create: Add Note create_and_resolve: Resolve with Note + create_and_unresolve: Reopen with Note delete: Delete - label: Notes + label: Moderator Notes + new_label: Add Moderator Note + placeholder: Describe what actions have been taken, or any other updates to this report… nsfw: 'false': Unhide media attachments 'true': Hide media attachments @@ -702,70 +716,79 @@ en: terms: body_html: | <h2>Privacy Policy</h2> - <h3 id="collect">What information do we collect?</h3> - <p>We collect information from you when you register on our site and gather data when you participate in the forum by reading, writing, and evaluating the content shared here.</p> - - <p>When registering on our site, you may be asked to enter your name and e-mail address. You may, however, visit our site without registering. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address.</p> + <ul> + <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li> + <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li> + <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li> + <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li> + </ul> - <p>When registered and posting, we record the IP address that the post originated from. We also may retain server logs which include the IP address of every request to our server.</p> + <hr class="spacer" /> <h3 id="use">What do we use your information for?</h3> - <p>Any of the information we collect from you may be used in one of the following ways:</p> + <p>Any of the information we collect from you may be used in the following ways:</p> <ul> - <li>To personalize your experience — your information helps us to better respond to your individual needs.</li> - <li>To improve our site — we continually strive to improve our site offerings based on the information and feedback we receive from you.</li> - <li>To improve customer service — your information helps us to more effectively respond to your customer service requests and support needs.</li> - <li>To send periodic emails — The email address you provide may be used to send you information, notifications that you request about changes to topics or in response to your user name, respond to inquiries, and/or other requests or questions.</li> + <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li> + <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li> + <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li> </ul> + <hr class="spacer" /> + <h3 id="protect">How do we protect your information?</h3> - <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information.</p> + <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL, and your password is hashed using a strong one-way algorithm. You may enable two-factor authentication to further secure access to your account.</p> + + <hr class="spacer" /> - <h3 id="data-retention">What is your data retention policy?</h3> + <h3 id="data-retention">What is our data retention policy?</h3> <p>We will make a good faith effort to:</p> <ul> - <li>Retain server logs containing the IP address of all requests to this server no more than 90 days.</li> - <li>Retain the IP addresses associated with registered users and their posts no more than 5 years.</li> + <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li> + <li>Retain the IP addresses associated with registered users no more than 12 months.</li> </ul> + <p>You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.</p> + + <p>You may irreversibly delete your account at any time.</p> + + <hr class="spacer"/> + <h3 id="cookies">Do we use cookies?</h3> <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p> - <p>We use cookies to understand and save your preferences for future visits and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business.</p> + <p>We use cookies to understand and save your preferences for future visits.</p> + + <hr class="spacer" /> <h3 id="disclose">Do we disclose any information to outside parties?</h3> - <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.</p> + <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety.</p> - <h3 id="third-party">Third party links</h3> + <p>Your public content may be downloaded by other servers in the network. Your public and followers-only posts are delivered to the servers where your followers reside, and direct messages are delivered to the servers of the recipients, in so far as those followers or recipients reside on a different server than this.</p> - <p>Occasionally, at our discretion, we may include or offer third party products or services on our site. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these sites.</p> + <p>When you authorize an application to use your account, depending on the scope of permissions you approve, it may access your public profile information, your following list, your followers, your lists, all your posts, and your favourites. Applications can never access your e-mail address or password.</p> + + <hr class="spacer" /> <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> <p>Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p> - <h3 id="online">Online Privacy Policy Only</h3> - - <p>This online privacy policy applies only to information collected through our site and not to information collected offline.</p> - - <h3 id="consent">Your Consent</h3> - - <p>By using our site, you consent to our web site privacy policy.</p> + <hr class="spacer" /> <h3 id="changes">Changes to our Privacy Policy</h3> <p>If we decide to change our privacy policy, we will post those changes on this page.</p> - <p>This document is CC-BY-SA. It was last updated May 31, 2013.</p> + <p>This document is CC-BY-SA. It was last updated March 7, 2018.</p> <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: "%{instance} Terms of Service and Privacy Policy" diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 84d63d831..a896592b0 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -667,74 +667,6 @@ eo: reblogged: diskonigita sensitive_content: Tikla enhavo terms: - body_html: | - <h2>Privateca politiko</h2> - - <h3 id="collect">Kiujn informojn ni kolektas?</h3> - - <p>Ni kolektas informojn de vi, kiam vi registriĝas en nia retejo aŭ partoprenas en la forumo per legado, skribado, kaj traktado de la enhavo diskonigita ĉi tie.</p> - - <p>En registriĝo, ni povas peti al vi vian nomon kaj retadreson. Vi tamen povas viziti nian retejon sen registriĝo. Via retadreso estos validigita per retmesaĝo, kiu enhavos unikan ligilon. Se tiu ligilo estas vizitita, ni scios ke vi regas la retadreson.</p> - - <p>Post registriĝo, ni registras la IP-adreson de tiu, kiu kreas mesaĝon. Ni ankaŭ povas konservi servilan historion, en kiu troviĝas la IP-adreso de ĉiu peto al nia servilo.</p> - - <h3 id="use">Por kio ni uzas viajn informojn?</h3> - - <p>Ajna informo, kiun ni kolektas povas esti uzata por unu el tiuj celoj:</p> - - <ul> - <li>Proprigi vian sperton — viaj informoj helpas nin pli bone respondi al viaj propraj bezonoj.</li> - <li>Plibonigi nian retejon — ni daŭre klopodas por plibonigi nian retejon uzante la informojn kaj komentojn, kiujn ni ricevas de vi.</li> - <li>Plibonigi nian helpon al klientoj — viaj informoj helpas nin pli bone respondi al klientaj petoj kaj al subtenaj bezonoj.</li> - <li>Sendi periodajn retmesaĝojn — La retadreso, kiun vi donas al ni, povas esti uzata por sendi al vi informojn kaj sciigojn, kiujn vi volas ricevi pri ŝanĝoj rilate al apartaj temoj, aŭ responde al via uzantnomo, al petoj kaj al demandoj.</li> - </ul> - - <h3 id="protect">Kiel ni protektas viajn informojn?</h3> - - <p>Ni realigis diversajn sekurigajn procedojn por konservi la sekurecon de viaj personaj informoj kiam vi enmetas, sendas, aŭ aliras viajn personajn informojn.</p> - - <h3 id="data-retention">Kio estas nia politiko pri konservado de datumoj?</h3> - - <p>Ni honeste klopodas:</p> - - <ul> - <li>Ne konservi servilan historion, kiu enhavas la IP-adresojn de ĉiuj petoj, dum pli ol 90 tagoj.</li> - <li>Ne konservi la IP-adresojn de registritaj uzantoj kaj de iliaj mesaĝoj dum pli ol 5 jaroj.</li> - </ul> - - <h3 id="cookies">Ĉu ni uzas kuketojn?</h3> - - <p>Jes. Kuketoj estas etaj dosieroj, kiujn retejo aŭ ĝia servo donas al la memoro de via komputilo, per via retumilo (se vi permesas tion). Ĉi tiuj kuketoj ebligas al la retejo rekoni vian retumilon, kaj se vi havas registritan konton, ligas ĝin al via registrita konto.</p> - - <p>Ni uzas kuketojn por kompreni kaj konservi viajn preferojn por postaj vizitoj, kaj kunmeti informojn pri reteja trafiko kaj interago, por ke ni povu doni pli bonan retejan sperton kaj pli bonajn ilojn estonte. Ni povas kontrakti kun eksteraj servoj por helpi nin pli bone kompreni la vizitantojn de la retejo. Ĉi tiuj eksteraj servoj ne rajtas uzi la informojn, kiujn ni kolektis, krom por helpi nin regi kaj plibonigi nian komercon.</p> - - <h3 id="disclose">Ĉu ni disdonas informojn al eksteraj personoj?</h3> - - <p>Ni ne vendas, interŝanĝas aŭ transdonas al eksteraj personoj viajn persone identigeblajn informojn. Ĉi tio ne inkludas la eksterajn servojn, kiujn ni fidas, kiuj helpas nin funkciigi nian retejon, regi nian komercon, aŭ servi vin, kiom longe tiuj personoj konsentas pri la sekura konservado de ĉi tiuj informoj. Ni ankaŭ povas disdoni viajn informojn, kiam ni pensas ke tio estas nepra por respekti leĝojn, por respektigi la politikojn de nia retejo, aŭ por protekti la rajtojn, posedaĵojn, kaj sekurecon de ni kaj de aliaj. Tamen, informoj de vizitantoj, kiuj ne identigas personojn, povas esti donitaj al eksteraj personoj por merkatado, reklamado, aŭ aliaj uzoj.</p> - - <h3 id="third-party">Eksteraj ligiloj</h3> - - <p>Foje, laŭ nia elekto, ni povas enmeti aŭ oferti eksterajn produktojn aŭ servojn en nia retejo. Ĉi tiuj eksteraj retejoj havas apartajn kaj sendependajn privatecajn politikojn. Tial, ni havas nek responsojn nek devigojn rilate al la enhavoj kaj agadoj de ĉi tiuj ligitaj retejoj. Tamen, ni celas protekti tiujn, kiuj uzas nian retejon, kaj bonvenigas ajnan komenton pri ĉi tiuj retejoj.</p> - - <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> - - <p>Niaj retejo, produktoj kaj servoj estas por tiuj, kiuj havas almenaŭ 13 jarojn. Se ĉi tiu servilo estas en Usono, kaj vi havas malpli ol 13 jarojn, pro la postuloj de COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) ne uzu ĉi tiun retejon.</p> - - <h3 id="online">Privateca politiko nur rete</h3> - - <p>Ĉi tiu privateca politiko validas nur por informoj kolektitaj per nia retejo kaj ne por informoj kolektitaj eksterrete.</p> - - <h3 id="consent">Via konsento</h3> - - <p>Per uzado de nia retejo, vi konsentas kun nia reta privateca politiko.</p> - - <h3 id="changes">Ŝanĝoj al nia privateca politiko</h3> - - <p>Se ni decidas ŝanĝi nian privatecan politikon, ni afiŝos tiujn ŝanĝojn en ĉi tiu paĝo.</p> - - <p>Ĉi tiu dokumento estas laŭ permeso CC-BY-SA. Ĝi estis laste ĝisdatigita je 2018-02-27.</p> - - <p>Originale adaptita el la <a href="https://github.com/discourse/discourse">privateca politiko de Discourse</a>.</p> title: Uzkondiĉoj kaj privateca politiko de %{instance} themes: default: Mastodon diff --git a/config/locales/es.yml b/config/locales/es.yml index 199253d6f..b5e540e28 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -656,74 +656,6 @@ es: reblogged: retooteado sensitive_content: Contenido sensible terms: - body_html: | - <h2>Políticas de privacidad</h2> - - <h3 id="collect">¿Qué información recolectamos?</h3> - - <p>Recolectamos información tuya cuando te registras en nuestro sitio y adquirimos datos cuando participas en el foro leyendo, escribiendo, y evaluando el contenido compartido aquí.</p> - - <p>Cuando te registras en nuestro sitio, puede que se te pida tu nombre y dirección de correo electrónico. De todas formas, puedes visitar nuestro sitio sin registrarte. Tu dirección de correo electrónico será verificada por un e-mail conteniendo un enlace único. Si ese enlace es visitado, sabemos que tú controlas esa dirección.</p> - - <p>Cuando te registras y posteas, grabamos la IP de la que se origina esa acción. También puede que retengamos logs del servidor, que incluyen la dirección IP de todos los pedidos a nuestro servidor.</p> - - <h3 id="use">¿Para qué usamos tu información?</h3> - - <p>Toda la información que recolectamos de ti puede usarse en una de las siguientes maneras:</p> - - <ul> - <li>Para personalizar tu experiencia — tu información nos ayuda a responder mejor tus necesidades individuales.</li> - <li>Para mejorar nuestro sitio — nos esforzamos continuamente en mejorar nuestras ofertas del sitio basándonos en la información y apoyo que recibimos de ti.</li> - <li>Para mejorar el servicio al cliente — tu información nos ayuda a responder más efectivamente al servicio al cliente y otras necesidades.</li> - <li>Para enviar e-mails periódicos — la dirección de e-mail que provees puede usarse para enviarte información, notificaciones que pides sobre cambios en tópicos o en respuesta a tu nombre de usuario, responder consultas, y/u otros pedidos o preguntas.</li> - </ul> - - <h3 id="protect">¿Cómo protegemos tu información?</h3> - - <p>Implementamos una variedad de medidas de seguridad para mantener a salvo tu información personal cuando entras, publicas, o accesas a ella.</p> - - <h3 id="data-retention">¿Cuáles son sus políticas de retención de datos?</h3> - - <p>Haremos un gran esfuerzo en:</p> - - <ul> - <li>Retener logs del servidor conteniendo la dirección IP de todos los pedidos a este servidor en no más de 90 días.</li> - <li>Retener las direcciones IP asociadas con usuarios registrados y sus posts no más de 5 años.</li> - </ul> - - <h3 id="cookies"¿Usamos cookies?</h3> - - <p>Sí. Las cookies son pequeños archivos que un sitio web o su proveedor de servicio transfieren al disco duro de tu computadora a través de tu navegador web (si se le permite). Estas cookies permiten al sitio reconocer tu navegador y, si y tienes una cuenta registrada, asociarlo con ella.</p> - - <p>Usamos cookies para entender y guardar tus preferencias para futuras visitas y agregar datos compilados sobre el tráfico del sitio e interacción para que podamos ofrecer una mejor experiencia y herramientas en el futuro. Puede que contratemos con proveedores de servicio de tercera mano para que nos asistan en el mejor entendimiento de nuestros visitantes del sitio. A estos proveedores de servicio no se les permite usar la información recolectada a nuestras espaldas excepto para ayudarnos a conducir y mejorar nuestro trabajo.</p> - - <h3 id="disclose">¿Revelamos alguna información a terceras manos?</h3> - - <p>No vendemos, intercambiamos, ni de ninguna otra manera transferimos tu información personal identificable a terceras partes. Esto no incluye las terceras manos que nos asisten en operar nuestro sitio, conducción o trabajo, o en servirte, tanto como que éstas acepten en mantener esta información confidencial. Puede que también liberemos tu información cuando creamos que es apropiado para cumplir con la ley, enforzar nuestras políticas del sitio, o proteger la nuestra u otros derechos, propiedad, o seguridad. De todas formas, la información del visitante autorizado no-personal puede proveerse a otras partes por marketing, publicidad, u otros usos.</p> - - <h3 id="third-party">Enlaces de terceras partes</h3> - - <p>Ocasionalmente, a nuestra discreción, puede que incluyamos u ofrezcamos productos de terceras partes o servicios en nuestro sitio. Estas terceras partes tienen políticas de privacidad separadas e independientes. Por lo tanto no tenemos responsabilidad u obligación por el contenido y actividades de estos sitios enlazados. Sin embargo, buscamos proteger la integridad de nuestro sitio y dar la bienvenida a cualquier ayuda sobre estos sitios.</p> - - <h3 id="coppa">Children's Online Privacy Protection Act Compliance (Cumplimiento de la Ley de la Protección Privada en Línea del Niño)</h3> - - <p>Nuestro sitio y todos nuestros productos y servicios están dirigidos a gente que tiene al menos 13 años de edad. Si el servidor está alojado en EE.UU, y tienes menos de 13 años, no uses este sitio por los requerimientos del COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>).</p> - - <h3 id="online">Solo Políticas de Privacidad en Línea</h3> - - <p>Estas políticas de privacidad aplican únicamente a la información recolectada a través de nuestro sitio y no a información recolectada <i>offline</i>.</p> - - <h3 id="consent">Tu Consentimiento</h3> - - <p>Al usar nuestro sitio, estás consentido a nuestras políticas de privacidad del sitio.</p> - - <h3 id="changes">Cambios a nuestras Políticas de Privacidad</h3> - - <p>Si decidimos cambiar nuestras políticas de privacidad, las publicaremos en esta página.</p> - - <p>Este documento está publicado bajo la licencia CC-BY-SA. Última vez actualizado el 31 de Mayo del 2013.</p> - - <p>Adaptado originalmente del <a href="https://github.com/discourse/discourse">discurso de las políticas de privacidad</a>.</p> title: Términos del Servicio y Políticas de Privacidad de %{instance} time: formats: diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 86756c01b..ed25ea8c9 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -613,74 +613,6 @@ fa: reblogged: بازبوقید sensitive_content: محتوای حساس terms: - body_html: | - <h2>سیاست رازداری (Privacy Policy)</h2> - - <h3 id="collect">ما چه اطلاعاتی را گردآوری میکنیم؟</h3> - - <p>این سایت برخی از اطلاعات مربوط به شما را ثبت میکند. این موارد شامل اطلاعات ثبتنامی شماست، و نیز شامل نوشتههایی است که اینجا میخوانید، مینویسید، یا واکنشهایی که به نوشتههای دیگران نشان میدهید.</p> - - <p>وقتی که در این سایت ثبتنام میکنید، ممکن است از شما بخواهیم که نام و نشانی ایمیل خود را وارد کنید. البته بدون ثبتنام نیز میتوان از این سایت بازدید کرد. برای تأیید ایمیل شما، ما یک نشانی اینترنتی یکتا را به آن میفرستیم. اگر آن نشانی را کسی باز کند، ما میفهمیم که آن شما بودهاید و بنابراین نشانی ایمیل متعلق به شماست.</p> - - <p>وقتی که عضو باشید و چیزی بنویسید، ما نشانی اینترنتیای (IP) را که نوشته از آن آمده است ثبت میکنیم. سیاههٔ کاری (log) سرور شامل نشانی IP همهٔ درخواستها به سرور است که ما شاید آن را هم ثبت کنیم.</p> - - <h3 id="use">ما با اطلاعات شما چه کار میکنیم؟</h3> - - <p>اطلاعاتی را که ما از شما ثبت میکنیم، ممکن است در موارد زیر به کار بروند:</p> - - <ul> - <li>برای شخصیسازی تجربهٔ کاربری شما — ما به کمک اطلاعات شما بهتر میتوانیم نیازهای شما را برآورده کنیم.</li> - <li>برای بهتر کردن سایت — ما پیوسته میکوشیم تا خدمات این سایت را به کمک اطلاعات و بازخوردی که از شما میگیریم بهتر کنیم.</li> - <li>برای بهتر کردن خدمات به کاربران — ما به کمک اطلاعات شما به طور مؤثرتری میتوانیم به درخواستهای پشتیبانی شما پاسخ دهیم.</li> - <li>برای فرستادن ایمیلهای دورهای — ما گاهی به نشانی ایمیلی که وارد کردهاید نامه میفرستیم تا به درخواستهای شما پاسخ دهیم یا شما را در جریان پاسخ دیگران به شما قرار دهیم.</li> - </ul> - - <h3 id="protect">ما چگونه از اطلاعات شما محافظت میکنیم؟</h3> - - <p>ما روشهای امنیتی گوناگونی را پیاده کردهایم تا امنیت اطلاعات شخصی شما هنگام ثبت، فرستادهشدن، و بازیابی آنها حفظ شود.</p> - - <h3 id="data-retention">سیاست ما برای نگهداری اطلاعات شما چیست؟</h3> - - <p>ما با حسن نیت تلاش میکنیم تا:</p> - - <ul> - <li>سیاههٔ کاری سرور که شامل نشانی IP همهٔ درخواستها به این سرور است را بیشتر از ۹۰ روز ذخیره نکنیم.</li> - <li>نشانی IP مربوط به کاربران ثبتنامشده را بیشتر از ۵ سال نگه نداریم.</li> - </ul> - - <h3 id="cookies">آیا ما کوکیها را بهکار میبریم؟</h3> - - <p>بله. کوکیها پروندههای کوچکی هستند که یک سایت یا خدماتدهندهاش (اگر شما اجازه بدهید) از راه مرورگر در کامپیوتر شما ذخیره میکنند. به کمک این کوکیها سایت میتواند مرورگر شما را بشناسد و اگر شما ثبتنام کرده باشید، حساب شما را به مرورگرتان مرتبط کند.</p> - - <p>ما به کمک کوکیها ترجیحات شما را برای بازدیدهای آینده میفهمیم و ذخیره میکنیم و دادههای جامعی دربارهٔ بازدیدها از سایت و برهمکنشها با آن را تهیه میکنیم. به این ترتیب میتوانیم در آینده تجربهٔ کاربری سایت و ابزارهای مربوط به آن را بهتر کنیم. برای داشتن درک بهتری از بازدیدکنندگان این سایت، ما گاهی از خدماتدهندههای دیگر نیز کمک میگیریم. این خدماتدهندهها اجازه ندارند تا از اطلاعاتی که به جای ما جمع میکنند برای کاری به جز بهترکردن کار ما استفاده کنند.</p> - - <h3 id="disclose">آیا ما اطلاعاتی به نهادهای دیگر فاش میکنیم؟</h3> - - <p>ما اطلاعاتی را که بتواند شما را شناسایی کند به نهادهای دیگر نمیفروشیم، معامله نمیکنیم، یا به هر روش دیگری منتقل نمیکنیم. این شامل نهادهای مورد اعتمادی نمیشود که به ما در گرداندن این سایت یا انجام کارهایمان کمک میکنند، یا به شما خدمات میرسانند، تا جایی که آنها این دادهها را محرمانه نگه دارند. ما همچنین ممکن است اطلاعات شما را به حکم قانون یا برای اِعمال سیاستهای سایت، یا به خاطر حفظ حقوق، داراییها، یا امنیت خودمان یا دیگران منتشر کنیم. ما ممکن است اطلاعات بازدیدکنندگان سایت را که با آن نمیتوان شما را شناسایی کرد برای بازاریابی، تبلیغات، یا هدفهای دیگر به نهادهای دیگر ارائه دهیم.</p> - - <h3 id="third-party">پیوند (لینک) به صفحههای دیگران</h3> - - <p>ما گاهی ممکن است به صلاحدید خودمان محصولات یا خدمات دیگران را در این سایت بگنجانیم یا پیشنهاد دهیم. سایتهای مرتبط با این محصولات و خدمات دارای سیاستهای رازداری جداگانه و مستقل خودشان هستند. بنابراین ما مسئولیتی دربارهٔ محتوا و کنشهای این سایتها به عهده نمیگیریم. با این وجود، ما تلاش میکنیم که این سایت به درستی کار کند و از بازخورد شما برای چنین محصولات و خدماتی استقبال میکنیم.</p> - - <h3 id="coppa">پیروی از قانون پشتیبانی از حریم خصوصی آنلاین کودکان</h3> - - <p>سایت ما، محصولات و خدماتش همه برای کسانی است که دستکم ۱۳ سال سن داشته باشند. اگر این سرور در خاک ایالات متحدهٔ امریکا قرار دارد و سن شما کمتر از ۱۳ سال است، به خاطر رعایت قانون COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) لطفاً این سایت را به کار نبرید.</p> - - <h3 id="online">تنها سیاست رازداری آنلاین</h3> - - <p>این سیاست رازداری آنلاین تنها مربوط به اطلاعاتی است که از راه سایت ما گردآوری میشود و شامل اطلاعاتی که به طور آفلاین گردآوری شده نیست.</p> - - <h3 id="consent">موافقت شما</h3> - - <p>با استفاده از این سایت، شما موافقت خود را با سیاست رازداری ما اعلام میکنید.</p> - - <h3 id="changes">تغییرات در سیاست رازداری ما</h3> - - <p>اگر ما سیاست رازداری خود را تغییر دهیم، این تغییرات را در این صفحه خواهیم نوشت.</p> - - <p>این نوشته تحت اجازهنامهٔ CC-BY-SA قرار دارد. تاریخ آخرین بهروزرسانی آن ۱۰ خرداد ۱۳۹۲ است.</p> - - <p>این نوشته اقتباسی است از <a href="https://github.com/discourse/discourse">سیاست رازداری Discourse</a>.</p> title: شرایط استفاده و سیاست رازداری %{instance} themes: default: ماستدون diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 0e1098214..1689754a0 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -664,74 +664,6 @@ fr: reblogged: a partagé sensitive_content: Contenu sensible terms: - body_html: | - <h2>Politique de confidentialité</h2> - - <h3 id="collect">Quelles données collectons-nous ?</h3> - - <p>Nous collectons des données lorsque vous vous enregistrez sur notre site et les récoltons lorsque vous participez dans le forum en lisant, écrivant, et évaluant le contenu partagé ici.</p> - - <p>Lors de l’enregistrement sur notre site, il peut vous être demandé de renseigner votre nom et adresse électronique. Vous pouvez, cependant, visiter notre site sans inscription. Votre adresse électronique devra être vérifiée grâce à un courriel contenant un lien unique. Si ce lien est visité, nous savons que vous contrôlez cette adresse.</p> - - <p>Lors de l’inscription et de la publication de statuts, nous enregistrons l’adresse IP de laquelle les statuts proviennent. Nous pouvons également conserver des historiques serveurs qui contiendront l’adresse IP de chaque requête adressée à notre serveur.</p> - - <h3 id="use">Que faisons-nous avec vos données ?</h3> - - <p>Toute information que nous collectons pourra être utilisée d’une des manières suivantes :</p> - - <ul> - <li>Pour personnaliser votre expérience — vos données nous aident à mieux répondre à vos besoins individuels.</li> - <li>Pour améliorer notre site — nous faisons tout notre possible pour améliorer notre site en fonction des données, retours et suggestions que nous recevons.</li> - <li>Afin d’améliorer le support client — vos données nous aident à mieux répondre à vos requêtes et demandes de support.</li> - <li>Afin d’envoyer des courriels à intervalles réguliers — l’adresse électronique que vous renseignez peut être utilisée pour vous envoyer des données et notifications concernant des changements ou en réponse à votre nom d’utilisateur⋅ice, en réponse à vos demandes et/ou autres requêtes ou questions</li> - </ul> - - <h3 id="protect">Comment protégeons-nous vos données ?</h3> - - <p>Nous appliquons une multitude de mesures afin de maintenir la sécurité de vos données personnelles lorsque vous entrez, soumettez, ou accédez à ces dernières.</p> - - <h3 id="data-retention">Quelle est notre politique de conservation des données ?</h3> - - <p>Nous nous efforçons de :</p> - - <ul> - <li>ne pas garder les historiques serveurs contenant l’adresse IP de chaque requête adressée à ce serveur plus de 90 jours ;</li> - <li>ne pas conserver les adresses IP associées aux utilisateur⋅trices et leur contenu plus de 5 ans.</li> - </ul> - - <h3 id="cookies">Utilisons-nous des « cookies » ?</h3> - - <p>Oui. Les cookies sont de petits fichiers qu’un site ou prestataires de services transfèrent sur le disque dur de votre ordinateur par le biais de votre navigateur Web (si ce dernier le permet). Ces cookies permettent au site de reconnaître votre navigateur et, si vous disposez d’un compte, de l’associer à celui-ci.</p> - - <p>Nous utilisons les cookies pour enregistrer vos préférences pour de futures visites, compiler des données agrégées à propos du trafic et des interactions effectuées sur le site afin de proposer une meilleure expérience dans le futur. Nous pouvons contracter les services de tiers afin de nous aider à mieux comprendre les visiteurs de notre site. Ces tiers ont l’autorisation d’utiliser ces données seulement à des fins d’améliorations.</p> - - <h3 id="disclose">Divulguons-nous des données à des tiers ?</h3> - - <p>Nous n’échangeons pas, ne vendons pas ni effectuons de quelconques transferts avec des tiers d’informations permettant de vous identifier personnellement. Cela n’inclut pas les tiers de confiance qui nous aident à gérer notre entreprise et à vous servir tant que ces tiers s’accordent à garder lesdites informations confidentielles. Nous pouvons être amenés à délivrer vos informations lorsque jugé adéquat afin de respecter la loi, d’appliquer la politique de notre site, ou afin de protéger nos droits, ceux des autres, notre propriété ou sécurité. Cependant, aucune information permettant l’identification de nos visiteur⋅euse⋅s ne sera divulguée à des fins publicitaires, commerciales ou tout autre usage.</p> - - <h3 id="third-party">Liens vers des tiers</h3> - - <p>Nous pouvons être amenés à inclure ou offrir les services ou produits de tiers sur notre site. Ces tiers possèdent leur propre politique de confidentialité. Nous ne sommes donc pas responsables du contenu ou activités desdits tiers. Néanmoins, nous cherchons à protéger l’intégrité de notre site et sommes ouverts à toute remarque concernant ces tiers.</p> - - <h3 id="coppa" lang="en">Children's Online Privacy Protection Act</h3> - - <p>Notre site, nos produits et services sont tous destinés à l’usage de personnes âgées de 13 ans ou plus. Si ce serveur est hébergé aux États-Unis et que vous êtes âgé⋅e de moins de 13 ans, au vu du COPPA (<a href="https://fr.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act"><i lang="en">Children's Online Privacy Protection Act</i></a>) n’utilisez pas ce site.</p> - - <h3 id="online">Politique de confidentialité en ligne</h3> - - <p>Cette politique de confidentialité en ligne s'applique uniquement aux informations collectées par le biais de notre site et non aux informations collectées hors ligne.</p> - - <h3 id="consent">Votre consentement</h3> - - <p>En utilisant notre site, vous consentez à la présente politique de confidentialité.</p> - - <h3 id="changes">Changements de notre politique de confidentialité</h3> - - <p>Si nous décidons d’apporter des changements à notre politique de confidentialité, nous les publierons sur cette page.</p> - - <p>Ce document est distribué sous licence CC-BY-SA. Il a été mis à jour pour la dernière fois le 31 mai 2013. Il a été traduit en français en juillet 2017.</p> - - <p>Originellement adapté à partir de la politique de confidentialité de <a href="https://github.com/discourse/discourse">Discourse</a>.</p> title: "%{instance} Conditions d’utilisations et politique de confidentialité" time: formats: diff --git a/config/locales/gl.yml b/config/locales/gl.yml index bddc1b789..f4ca7e8c5 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -665,74 +665,6 @@ gl: reblogged: promocionada sensitive_content: Contido sensible terms: - body_html: | - <h2>Política de intimidade</h2> - - <h3 id="collect">Qué información recollemos?</h3> - - <p>Recollemos información sobre vostede cando se rexistra no noso sitio web e recollemos datos cando participa no foro lendo, escribindo e evaluando o contido compartido aquí. </p> - - <p>Cando se rexistra no noso sitio, podería solicitarselle o seu nome e enderezo de correo electrónico. Vostede podería, porén, visitar o noso sitio sin rexistrarse. O seu enderezo de correo será verificado con un correo con unha ligazón única. Si esa ligazón é visitada, saberemos que vostede controla ese enderezo de correo.</p> - - <p>Cando se rexistra e publica, almacenamos o enderezo IP desde onde publicou. Poderiamos tamén gardar rexistros do servidor que inclúan a IP de cada petición ao realizada ao servidor. </p> - - <h3 id="use">Con qué fin utilizamos a súa información?</h3> - - <p>Toda a información recollida de vostede podería ser utilizada dos seguintes xeitos:</p> - - <ul> - <li>Para individualizar a súa experiencia — a súa información axúdanos a respostar mellor as súas necesidades individuais.</li> - <li>Para mellorar o noso sitio —esforzámonos en mellorar o que ofrece o noso sitio baseándonos na información e críticas que vostede nos proporciona.</li> - <li>Para mellorar o servizo ao cliente —a súa información axúdanos a respostar máis eficientemente as súas peticións de servizo ao cliente e axuda.</li> - <li>Para enviar correos electrónicos periodicamente — O enderezo de correo que nos proporciona podería ser utilizado para enviarlle información, notificacións que solicitou sobre cambios ou asuntos ou en resposta ao ser nome de usuaria, responder a enquisas, e/ou outras peticións ou cuestións.</li> - </ul> - - <h3 id="protect">Cómo protexemos a súa información?</h3> - - <p>Implementamos varias medidas de seguridade para manter a seguiridade da súa información personal cando introduce, envía ou accede a súa información personal.</p> - - <h3 id="data-retention">Qué é a política de retención dos seus datos?</h3> - - <p>Faremos un sincero esforzo para:</p> - - <ul> - <li>Manter rexistros do sistema con enderezos IP de todas as peticións feitas a este servidor no seu nome non máis de 90 días.</li> - <li>Manter os enderezos IP asociados a usuarias rexistradas e as súas mensaxes non máis de 5 anos. </li> - </ul> - - <h3 id="cookies">Utilizamos cookies?</h3> - - <p>Si. As cookies son pequenos ficheiros que un sitio ou o seu proveedor de servizo transfire ao disco duro da súa computadora a través do navegador web (se vostede o permite). Estas cookies permiten ao sitio recoñer o seu navegador e, si ten unha conta rexistrada, asocialo coa súa conta.</p> - - <p>Utilizamos cookies para comprender e gardar as súas preferencias para futuras visitas e compilar datos agregados sobre o tráfico do sitio e interacción co sitio de tal xeito que no futuro poidamos ofrecer unha mellor experiencia de uso do sitio e ferramentas. Poderiamos contratar servizos de terceiros para axudarnos a entender mellor as nosas visitantes. Estos proveedores de servizo non teñen permiso para utilizar a información recollida no noso nome excepto para axudarnos a xestionar e mellorar o noso negocio. </p> - - <h3 id="disclose">Mostramos información a terceiros alleos?</h3> - - <p>Non vendemos, nin negociamos con, ou transmitimos de outros xeitos a axentes terceiros alleos a información que a información que a identifica personalmente. Esto non inclúe terceiros de confianza que non axudan a operar o sitio, xestionar o negocio, ou servila, así estas partes se comprometan coa confidencialidade dos datos. Poderiamos revelar a súa información cando creamos que facelo así é axeitado para cumplir coa lei, cumplir coas normas do sitio ou protexer os nosos dereitos, propiedades ou seguridade e os de outras. Porén, non se proporcionará información identificable a terceiros para publicidade, márquetin ou outros usos.</p> - - <h3 id="third-party">Ligazóns a terceiros</h3> - - <p>De xeito ocasional, a nosa discreción, poderiamos incluír ofertas de productos e servizos de terceiros no noso sitio. Estos sitios de terceiros teñen políticas de intimidade propias. Polo tanto non temos responsabilidade ou obligacións polo contido e actividades de esos sitios. Con todo, procuramos protexer a integridade do noso sitio e agradecemos calquer opinión e crítica sobre estos sitios.</p> - - <h3 id="coppa">Cumplimento coa Children's Online Privacy Protection Act</h3> - - <p>O noso sitio, productos e servizos están dirixidos as personas con 13 anos como mínimo. Si este servidor está en USA e vostede ten menos de 13 anos, a requerimento da COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) non utilice este sitio web.</p> - - <h3 id="online">Política de intimidade só en liña</h3> - - <p>Esta política de intimidade aplícase só a información recollida no noso sitio e non a información recollida fora de liña. </p> - - <h3 id="consent">O seu consentimento</h3> - - <p>Utilizando o noso sitio, vostede acepta esta política de intimidade.</p> - - <h3 id="changes">Cambios na política de intimidade</h3> - - <p>Si decidimos cambiar a nosa política de intimidade publicaremos esos cambios en esta páxina.</p> - - <p>Este documento ten licenza CC-BY-SA. Foi actualizado o 31 de maio de 2013.</p> - - <p>Adaptado do orixinal <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: "%{instance} Termos do Servizo e Política de Intimidade" themes: default: Mastodon diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 6be82c1de..2560b3816 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -633,76 +633,6 @@ hu: reblogged: reblogolt sensitive_content: Szenzitív tartalom terms: - body_html: | - <h2>Adatvédelmi és adatkezelési nyilatkozat</h2> - - <h3 id="collect">Milyen információt gyűjtünk?</h3> - - <p>Az oldalra történő regisztráció és a szolgáltatás használata - olvasás, tartalom létrehozása, tartalommegosztás - során információt gyűjtünk veled kapcsolatban.</p> - - <p>A regisztráció során kérhetjük nevedet és e-mail címedet. Az oldalt természetesen regisztráció nélkül is felkeresheted. Az e-mail címed megerősítése egy egyedi információt tartalmazó link segítségével történik. Mondott linkre kattintva ellenőrizzük, hogy valóban te vagy a cím kezelője.</p> - - <p>Regisztrált felhasználók esetében tülkök írásakor rögzítjük a felhasználó IP-címét. A szerver napjófájlja szintén tárolhatja ezt az IP-címet, valamint a szerverre érkező minden kérés küldő-oldali IP-címét.</p> - - <h3 id="use">Mire használjuk a begyűjtött információt?</h3> - - <p>Minden begyűjtött információt az alábbi okokból használhatunk fel:</p> - - <ul> - <li>A felhasználói élmény személyre szabásához — a tőled gyűjtött információ segítségével biztosíthatjuk számodra az egyedi igényeknek történő megfelelést.</li> - <li>Szolgáltatásunk fejlesztéséhez — folyamatosan igyekszünk fejlődni és jobbá válni, és ezt a tőled kapott adatok és visszajelzések is nagyban segítik.</li> - <li>Az ügyféltámogatás fejlesztéséhez — a gyűjtött adatok segítségével hatékonyabban támogathatjuk felhasználóinkat, ha azok segítségre szorulnak.</li> - <li>E-mail értesítések küldéséhez — a megadott e-mail címedre küldjük ki az általad igényelt értesítéseket, a szolgáltatásra vonatkozó információkat és a válaszokat a tőled beérkező megkeresésekre.</li> - </ul> - - <h3 id="protect">Hogyan védjük a tőled gyűjtött információt?</h3> - - <p>Bitonsági mechanizmusok egész sorát vetjük be annak érdekében, hogy biztosítsuk a tőled származó személyes és használatai adatok és információk biztonságát.</p> - - <h3 id="data-retention">Meddig tároljuk a tőled származó adatokat?</h3> - - <p>Minden tőlünk telhetőt megteszünk annak érdekében, hogy</p> - - <ul> - <li>a szerver naplófájljaiban tárolt, a szerverre érkező kérések küldő-oldali IP-címét maximum 90 napig,</li> - <li>a regisztrált felhasználók tülkjeinek eredeti IP-címét pedig maximum 5 évig</li> - </ul> - - <p>tároljuk.</p> - - <h3 id="cookies">Használunk-e sütiket?</h3> - - <p>Igen. A sütik olyan kisméretű fájlok, amelyeket a szolgáltatások vagy internet-szolgáltatók küldenek a felhasználó számítógépére a böngészőn keresztül (természetesen csak abban az esetben, ha a felhasználó ezt engedélyezi). Oldalunk ezen sütik segítségével ismerik fel a böngésződet és - amennyiben rendelkezel nálunk fiókkal - kötik össze azt a felhasználói fiókoddal.</p> - - <p>A sütik segítségével jobban megérthetjük használati szokásaidat, eltárolhatjuk beállításaidat következő látogatásodig, valamint így mérhetjük az oldal látogatottságát és használatát, mely adatok segítenek abban, hogy jobbá tehessük az általunk nyújtott szolgáltatást. Esetenként harmadik féllel is kapcsolatba léphetünk a kinyert használati adatok jobb megértése érdekében. Ezen harmadik felek számára azonban az adatok használata szigorú feltételekhez kötött: kizárólag az engedélyünkkel és királólag a mi szolgáltatásunk fejlesztésével összefüggésben használhatják azokat.</p> - - <h3 id="disclose">Milyen információt adunk ki külső szereplőknek?</h3> - - <p>Soha, semmilyen körülmények között nem adunk ki, át vagy el külső szereplőknek olyan adatot, amelynek segítségével egyes felhasználóink egyedileg azonosíthatók. Ez nem vonatkozik olyan harmadik felekre, melyek jelen szolgáltatás üzemeltetésében, javításában vagy támogatásában segítségünkre vannak – ezeket a feleket azonban titoktartási szerződés köti mondott adatokkal kapcsolatban. A gyűjtött adatokat ezen felül megfelelő meghagyás megléte esetén kiadhatjuk a törvény és a rendfenntartás képviselőinek, amennyiben ezen adatoknak jog-, élet- vagy vagyonvédelmi jelentőségük van. Hirdetési- és marketing-, valamint egyéb, a fentiekben nem érintett célból csak olyan adatok adhatók ki, amelyek nem teszik lehetővé az egyes felhasználók egyedi azonosítását.</p> - - <h3 id="third-party">Harmadik felekre mutató hivatkozások</h3> - - <p>Esetenként elhelyezhetünk harmadik fél által ajánlott termékekre vagy szolgáltatásokra mutató hivatkozásokat az oldalon. Ezen harmadik feleknek saját, tőlünk független adatvédelmi és adatkezelési nyilatkozatuk van. Ennek értelmében az oldal üzemeltetői semmilyen felelősséget nem tudnak vállalni az ezen harmadik fél által üzemeltetett oldalak viselkedésével és tartalmával kapcsolatban. Ugyanakkor arra törekszünk, hogy mindenben saját felhasználóink érdekeit képviseljük, így minden, a fenti harmadik felekkel kacsolatos visszejelzést szívesen veszünk.</p> - - <h3 id="coppa">Megfelelés a Gyermekek Online Adatvédelméről Szóló Rendeletnek</h3> - - <p>Az oldal, valamint az azon keresztül nyújtott szolgáltatás a 13 éven felülieket célozza. Amennyiben ez a szerver az Amerikai Egyesült Államok területén található és te nem vagy még 13 éves, a COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Gyermekek Online Adatvédelméről Szóló Rendelet</a>) értelmében kérjük ne használd ezt az oldalt és szolgáltatást. - - <h3 id="online">Az adatvédelmi és adatkezelési nyilatkozat hatálya</h3> - - <p>Jelen adatvédelmi és adatkezelési nyilatkozat kizárólag az oldalunkon keresztül gyűjtött online adatokra vonatkozik, offline módon gyűjtött adatokra nem terjed ki.</p> - - <h3 id="consent">Használói beleegyezés</h3> - - <p>Az oldal és a szolgáltatás használatával elfogadottnak tekinted jelen adatvédelmi és adatkezelési nyilatkozatot.</p> - - <h3 id="changes">A nyilatkozat módosításairól</h3> - - <p>Amennyiben a jövőben módosítjuk jelen adatvédelmi és adatkezelési nyilatkozatunkat, a módosított szöveg ugyanezen oldalon lesz megtalálható.</p> - - <p>Jelen dokumentum a CC-BY-SA licenc alatt érhető el. Angol eredetijének utolsó módosítása: 2013. május 31.</p> - - <p>A dokumetum a <a href="https://github.com/discourse/discourse">Discourse adatvédelmi és adatkezelési nyilatkozatán</a> alapul.</p> title: "%{instance} Felhasználási feltételek és Adatkezelési nyilatkozat" themes: default: Mastodon diff --git a/config/locales/ja.yml b/config/locales/ja.yml index f8ebd8bcf..5f5cb9b01 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -700,74 +700,6 @@ ja: reblogged: さんがブースト sensitive_content: 閲覧注意 terms: - body_html: | - <h2>プライバシーポリシー</h2> - - <h3 id="collect">どのような情報を収集するのですか?</h3> - - <p>あなたがこのサイトに登録すると、ここで共有された情報を読んだり、書いたり、評価したりして、フォーラムでの情報を集める事ができます。</p> - - <p>このサイトに登録する際には、名前とメールアドレスの入力を求めることがあります。ただし、登録をすることなくこのサイトを利用することも可能です。あなたのメールアドレスは、固有のリンクを含んだメールで確認されます。そのリンクにアクセスした場合にメールアドレスを制御することとなります。</p> - - <p>アカウントを登録し、投稿を行った際にはその投稿が行われたIPアドレスを記録します。また、このサーバーに対する全てのリクエストはIPアドレスを含むサーバーログとして保管されます。</p> - - <h3 id="use">自分の情報を何に使うのですか?</h3> - - <p>このサイトで収集された情報は、次のいくつかの方法で使用されます:</p> - - <ul> - <li>パーソナライズ・エクスペリエンス — あなたの情報は、あなたや他のユーザーのニーズに対応するために役立ちます。</li> - <li>サイトの改善・最適化 — このサービスはあなたから受け取った情報やフィードバックに基づいて提供されるサイトの改善を行いつづけます。</li> - <li>サービスの向上 — あなたの情報は、ユーザーからの要求やサポートへより効果的に対応するために役立ちます。</li> - <li>定期メールの送信 — メールアドレスは、情報の送信、トピックの変更やユーザー名に関係するお知らせ、お問い合わせに関する返答、その他のリクエストや質問に関してお知らせするために使用されます。</li> - </ul> - - <h3 id="protect">自分の情報はどのように保護されるのですか?</h3> - - <p>このサービスはあなたの個人情報の入力、送信、またはアクセスに際してあなたの個人情報の安全性を維持するために様々なセキュリティ手段をとっています。</p> - - <h3 id="data-retention">データ保持のポリシーはどのようになっていますか?</h3> - - <p>このサービスはデータ保持に関して次のことを行うよう努めます。:</p> - - <ul> - <li>このサーバーへのすべての要求に対して、IPアドレスを含むサーバーログを90日以内に渡って保持します。</li> - <li>登録されたユーザーとその投稿に関連付けされたIPアドレスを5年以内に渡って保持します。</li> - </ul> - - <h3 id="cookies">クッキーを使用していますか?</h3> - - <p>はい。クッキーはあなたがウェブブラウザ上で許可した場合にコンピュータのストレージに転送される小さなファイルです。これらのクッキーを使用すると、サイトでブラウザが識別され、登録済みのアカウントを持っている場合は登録済みのアカウントに関連付けがされます。</p> - - <p>クッキーを使用して、今後再度閲覧された場合に前回のデータから設定を呼び出したり、今後の改善のためにサイトのトラフィックやサイトの相互作用に関する集計データを作成します。このサービスは、サイトを訪れた方との理解を深めるために、第三者のサービス提供者と契約することがあります。これらのサービス提供者というものは、このサービスでの業務を行ったり、改善するためにこのサービスの代わって収集された情報を使用することはできません。</p> - - <h3 id="disclose">このサイトは外部に何らかの情報を開示していますか?</h3> - - <p>私たちは、個人を特定出来る情報を外部へ販売、取引、または他の方法で渡すことはありません。これには、このサイトを操作したり、業務を行ったり、サービスを提供するのに役立つ信頼できる第三者は含まれません。法令遵守、サイトポリシーの施行、このサービスや他の人の権利、財産または安全の保護のために適切であると判断した場合に、あなたの情報を公開する場合があります。ただし、マーケティングや広告、その他の目的で匿名での訪問者情報を他者へ提供することができます。</p> - - <h3 id="third-party">サードパーティのリンク</h3> - - <p>必要に応じて、このサービスの方針にもとづいてこのサイトや第三者のサービスを提供することがあります。これらの第三者のサイトには、個別の独立したプライバシーポリシーがあります。従って、これらのリンク先のサイトに関するコンテンツや活動にかんしては一切責任を負いません。ですが、サイトの完全性やこれらのサイトに関するフィードバックは非常に重要なものであると認識しております。</p> - - <h3 id="coppa">子供のオンライン・プライバシー保護法</h3> - - <p>このサイト、製品、サービスはすべて13歳以上の人を対象としております。このサーバーが米国にあり、13歳未満の場合はCOPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) にもとづいてこのサイトを使用しないでください。</p> - - <h3 id="online">オンライン限定のプライバシーポリシー</h3> - - <p>このオンライン・プライバシーポリシーは、このサイトを通じて収集された情報のみに適用され、オフラインで収集される情報には適用されません。</p> - - <h3 id="consent">あなたの同意</h3> - - <p>このサービスを使用することにより、このサイトのプライバシーポリシーに同意するものとします。</p> - - <h3 id="changes">プライバシーポリシーの変更</h3> - - <p>プライバシーポリシーを変更する場合は、このページへ変更内容を掲載します。</p> - - <p>この文章のライセンスはCC-BY-SAです。このページは2017年5月6日が最終更新です。</p> - - <p>オリジナルの出典 <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: "%{instance} 利用規約・プライバシーポリシー" themes: default: Mastodon diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 450330698..bbf27d5c3 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -667,74 +667,6 @@ ko: reblogged: 님이 부스트 했습니다 sensitive_content: 민감한 컨텐츠 terms: - body_html: | - <h2>사생활 정책</h2> - - <h3 id="collect">우리가 어떤 정보를 수집하나요?</h3> - - <p>우리는 귀하가 우리 사이트에 가입할 때, 그리고 우리의 포럼에 읽고, 쓸 때, 그리고 포럼에 게시된 공유된 콘텐츠를 평가할 때 정보를 수집합니다.</p> - - <p>우리 사이트에 가입할 때, 귀하는 이름과 이메일 주소 입력을 요구 받을 수 있습니다. 하지만 귀하는 우리의 사이트를 가입하지 않고도 방문할 수 있습니다. 귀하의 이메일 주소는 고유한 링크를 담고 있는 이메일로 검증 될 것입니다. 만약 귀하가 그 링크를 방문한다면, 우리는 귀하가 그 이메일 주소를 소유하고 있다는 것을 알 수 있습니다.</p> - - <p>가입을 하고 글을 쓸 때, 우리는 글이 어떤 IP에서 작성 되었는지 기록합니다. 또한 우리는 모든 요청에 대한 IP 주소를 담고 있는 서버 로그를 보관할 수 있습니다.</p> - - <h3 id="use">우리가 귀하의 정보를 어떻게 사용하나요?</h3> - - <p>우리가 귀하에게서 수집하는 어떠한 정보는 다음 중 하나와 같은 방법으로 사용될 수 있습니다:</p> - - <ul> - <li>귀하의 경험을 개인화 하기 위해 — 귀하의 정보는 우리가 귀하의 개별적인 요구에 더 나은 응답을 할 수 있도록 돕습니다.</li> - <li>우리의 사이트를 개선하기 위해 — 우리는 귀하에게 받는 정보와 귀하에게 받는 피드박을 바탕으로 우리의 사이트 내용을 계속 개선하기 위해 노력합니다.</li> - <li>고객 서비스를 개선하기 위해 — 귀하의 정보는 우리가 귀하의 서비스 요청과 지원 요청에 더 효과적으로 응답할 수 있게 돕습니다.</li> - <li>주기적인 이메일을 보내기 위해 — 귀하가 제공하는 이메일 주소는 귀하에게 정보, 귀하가 요청하는 주제에 대한 변경과 귀하의 유저 이름에 대한 응답에 대한 알림, 문의에 대한 답, 또는 다른 요청과 질문을 보내는 데에 사용될 수 있습니다.</li> - </ul> - - <h3 id="protect">우리가 어떻게 귀하의 정보를 보호하나요?</h3> - - <p>우리는 귀하가 개인정보를 입력, 제출, 접근 할 때 귀하의 개인정보의 안전을 유지하기 위한 여러가지 보안 방법을 구현합니다.</p> - - <h3 id="data-retention">정보 보관 정책은 어떻게 되나요?</h3> - - <p>우리는 다음과 같이 노력 하겠습니다:</p> - - <ul> - <li>모든 요청에 대한 IP 주소를 담고 있는 서버 로그를 최대 90일까지 보관합니다.</li> - <li>등록된 사용자와 관련된 IP 주소와 그들의 게시물들을 최대 5년까지 보관합니다.</li> - </ul> - - <h3 id="cookies">쿠키를 사용하나요?</h3> - - <p>네. 쿠키는 사이트나 서비스 제공자가 (만약 허용하신다면) 웹 브라우저를 통해 귀하의 컴퓨터 하드디스크에 전송하는 작은 파일들입니다. 이 쿠키들은 사이트가 귀하의 브라우저를 인식하게 하고, 만약 가입한 계정이 있다면 브라우저를 가입한 계정과 연관짓는 일을 가능하게 합니다.</p> - - <p>우리는 쿠키를 사용해 귀하의 환경설정을 미래의 방문을 위해 저장하고, 사이트 접근 기록과 사이트 상호작용 기록을 모아 미래에 우리가 더 나은 사이트 경험과 도구를 제공할 수 있도록 합니다. 우리는 제 3자의 서비스 제공자와 계약하여 우리 사이트의 방문자에 대해 더 나은 이해를 하기 위해 도움을 받을 수 있습니다. 이러한 서비스 제공자들은 우리가 더 나은 서비스를 제공하도록 돕는 목적 외에는 이 정보를 사용할 수 없습니다.</p> - - <h3 id="disclose">우리가 외부에 정보를 공개하나요?</h3> - - <p>우리는 귀하를 식별할 수 있는 정보를 외부에 팔거나, 거래하거나, 전송하지 않습니다. 이는 우리가 우리의 사이트를 운영하고, 사업을 하고, 귀하에게 서비스를 제공하는 데에 도움을 주는 믿을 수 있는 제 3자의 서비스 제공자를 포함하지 않으며, 이는 그 서비스 제공자가 이 정보를 비밀로 취급하는 것에 동의하는지에 따라 다릅니다. 우리는 또한 법을 지키는 것, 우리 사이트의 정책을 집행하는 것, 우리와 다른 사람들의 권리, 재산, 안전을 보호하는 것으로 인해 정보 공개가 적합하다고 생각되면 정보를 공개 할 수 있습니다. 그러나, 귀하를 식별할 수 없는 방문자 정보는 외부에 마케팅, 광고, 혹은 다른 용도로 제공될 수 있습니다.</p> - - <h3 id="third-party">제 3자 링크</h3> - - <p>종종, 우리의 재량에 따라 우리의 사이트에 제 3자의 상품이나 서비스를 포함하거나 제공할 수 있습니다. 이러한 제 3자 사이트는 독립적인 개인정보 정책을 가지고 있습니다. 이러한 링크된 제 3자 사이트의 내용과 활동에 대해서 우리는 어떠한 의무와 법적 책임을 가지고 있지 않습니다. 그래도 우리는 그 사이트에 대한 피드백을 환영하며, 우리 사이트만의 정체성을 유지하도록 노력하겠습니다.</p> - - <h3 id="coppa">아동 온라인 사생활 보호법 준수</h3> - - <p>우리 사이트, 제품과 서비스는 적어도 13살인 사람들에게 맞춰져 있습니다. 만약 이 서버가 미합중국에 위치하고, 귀하가 13살이 되지 않는다면, COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) 의 요구사항에 따라 이 사이트를 이용하지 마십시오.</p> - - <h3 id="online">온라인 사생활 정책 한정</h3> - - <p>이 온라인 사생활 정책은 우리 사이트를 통해 수집된 정보에게만 적용되며, 오프라인에서 수집된 정보에는 적용되지 않습니다.</p> - - <h3 id="consent">귀하의 동의</h3> - - <p>우리의 사이트를 사용함으로서, 귀하는 우리 사이트의 사생활 정책에 동의합니다.</p> - - <h3 id="changes">사생활 정책의 변경</h3> - - <p>만약 우리가 사생활 정책을 변경하도록 결정한다면, 우리는 그 변경사항을 이 페이지에 게시하겠습니다.</p> - - <p>이 문서는 CC-BY-SA 정책으로 배포됩니다. 마지막으로 2013년 3월 31일에 수정되었습니다.</p> - - <p><a href="https://github.com/discourse/discourse">Discourse privacy policy</a>에서 가져옴.</p> title: "%{instance} 이용약관과 개인정보 취급 방침" time: formats: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 03500a839..16e68fffe 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -665,74 +665,6 @@ nl: reblogged: boostte sensitive_content: Gevoelige inhoud terms: - body_html: | - <h2>Privacy Policy</h2> - - <h3 id="collect">What information do we collect?</h3> - - <p>We collect information from you when you register on our site and gather data when you participate in the forum by reading, writing, and evaluating the content shared here.</p> - - <p>When registering on our site, you may be asked to enter your name and e-mail address. You may, however, visit our site without registering. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address.</p> - - <p>When registered and posting, we record the IP address that the post originated from. We also may retain server logs which include the IP address of every request to our server.</p> - - <h3 id="use">What do we use your information for?</h3> - - <p>Any of the information we collect from you may be used in one of the following ways:</p> - - <ul> - <li>To personalize your experience — your information helps us to better respond to your individual needs.</li> - <li>To improve our site — we continually strive to improve our site offerings based on the information and feedback we receive from you.</li> - <li>To improve customer service — your information helps us to more effectively respond to your customer service requests and support needs.</li> - <li>To send periodic emails — The email address you provide may be used to send you information, notifications that you request about changes to topics or in response to your user name, respond to inquiries, and/or other requests or questions.</li> - </ul> - - <h3 id="protect">How do we protect your information?</h3> - - <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information.</p> - - <h3 id="data-retention">What is your data retention policy?</h3> - - <p>We will make a good faith effort to:</p> - - <ul> - <li>Retain server logs containing the IP address of all requests to this server no more than 90 days.</li> - <li>Retain the IP addresses associated with registered users and their posts no more than 5 years.</li> - </ul> - - <h3 id="cookies">Do we use cookies?</h3> - - <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p> - - <p>We use cookies to understand and save your preferences for future visits and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business.</p> - - <h3 id="disclose">Do we disclose any information to outside parties?</h3> - - <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.</p> - - <h3 id="third-party">Third party links</h3> - - <p>Occasionally, at our discretion, we may include or offer third party products or services on our site. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these sites.</p> - - <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> - - <p>Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p> - - <h3 id="online">Online Privacy Policy Only</h3> - - <p>This online privacy policy applies only to information collected through our site and not to information collected offline.</p> - - <h3 id="consent">Your Consent</h3> - - <p>By using our site, you consent to our web site privacy policy.</p> - - <h3 id="changes">Changes to our Privacy Policy</h3> - - <p>If we decide to change our privacy policy, we will post those changes on this page.</p> - - <p>This document is CC-BY-SA. It was last updated May 31, 2013.</p> - - <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: "%{instance} Terms of Service and Privacy Policy" time: formats: diff --git a/config/locales/no.yml b/config/locales/no.yml index 3adf71bee..d5edb3975 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -633,74 +633,6 @@ reblogged: fremhevde sensitive_content: Følsomt innhold terms: - body_html: | - <h2>Personvernserklæring</h2> - - <h3 id='collect'>Hvilke opplysninger samler vi?</h3> - - <p>Vi samler opplysninger fra deg når du registrerer deg på nettstedet vårt, og vi samler data når du deltar på forumet ved å lese, skrive og evaluere innholdet som deles her.</p> - - <p>Når du registrerer deg på nettstedet vårt, kan du bli bedt om å oppgi navnet og e-postadressen din. Imidlertid kan du besøke nettstedet vårt uten å registrere deg. E-postadressen din vil bli bekreftet med en e-post som inneholder en unik lenke. Hvis siden den lenker til, blir besøkt, vet vi at du har kontroll over e-postadressen.</p> - - <p>Når du registrerer deg og skriver innlegg, registrerer vi IP-adressen som innlegget stammer fra. Vi kan også oppbevare logger som inkluderer IP-adressen til alle forespørslene sendt til tjeneren vår.</p> - - <h3 id='use'>Hva bruker vi opplysningene dine til?</h3> - - <p>Alle opplysningene vi samler fra deg, kan bli brukt på en av følgende måter:</p> - - <ul> - <li>For å gjøre opplevelsen din mer personlig. Opplysningene dine hjelper oss å svare bedre på dine individuelle behov.</li> - <li>For å forbedre nettstedet vårt. Vi jobber konstant for å forbedre nettstedets tilbud basert på opplysningene og tilbakemeldingene vi mottar fra deg.</li> - <li>For å forbedre vår kundeservice. Dine opplysninger hjelper oss å svare mer effektivt på dine forespørsler sendt til kundeservice eller behov om støtte.</li> - <li>For å sende periodiske e-poster. E-postadressen du oppgir, kan bli brukt til å sende deg informasjon, påminnelser som du ber om ved endringer av emner eller ved svar til brukernavnet ditt, til henvendelser, og/eller andre forspørsler eller andre spørsmål.</li> - </ul> - - <h3 id='protect'>Hvordan sikrer vi opplysningene?</h3> - - <p>Vi gjennomfører flere sikkerhetstiltak for å holde personopplysningene dine sikre når du skriver inn, lagrer eller henter dem.</p> - - <h3 id='data-retention'>Hva er retningslinjene deres for lagring av data?</h3> - - <p>Vi vil forsøke i god tro å:</p> - - <ul> - <li>Ikke oppbevare tjener-logger som inneholder IP-adressen til alle forespørslene til denne tjeneren i lenger enn i 90 dager.</li> - <li>Ikke oppbevare IP-adressene forbundet med registrerte brukere og deres innlegg lenger enn i 5 år.</li> - </ul> - - <h3 id='cookies'>Bruker vi informasjonskapsler?</h3> - - <p>Ja. Informasjonskapsler er små filer som et nettsted eller dets tjenesteleverandør overfører til harddisken på datamaskinen din gjennom nettleseren din (dersom du tillater det). Disse informasjonskapslene gjør det mulig for nettstedet å gjenkjenne nettleseren din og, dersom du har en konto, knytte nettleseren til den.</p> - - <p>Vi bruker informasjonskapsler for å forstå og lagre preferansene dine for fremtidige besøk og for å samle aggregatdata om trafikk på og samhandling med nettstedet slik at vi kan tilby bedre opplevelser og verktøy på nettstedet i fremtiden. Vi kan inngå avtaler med tredjeparts tjenesteleverandører for å bistå oss i å forstå besøkerne våres bedre. Disse tjenesteleverandørene har ikke lov til å bruke opplysningene samlet på våres vegne unntatt til å hjelpe oss å gjennomføre og forbedre anliggendet vårt.</p> - - <h3 id='disclose'>Gir vi noen opplysninger videre til andre parter?</h3> - - <p>Vi verken selger, handler med eller overfører på noen annen måte til andre parter dine identifiserbare personopplysninger. Dette inkluderer ikke tredjeparter som har vår tillit og bistår oss i å drive nettstedet, utføre våre anliggender eller yter tjenester til deg, så lenge disse partene samtykker til å behandle disse opplysningene fortrolig. Vi kan også frigi opplysningene dine dersom vi tror at å frigi dem er hensiktsmessig for å overholde loven, håndheve nettstedet retningslinjer eller beskytte våre og andres rettigheter. Imidlertid kan opplysninger som ikke er personlig identifiserbare, bli delt med andre parter for markedsføring, reklame eller annet bruk.</p> - - <h3 id='third-party'>Tredjeparts lenker</h3> - - <p>Av og til, etter skjønn, kan vil inkludere eller tilby tredjeparts produkter eller tjenester på nettstedet vårt. Disse tredjeparts nettstedene har separate og selvstendige personvernerklæringer. Vi bærer derfor intet ansvar eller forpliktelser for innholdet eller aktivitetene til disse nettstedene det lenkes til. Ikke mindre prøver vi å bevare vår eget nettsteds integritet og ønsker enhver tilbakemelding om disse nettstedene velkomne.</p> - - <h3 id='coppa'>Overensstemmelse med Children's Online Privacy Protection Act</h3> - - <p>Nettstedet er rettet mot folk som er minst 13 år gamle. Dersom denne tjeneren er i USA, og du er under 13 år i henhold til kravene i COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>), ikke bruk dette nettstedet.</p> - - <h3 id='online'>Personvernerklæring bare for nettet</h3> - - <p>Denne nett-personvernerklæringen gjelder bare for informasjon samlet gjennom nettstedet vårt og ikke for opplysninger samlet når en er frakoblet.</p> - - <h3 id='consent'>Ditt samtykke</h3> - - <p>Ved å bruke dette nettstedet samtykker du til nettstedets personvernerklæring.</p> - - <h3 id='changes'>Endringer i vår personvernerklæring</h3> - - <p>Dersom vi beslutter å endre personvernerklæringen vår, vil vi publisere disse endringene på denne siden.</p> - - <p>Dette dokumentet er lisensiert under CC-BY-SA. De ble sist oppdatert 12. april 2017.</p> - - <p>Dokumentet er en adoptert og endret versjon fra <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: "%{instance} Personvern og villkår for bruk av nettstedet" themes: default: Mastodon diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 49b1df8bf..f8e819c53 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -742,74 +742,6 @@ oc: reblogged: a partejat sensitive_content: Contengut sensible terms: - body_html: | - <h2>Politica de confidencialitat</h2> - - <h3 id="collect">Quinas informacions reculhèm ?</h3> - - <p>Collectem informacions sus vos quand vos marcatz sus nòstre site e juntem las donadas quand participatz a nòstre forum en legir, escriure e notar lo contengut partejat aquí.</p> - - <p>Pendent l’inscripcion podèm vos demandar vòstre nom e adreça de corrièl. Podètz çaquelà visitar nòstre site sens vos marcar. Verificarem vòstra adreça amb un messatge donant un ligam unic. Se clicatz sul ligam sauprem qu’avètz lo contraròtle de l’adreça.</p> - - <p>Quand sètz marcat e que publicatz quicòm, enregistrem l’adreça IP d’origina. Podèm tanben salvagardar los jornals del servidor que tenon l’adreça IP de totas las demandas fachas al nòstre servidor.</p> - - <h3 id="use">Qué fasèm de vòstras informacions ?</h3> - - <p>Totas las informacions que collectem de vos pòdon servir dins los cases seguents :</p> - - <ul> - <li>Per personalizar vòstre experiéncia — vòstras informacions nos ajudaràn a respondre melhor a vòstres besonhs individuals.</li> - <li>Per melhorar nòstre site — s’eforcem de longa a melhorar çò que nòstre site ofrís segon las informacions e los comentaris que recebèm de vòstra part.</li> - <li>Per melhorar nòstre servici client — vòstras informacions nos ajudan per respondre amb mai eficacitat a vòstras demandas d’assisténcia.</li> - <li>Per enviar periodicament de corrièls — Podèm utilizar l’adreça qu’avètz donada per vos enviar d’informacions e de notificacions que demandatz tocant de cambiaments dins los subjèctes del forum o en responsa a vòstre nom d’utilizaire, en responsa a una demanda, e/o tota autra question.</li> - </ul> - - <h3 id="protect">Cossí protegèm vòstras informacions ?</h3> - - <p>Apliquem tota una mena de mesuras de seguretat per manténer la fisança de vòstras informacions personalas quand las picatz, mandatz, o i accedètz.</p> - - <h3 id="data-retention">Quala es vòstra politica de conservacion de donadas ?</h3> - - <p>Farem esfòrces per :</p> - - <ul> - <li>Gardar los jornals del servidor que contenon las adreças IP de totas las demandas al servidor pas mai de 90 jorns.</li> - <li>Gardar las adreças IP ligadas als utilizaires e lors publicacions pas mai de 5 ans.</li> - </ul> - - <h3 id="cookies">Empleguem de cookies ?</h3> - - <p>Òc-ben. Los cookies son de pichons fichièrs qu’un site o sos provesidors de servicis plaçan dins lo disc dur de vòstre ordenador via lo navigator Web (Se los acceptatz). Aqueles cookies permeton al site de reconéisser vòstre navigator e se tenètz un compte enregistrat de l’associar a vòstre compte.</p> - - <p>Empleguem de cookies per comprendre e enregistrar vòstras preferéncias per vòstras visitas venentas, per recampar de donadas sul trafic del site e las interaccions per dire que posquem ofrir una melhora experiéncia del site e de las aisinas pel futur. Pòt arribar que contractèssem amb de provesidors de servicis tèrces per nos ajudar a comprendre melhor nòstres visitors. Aqueles provesidors an pas lo drech que d’utilizar las donadas collectadas per nos ajudar a menar e melhorar nòstre afar.</p> - - <h3 id="disclose">Divulguem d’informacions a de tèrces ?</h3> - - <p>Vendèm pas, comercem o qualque transferiment que siasque a de tèrces vòstras informacions personalas identificablas. Aquò inclutz pas los tèrces partits de confisança que nos assiston a menar nòstre site, menar nòstre afar o vos servir, baste que son d’acòrd per gardar aquelas informacions confidencialas. Pòt tanben arribar que liberèssem vòstras informacions quand cresèm qu’es apropriat d’o far per se sometre a la lei, per refortir nòstras politicas, o per protegir los dreches, proprietats o seguritat de qualqu’un o de nosautres. Pasmens es possible que mandèssem d’informacions non-personalas e identificablas de nòstres visitors a d’autres partits per d’utilizacion en marketing, publicitat o un emplec mai.</p> - - <h3 id="third-party">Ligams de tèrces</h3> - - <p>Pòt arribar, a nòstra discrecion, qu’incluguèssem o ofriguèssem de produches o servicis de tèrces partits sus nòstre site. Aqueles sites tèrces an de politicas de confidencialitats separadas e independentas. En consequéncia avèm pas cap de responsabilitat pel contengut e las activitats d’aqueles sites ligats. Pasmens cerquem de protegir l’integritat de nòstre site e aculhèm los comentaris tocant aqueles sites.</p> - - <h3 id="coppa">Conformitat amb la lei de proteccion de la confidencialitat dels mainatges</h3> - - <p>Nòstre site, nòstres produches e servicis son totes destinats a de monde d’almens 13 ans. S’aqueste servidor se tròba en los Estats Units per acontentar las exigéncias del COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) utilizetz pas aqueste site.</p> - - <h3 id="online">Politica de confidencialitat en linha solament</h3> - - <p>Aquesta politica de confidencialitat s’aplica pas qu’a las informacions collectadas via nòstre site e non pas a las informacions collectadas fòra linha.</p> - - <h3 id="consent">Vòstre consentiment</h3> - - <p>N’utilizant nòstre site, consentètz a nòstra politica de confidencialitat.</p> - - <h3 id="changes">Cambiament dins nòstra politica de confidencialitat</h3> - - <p>Se decidèm de cambiar nòstra politica de confidencialitat, publicarem los cambiaments sus aquesta pagina.</p> - - <p>Aqueste document es jos licéncia CC-BY-SA. Darrièra mesa a jorn lo 31 de mai de 2013</p> - - <p>Prima adaptacion de la <a href="https://github.com/discourse/discourse">politica de confidencialitat de Discourse</a>.</p> title: Condicions d’utilizacion e politica de confidencialitat de %{instance} time: formats: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 2bd50f28c..a71f48758 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -713,72 +713,81 @@ pl: terms: body_html: | <h2>Polityka prywatności</h2> - <h3 id="collect">Jakie informacje zbieramy?</h3> - <p>Zbieramy informacje podane przy rejestracji i treści utworzone w trakcie korzystania z serwisu.</p> - - <p>Podczas rejestracji, możesz otrzymać prośbę o podanie adresu e-mail. Możesz jednak odwiedzać stronę bez rejestracji. Adres zostanie zweryfikowany przez kliknięcie w link wysłany w wiadomości. Dzięki temu wiemy, że jesteś właścicielem tego adresu.</p> + <ul> + <li><em>Podstawowe informacje o koncie</em>: Podczas rejestracji na tym serwerze, możesz zostać poproszony o wprowadzenie nazwy użytkownika, adresu e-mail i hasła. Możesz także wprowadzić dodatkowe informacje o profilu, takie jak nazwa wyświetlana i biografia oraz wysłać awatar i obraz nagłówka. Nazwa użytkownika, nazwa wyświetlana, biografia, awatar i obraz nagłówka są zawsze widoczne dla wszystkich.</li> + <li><em>Wpisy, śledzenie i inne publiczne informacje</em>: Lista osób które śledzisz jest widoczna publicznie, tak jak lista osób, które Cię śledzą. Jeżeli dodasz wpis, data i czas jego utworzenia i aplikacja, z której go wysłano są przechowywane. Wiadomości mogą zawierać załączniki multimedialne, takie jak zdjęcia i filmy. Publiczne i niewidoczne wpisy są dostępne publicznie. Udostępniony wpis również jest widoczny publicznie. Twoje wpisy są dostarczane obserwującym, co oznacza że jego kopie mogą zostać dostarczone i być przechowywane na innych serwerach. Kiedy usuniesz wpis, przestaje być widoczny również dla osób śledzących Cię. „Podbijanie” i dodanie do ulubionych jest zawsze publiczne.</li> + <li><em>Wpisy bezpośrednie i tylko dla śledzących</em>: Wszystkie wpisy są przechowywane i przetwarzane na serwerze. Wpisy przeznaczone tylko dla śledzących są widoczne tylko dla nich i osób wspomnianych we wpisie, a wpisy bezpośrednie tylko dla wspimnianych. W wielu przypadkach oznacza to, że ich kopie są dostarczane i przechowywane na innych serwerach. Staramy się ograniczać zasięg tych wpisów wyłącznie do właściwych odbiorców, ale inne serwery mogą tego nie robić. Ważne jest, aby sprawdzać jakich serwerów używają osoby, które Cię śledzą. Możesz aktywować opcję pozwalającą na ręczne akceptowanie i odrzucanie nowych śledzących. <em>Pamiętaj, że właściciele serwerów mogą zobaczyć te wiadomości</em>, a odbiorcy mogą wykonać zrzut ekranu, skopiować lub udostępniać ten wpis. <em>Nie udostępniaj wrażliwych danych z użyciem Mastodona.</em></li> + <li><em>Adresy IP i inne metadane</em>: Kiedy zalogujesz się, przechowujemy adres IP użyty w trakcie logowania wraz z nazwą używanej przeglądarki. Wszystkie aktywne sesje możesz zobaczyć (i wygasić) w ustawieniach. Ostatnio używany adres IP jest przechowywany przez nas do 12 miesięcy. Możemy również przechowywać adresy IP wykorzystywane przy każdym działaniu na serwerze.</li> + </ul> - <p>Podczas rejestracji i tworzenia wpisów, Twój adres IP jest zapisywany na naszych serwerach. Możemy też przechowywać adres IP użyty przy każdej operacji w serwisie.</p> + <hr class="spacer" /> - <h3 id="use">Jak wykorzystujemy zebrane informacje?</h3> + <h3 id="use">W jakim celu wykorzystujecie informacje?</h3> - <p>Zebrane informacje mogą zostać w jednym z następujących celach:</p> + <p>Zebrane informacje mogą zostać użyte w następujące sposoby:</p> <ul> - <li>Aby poprawić wrażenia — informacje o Tobie pomagają w dostosowywaniu serwisu do Twoich potrzeb.</li> - <li>Aby usprawnić stronę — nieustannie staramy się ulepszyć stronę na podstawie informacji o Tobie i Twoich opinii.</li> - <li>Aby usprawnić obsługę klienta — informacje pomogą obsłudze klienta utrzymywać kontakt z Tobą.</li> - <li>Aby okazjonalnie wysyłać wiadomości e-mail — Na podany adres e-mail mogą zostać wysłane wiadomości o wspomnieniu o Tobie we wpisach, przejrzeniu Twojego zgłoszenia i innych interakcji z Tobą.</li> + <li>Aby dostarczyć podstawową funkcjonalność Mastodona. Możesz wchodzić w interakcje z zawartością tworzoną przez innych tylko gdy jesteś zalogowany. Na przykład, możesz śledzić innych, aby widzieć ich wpisy w dostosowanej osi czasu.</li> + <li>Aby wspomóc moderację społeczności, na przykład porównując Twój adres IP ze znanymi, aby rozpoznać próbę obejścia blokady i inne naruszenia.</li> + <li>Adres e-mail może zostać wykorzystany, aby wysyłać Ci informacje, powiadomienia o osobach wchodzących w interakcje z tworzoną przez Ciebie zawartością, wysyłających Ci wiadomości, odpowiadać na zgłoszenia i inne żądania lub zapytania.</li> </ul> - <h3 id="protect">Jak zabezpieczamy dane?</h3> + <hr class="spacer" /> + + <h3 id="protect">W jaki sposób chronimy Twoje dane?</h3> - <p>Korzystamy z wielu zabezpieczeń, aby utrudnić osobom niepowołanym dostęp do danych, które wprowadzasz, publikujesz i czytasz.</p> + <p>Wykorzystujemy różne zabezpieczenia, aby zapewnić bezpieczeństwo informacji, które wprowadzasz, wysyłasz lub do których uzyskujesz dostęp. Poza tym, sesja przeglądarki oraz ruch pomiędzy aplikacją a API jest zabezpieczany z użyciem SSL, a hasło jest hashowane z użyciem silnego algorytmu. Możesz też aktywować uwierzytelnianie dwustopniowe, aby lepiej zabezpieczyć dostęp do konta.</p> - <h3 id="data-retention">Jak długo przechowujecie dane?</h3> + <hr class="spacer" /> - <p>Dołożymy wszelkich starań, aby przechowywać:</p> + <h3 id="data-retention">Jaka jest nasza polityka przechowywania danych?</h3> + + <p>Staramy się:</p> <ul> - <li>dzienniki serwera zawierające adresy IP przypisane do każdych operacji nie dłużej niż 90 dni.</li> - <li>adresy IP przypisane do użytkowników i ich wpisów nie dłużej niż 5 lat.</li> + <li>Przechowywać logi zawierające adresy IP używane przy każdym żądaniu do serwera przez nie dłużej niż 90 dni.</li> + <li>Przechowywać adresy IP przypisane do użytkowników przez nie dłużej niż 12 miesięcy.</li> </ul> - <h3 id="cookies">Czy używamy plików cookies?</h3> + <p>Możesz zażądać i pobrać archiwum tworzonej zawartości, wliczając Twoje wpisy, załączniki multimedialne, awatar i zdjęcie nagłówka.</p> - <p>Tak. Pliki cookies (zwane często ciasteczkami) są małymi zbiorami danych przechowywanych na Twoim dysku przez stronę internetową, aby rozpoznawać przeglądarkę i powiązać ją (jeżeli jesteś zarejestrowany/a) z Twoim kontem, jeżeli na to pozwolisz.</p> + <p>Możesz nieodwracalnie usunąć konto w każdej chwili.</p> - <p>Możemy używać ciasteczek, aby skonfigurować stronę na podstawie zapisanych preferencji, oraz dostosować ją do potrzeb innych użytkowników. Możemy korzystać z usług firm trzecich pomagających w zrozumieniu potrzeb użytkownika. Te usługi nie mogą korzystać ze zdobytych danych w celach innych niż analiza pomagająca ulepszać ten serwis.</p> + <hr class="spacer"/> - <h3 id="disclose">Czy przekazujecie dane podmiotów trzecim?</h3> + <h3 id="cookies">Czy używany plików cookies?</h3> - <p>Nie dokonujemy transakcji danych pozwalających na identyfikację Twojej osoby umieszczonych na tym serwisie. Nie oznacza to, że nie przekazujemy ich zaufanym podmiotom, które korzystają z nich poufnie. Możemy jednak udostępniać dane, jeżeli jest to wymagane prawnie, lub dla utrzymania bezpieczeństwa strony i innych użytkowników. W celach marketingowych (i podobnych) mogą zostać użyte jedynie dane niepozwalające na identyfikację osoby.</p> + <p>Tak. Pliki cookies są małymi plikami, które strona lub dostawca jej usługi dostarcza na dysk twardy komputera z użyciem przeglądarki internetowej (jeżeli na to pozwoli). Pliki cookies pozwalają na rozpoznanie przeglądarki i – jeśli jesteś zarejestrowany – przypisanie jej do konta.</p> - <h3 id="third-party">Odnośniki do treści stron trzecich</h3> + <p>Wykorzystujemy pliki cookies, aby przechowywać preferencję użytkowników na przyszłe wizyty.</p> - <p>Czasem na stronie mogą pojawić się odnośniki do stron trzecich. Mają one odrębne regulaminy i politykę prywatności. Nie odpowiadamy więc za zawartość tych stron. Dokładamy jednak wszelkich starań, aby nie stanowiły one zagrożenia, prosimy jednak o opinie na temat ich wykorzystania.</p> + <hr class="spacer" /> - <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> + <h3 id="disclose">Czy przekazujemy informacje osobom trzecim?</h3> + + <p>Nie sprzedajemy, nie wymieniamy i nie przekazujemy osobom trzecim informacji pozwalających na identyfikację Ciebie. Nie dotyczy to zaufanym dostawcom pomagającym w prowadzeniu lub obsługiwaniu użytkowników, jeżeli zgadzają się, aby nie przekazywać dalej tych informacji. Możemy również udostępnić informacje, jeżeli uważany to za wymagane przez prawo, konieczne do wypełnienia polityki strony, przestrzegania naszych lub cudzych praw, własności i bezpieczeństwa.</p> - <p>Ta strona i usługa jest przeznaczona dla osób, które ukończyły 13 lat. Jeżeli serwer znajduje się na terenie USA i nie masz ukończonych 13 lat, zgodnie z amerykańską ustawą COPPA (<a href="https://pl.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) nie możesz korzystać z tego serwisu.</p> + <p>Twoja publiczna zawartość może zostać pobrana przez inne serwery w sieci. Wpisy publiczne i tylko dla śledzących są dostarczane na serwery, na których znajdują się śledzący Cię, a wiadomości bezpośrednie trafiają na serwery adresatów, jeżeli są oni użytkownikami innego serwera.</p> - <h3 id="online">Polityka prywatności dotyczy tylko Internetu</h3> + <p>Kiedy pozwolisz aplikacji na dostęp do Twojego konta, w zależności od nadanych jej pozwoleń, może uzyskać dostęp do publicznych informacji, listy śledzonych, Twoich list, wszystkich wpisów i ulubionych. Aplikacje nie mogą uzyskać dostępu do Twojego adresu e-mail i hasła.</p> - <p>Ta polityka prywatności dotyczy jedynie danych zbieranych w Internecie, nie tych, które przechowywane są na Twoim komputerze, np. pliki cookies.</p> + <hr class="spacer" /> + + <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> - <h3 id="consent">Wyrażenie zgody</h3> + <p>Ta strona, produkty i usługi są przeznaczone dla osób, które ukończyły 13 lat. Jeżeli serwer znajduje się w USA, a nie ukończyłeś 13 roku życia, zgodnie z wymogami COPPA (<a href="https://pl.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Prawo o Ochronie Prywatności Dzieci w Internecie</a>), nie używaj tej strony.</p> - <p>Korzystanie ze strony jest równoznaczne z akceptacją naszej polityki prywatności.</p> + <hr class="spacer" /> <h3 id="changes">Zmiany w naszej polityce prywatności</h3> - <p>Jeżeli zdecydujemy się na zmiany w polityce prywatności, zmiany pojawią się na tej stronie.</p> + <p>Jeżeli zdecydujemy się na zmiany w polityce prywatności, pojawią się na tej stronie.</p> - <p>Dokument jest dostępny na licencji CC-BY-SA. Ostatnio modyfikowany 31 maja 2013, przetłumaczony 4 lipca 2017. Tłumaczenie (mimo dołożenia wszelkich starań) może nie być w pełni poprawne.</p> + <p>Dokument jest dostępny na licencji CC-BY-SA. Ostatnio zmodyfikowano go 7 marca 2018, przetłumaczono 9 kwietnia 2018. Tłumaczenie (mimo dołożenia wszelkich starań) może nie być w pełni poprawne.</p> - <p>Tekst bazuje na <a href="https://github.com/discourse/discourse">polityce prywatności Discourse</a>.</p> + <p>Bazowano na <a href="https://github.com/discourse/discourse">polityce prywatności Discourse</a>.</p> title: Zasady korzystania i polityka prywatności %{instance} time: formats: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 52da8efbd..ed7879525 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -665,74 +665,6 @@ pt-BR: reblogged: compartilhou sensitive_content: Conteúdo sensível terms: - body_html: | - <h2>Política de privacidade</h2> - - <h3 id="collect">Que informações nós coletamos?</h3> - - <p>Coletamos informações quando você se cadastra em nosso site e capturamos dados quando você participa do fórum lendo, escrevendo e analisando o conteúdo aqui compartilhado.</p> - - <p>Quando você se registrar em nosso site, será requisitado que você ceda seu nome e endereço de e-mail. Você pode, porém, visitar nosso site sem se cadastrar. Seu endereço de e-mail será verificado por uma mensagem contendo um link único. Se este link for visitado, saberemos que você controla este endereço de e-mail.</p> - - <p>Quando registrado e postando, nós gravamos o endereço de IP de onde a postagem se originou. Nós também podemos reter logs de serviores que incluem o endereço de IP em cada requisição para o nosso servidor.</p> - - <h3 id="use">Para que usamos essas informações?</h3> - - <p>Quaisquer das informações que coletamos podem ser usadas das seguintes formas:</p> - - <ul> - <li>Para personalizar a sua experiência — suas informações nos ajudam a nos adequar melhor às suas necessidades individuais.</li> - <li>Para melhorar nosso site — nós continuamente nos esforçamos para aprimorar nosso site baseados na informação e no feedback que recebemos de você.</li> - <li>Para aprimorar o serviço ao consumidor — suas informações nos ajudam a responder efetivamente às suas requisições e solicitações por suporte.</li> - <li>Para mandar e-mails periódicos — O endereço de e-mail que você forneceu pode ser usado para lhe enviar informações, notificações que você requisitar sobre mudanças a determinados tópicos ou menções ao seu nome de usuário, responder requisições e/ou solicitações e perguntas.</li> - </ul> - - <h3 id="protect">Como protegemos as suas informações?</h3> - - <p>Nós implementamos uma variedade de medidas de segurança para manter a segurança de suas informações pessoais quando você insere, submete ou acessa as suas informações pessoais.</p> - - <h3 id="data-retention">Qual a sua política de retenção de dados?</h3> - - <p>Faremos esforços de boa fé para:</p> - - <ul> - <li>Reter logs de servidor contendo o endereço IP de todas as requisições a este servidor por não mais que 90 dias.</li> - <li>Reter os endereços IP associados a usuários cadastrados e suas postagens por não mais que 5 anos.</li> - </ul> - - <h3 id="cookies">Nós usamos cookies?</h3> - - <p>Sim. Cookies são pequenos arquivos que um site ou o provedor de serviço transfere para o armazenamento interno de seu computador através de seu navegador (se você permitir). Estes cookies habilitam o site para reconhecer o seu navegador e, se você ter um cadastro, associá-lo a esta conta.</p> - - <p>Nós usamos cookies para entender e salvar as suas preferências para futuras visitas e compilar dados agregados sobre o tráfego do site para que possamos oferecer melhores experiências e ferramentas no futuro. Nós podemos contratar serviços de terceiros para nos auxiliar a entender melhor nossos visitantes. Estes provedores de serviço não são autoriza usar as informações coletadas em nosso nome exceto para nos ajudar a conduzir e aprimorar nosso funcionamento.</p> - - <h3 id="disclose">Nós revelamos informações para terceiros?</h3> - - <p>Nós não vendemos, tocamos ou transferimos para terceiros informações pessoais que te identificam. Isso não inclui partes em que confiamos para nos ajudar a operar nosso site, conduzir nosso funcionamento ou servir você desde que estes terceiros concordem em manter essas informações em segredo. Nós também podemos prover as suas informações para obedecer ordens judiciais, reforçar nossas políticas ou proteger nossos direitos ou de outrem, propriedades ou segurança. Entretanto, informações pessoais não identificáveis podem ser enviadas para outras partes para marketing, propaganda e outros usos.</p> - - <h3 id="third-party">Links de terceiros</h3> - - <p>Ocasionalmente, à nossa discrição, podemos icluir ou oferecer produtos ou serviços de terceiros em nosso site. Estes terceiros têm políticas de privacidade separadas e independentes. Nós, portanto, não nos responsabilizamos pelo conteúdo e atividades destes sites de terceiros. Occasionally, at our discretion, we may include or offer third party products or services on our site. Não obstante, nós procuramos proteger a integridade de nosso site e todo feedback sobre estes sites de terceiros é bem-vindo.</p> - - <h3 id="coppa">Obediência ao Ato de Proteção da Privacidade Online de Crianças</h3> - - <p>Nosso site, produtos e serviços são todos direcionados a pessoas que têm pelo menos 13 anos de idade. Se este servidor estiver nos EUA, e você tiver menos de 13 anos, pelos requerimentos da COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) não use este site.</p> - - <h3 id="online">Política de Apenas Privacidade Online</h3> - - <p>Esta política de privacidade online se aplica somente a informações coletadas por nosso site e não a informações coletadas offline.</p> - - <h3 id="consent">Seu Consentimento</h3> - - <p>Usando o nosso site, você concorda com a nossa política de privacidade.</p> - - <h3 id="changes">Mudanças em nossa Política de Privacidade</h3> - - <p>Se decidirmos mudar a nossa política de privacidade, publicaremos as mudanças nesta página.</p> - - <p>Este documento é CC-BY-SA. A sua última atualização aconteceu em 31 de maio de 2013.</p> - - <p>Originalmente adaptado da <a href="https://github.com/discourse/discourse">política de privacidade do Discourse</a>.</p> title: "%{instance} Termos de Serviço e Política de Privacidade" time: formats: @@ -775,7 +707,7 @@ pt-BR: tip_local_timeline: A timeline local é uma visão contínua das pessoas que estão em %{instance}. Esses são seus vizinhos próximos! tip_mobile_webapp: Se o seu navegador móvel oferecer a opção de adicionar Mastodon à tela inicial, você pode receber notificações push. Vai funcionar quase como um aplicativo nativo! tips: Dicas - title: Boas-vindas à bordo, %{name}! + title: Boas-vindas a bordo, %{name}! users: invalid_email: O endereço de e-mail é inválido invalid_otp_token: Código de autenticação inválido diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 5012e176f..27d4e88e3 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -635,74 +635,6 @@ pt: reblogged: boosted sensitive_content: Conteúdo sensível terms: - body_html: | - <h2>Política de privacidade</h2> - - <h3 id="collect">Quais são as informações que recolhemos?</h3> - - <p>Recolhemos informações quando te registas no nosso site e capturamos dados quando participas do fórum lendo, escrevendo e analisando o conteúdo aqui partilhado.</p> - - <p>Quando te registas no nosso site, será requisitado que você ceda seu nome e endereço de e-mail. Você pode, porém, visitar nosso site sem se cadastrar. Seu endereço de e-mail será verificado por uma mensagem contendo um link único. Se este link for visitado, saberemos que você controla este endereço de e-mail.</p> - - <p>Quando registrado e postando, nós gravamos o endereço de IP de onde a postagem se originou. Nós também podemos reter logs de serviores que incluem o endereço de IP em cada requisição para o nosso servidor.</p> - - <h3 id="use">Para que usamos essas informações?</h3> - - <p>Quaisquer das informações que coletamos podem ser usadas das seguintes formas:</p> - - <ul> - <li>Para personalizar a sua experiência — suas informações nos ajudam a nos adequar melhor às suas necessidades individuais.</li> - <li>Para melhorar nosso site — nós continuamente nos esforçamos para aprimorar nosso site baseados na informação e no feedback que recebemos de você.</li> - <li>Para aprimorar o serviço ao consumidor — suas informações nos ajudam a responder efetivamente às suas requisições e solicitações por suporte.</li> - <li>Para mandar e-mails periódicos — O endereço de e-mail que você forneceu pode ser usado para lhe enviar informações, notificações que você requisitar sobre mudanças a determinados tópicos ou menções ao seu nome de usuário, responder requisições e/ou solicitações e perguntas.</li> - </ul> - - <h3 id="protect">Como protegemos as suas informações?</h3> - - <p>Nós implementamos uma variedade de medidas de segurança para manter a segurança de suas informações pessoais quando você insere, submete ou acessa as suas informações pessoais.</p> - - <h3 id="data-retention">Qual a sua política de retenção de dados?</h3> - - <p>Faremos esforços de boa fé para:</p> - - <ul> - <li>Reter logs de servidor contendo o endereço IP de todas as requisições a este servidor por não mais que 90 dias.</li> - <li>Reter os endereços IP associados a usuários cadastrados e suas postagens por não mais que 5 anos.</li> - </ul> - - <h3 id="cookies">Nós usamos cookies?</h3> - - <p>Sim. Cookies são pequenos arquivos que um site ou o provedor de serviço transfere para o armazenamento interno de seu computador através de seu navegador (se você permitir). Estes cookies habilitam o site para reconhecer o seu navegador e, se você ter um cadastro, associá-lo a esta conta.</p> - - <p>Nós usamos cookies para entender e salvar as suas preferências para futuras visitas e compilar dados agregados sobre o tráfego do site para que possamos oferecer melhores experiências e ferramentas no futuro. Nós podemos contratar serviços de terceiros para nos auxiliar a entender melhor nossos visitantes. Estes provedores de serviço não são autoriza usar as informações coletadas em nosso nome exceto para nos ajudar a conduzir e aprimorar nosso funcionamento.</p> - - <h3 id="disclose">Nós revelamos informações para terceiros?</h3> - - <p>Nós não vendemos, tocamos ou transferimos para terceiros informações pessoais que te identificam. Isso não inclui partes em que confiamos para nos ajudar a operar nosso site, conduzir nosso funcionamento ou servir você desde que estes terceiros concordem em manter essas informações em segredo. Nós também podemos prover as suas informações para obedecer ordens judiciais, reforçar nossas políticas ou proteger nossos direitos ou de outrem, propriedades ou segurança. Entretanto, informações pessoais não identificáveis podem ser enviadas para outras partes para marketing, propaganda e outros usos.</p> - - <h3 id="third-party">Links de terceiros</h3> - - <p>Ocasionalmente, à nossa discrição, podemos icluir ou oferecer produtos ou serviços de terceiros em nosso site. Estes terceiros têm políticas de privacidade separadas e independentes. Nós, portanto, não nos responsabilizamos pelo conteúdo e atividades destes sites de terceiros. Occasionally, at our discretion, we may include or offer third party products or services on our site. Não obstante, nós procuramos proteger a integridade de nosso site e todo feedback sobre estes sites de terceiros é bem-vindo.</p> - - <h3 id="coppa">Obediência ao Ato de Proteção da Privacidade Online de Crianças</h3> - - <p>Nosso site, produtos e serviços são todos direcionados a pessoas que têm pelo menos 13 anos de idade. Se este servidor estiver nos EUA, e você tiver menos de 13 anos, pelos requerimentos da COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) não use este site.</p> - - <h3 id="online">Política de Apenas Privacidade Online</h3> - - <p>Esta política de privacidade online se aplica somente a informações coletadas por nosso site e não a informações coletadas offline.</p> - - <h3 id="consent">Seu Consentimento</h3> - - <p>Usando o nosso site, você concorda com a nossa política de privacidade.</p> - - <h3 id="changes">Mudanças em nossa Política de Privacidade</h3> - - <p>Se decidirmos mudar a nossa política de privacidade, publicaremos as mudanças nesta página.</p> - - <p>Este documento é CC-BY-SA. A sua última atualização aconteceu em 31 de maio de 2013.</p> - - <p>Originalmente adaptado da <a href="https://github.com/discourse/discourse">política de privacidade do Discourse</a>.</p> title: "%{instance} Termos de Serviço e Política de Privacidade" themes: default: Mastodon diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 108ca33e9..176ace92d 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -679,45 +679,6 @@ ru: reblogged: продвинул(а) sensitive_content: Чувствительный контент terms: - body_html: | - <h2>Privacy Policy</h2> - <h3 id="collect">What information do we collect?</h3> - <p>We collect information from you when you register on our site and gather data when you participate in the forum by reading, writing, and evaluating the content shared here.</p> - <p>When registering on our site, you may be asked to enter your name and e-mail address. You may, however, visit our site without registering. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address.</p> - <p>When registered and posting, we record the IP address that the post originated from. We also may retain server logs which include the IP address of every request to our server.</p> - <h3 id="use">What do we use your information for?</h3> - <p>Any of the information we collect from you may be used in one of the following ways:</p> - <ul> - <li>To personalize your experience — your information helps us to better respond to your individual needs.</li> - <li>To improve our site — we continually strive to improve our site offerings based on the information and feedback we receive from you.</li> - <li>To improve customer service — your information helps us to more effectively respond to your customer service requests and support needs.</li> - <li>To send periodic emails — The email address you provide may be used to send you information, notifications that you request about changes to topics or in response to your user name, respond to inquiries, and/or other requests or questions.</li> - </ul> - <h3 id="protect">How do we protect your information?</h3> - <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information.</p> - <h3 id="data-retention">What is your data retention policy?</h3> - <p>We will make a good faith effort to:</p> - <ul> - <li>Retain server logs containing the IP address of all requests to this server no more than 90 days.</li> - <li>Retain the IP addresses associated with registered users and their posts no more than 5 years.</li> - </ul> - <h3 id="cookies">Do we use cookies?</h3> - <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p> - <p>We use cookies to understand and save your preferences for future visits and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business.</p> - <h3 id="disclose">Do we disclose any information to outside parties?</h3> - <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.</p> - <h3 id="third-party">Third party links</h3> - <p>Occasionally, at our discretion, we may include or offer third party products or services on our site. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these sites.</p> - <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> - <p>Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p> - <h3 id="online">Online Privacy Policy Only</h3> - <p>This online privacy policy applies only to information collected through our site and not to information collected offline.</p> - <h3 id="consent">Your Consent</h3> - <p>By using our site, you consent to our web site privacy policy.</p> - <h3 id="changes">Changes to our Privacy Policy</h3> - <p>If we decide to change our privacy policy, we will post those changes on this page.</p> - <p>This document is CC-BY-SA. It was last updated May 31, 2013.</p> - <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: Условия обслуживания и политика конфиденциальности %{instance} themes: default: Mastodon diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 2d984049a..8d39d35b0 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -625,74 +625,6 @@ sr-Latn: reblogged: podržano sensitive_content: Osetljiv sadržaj terms: - body_html: | - <h2>Privacy Policy</h2> - - <h3 id="collect">What information do we collect?</h3> - - <p>We collect information from you when you register on our site and gather data when you participate in the forum by reading, writing, and evaluating the content shared here.</p> - - <p>When registering on our site, you may be asked to enter your name and e-mail address. You may, however, visit our site without registering. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address.</p> - - <p>When registered and posting, we record the IP address that the post originated from. We also may retain server logs which include the IP address of every request to our server.</p> - - <h3 id="use">What do we use your information for?</h3> - - <p>Any of the information we collect from you may be used in one of the following ways:</p> - - <ul> - <li>To personalize your experience — your information helps us to better respond to your individual needs.</li> - <li>To improve our site — we continually strive to improve our site offerings based on the information and feedback we receive from you.</li> - <li>To improve customer service — your information helps us to more effectively respond to your customer service requests and support needs.</li> - <li>To send periodic emails — The email address you provide may be used to send you information, notifications that you request about changes to topics or in response to your user name, respond to inquiries, and/or other requests or questions.</li> - </ul> - - <h3 id="protect">How do we protect your information?</h3> - - <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information.</p> - - <h3 id="data-retention">What is your data retention policy?</h3> - - <p>We will make a good faith effort to:</p> - - <ul> - <li>Retain server logs containing the IP address of all requests to this server no more than 90 days.</li> - <li>Retain the IP addresses associated with registered users and their posts no more than 5 years.</li> - </ul> - - <h3 id="cookies">Do we use cookies?</h3> - - <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p> - - <p>We use cookies to understand and save your preferences for future visits and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business.</p> - - <h3 id="disclose">Do we disclose any information to outside parties?</h3> - - <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.</p> - - <h3 id="third-party">Third party links</h3> - - <p>Occasionally, at our discretion, we may include or offer third party products or services on our site. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these sites.</p> - - <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> - - <p>Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p> - - <h3 id="online">Online Privacy Policy Only</h3> - - <p>This online privacy policy applies only to information collected through our site and not to information collected offline.</p> - - <h3 id="consent">Your Consent</h3> - - <p>By using our site, you consent to our web site privacy policy.</p> - - <h3 id="changes">Changes to our Privacy Policy</h3> - - <p>If we decide to change our privacy policy, we will post those changes on this page.</p> - - <p>This document is CC-BY-SA. It was last updated May 31, 2013.</p> - - <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: Uslovi korišćenja i politika privatnosti instance %{instance} themes: default: Mastodont diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 2daf32915..af4c6a846 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -625,74 +625,6 @@ sr: reblogged: подржано sensitive_content: Осетљив садржај terms: - body_html: | - <h2>Privacy Policy</h2> - - <h3 id="collect">What information do we collect?</h3> - - <p>We collect information from you when you register on our site and gather data when you participate in the forum by reading, writing, and evaluating the content shared here.</p> - - <p>When registering on our site, you may be asked to enter your name and e-mail address. You may, however, visit our site without registering. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address.</p> - - <p>When registered and posting, we record the IP address that the post originated from. We also may retain server logs which include the IP address of every request to our server.</p> - - <h3 id="use">What do we use your information for?</h3> - - <p>Any of the information we collect from you may be used in one of the following ways:</p> - - <ul> - <li>To personalize your experience — your information helps us to better respond to your individual needs.</li> - <li>To improve our site — we continually strive to improve our site offerings based on the information and feedback we receive from you.</li> - <li>To improve customer service — your information helps us to more effectively respond to your customer service requests and support needs.</li> - <li>To send periodic emails — The email address you provide may be used to send you information, notifications that you request about changes to topics or in response to your user name, respond to inquiries, and/or other requests or questions.</li> - </ul> - - <h3 id="protect">How do we protect your information?</h3> - - <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information.</p> - - <h3 id="data-retention">What is your data retention policy?</h3> - - <p>We will make a good faith effort to:</p> - - <ul> - <li>Retain server logs containing the IP address of all requests to this server no more than 90 days.</li> - <li>Retain the IP addresses associated with registered users and their posts no more than 5 years.</li> - </ul> - - <h3 id="cookies">Do we use cookies?</h3> - - <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p> - - <p>We use cookies to understand and save your preferences for future visits and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business.</p> - - <h3 id="disclose">Do we disclose any information to outside parties?</h3> - - <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.</p> - - <h3 id="third-party">Third party links</h3> - - <p>Occasionally, at our discretion, we may include or offer third party products or services on our site. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these sites.</p> - - <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> - - <p>Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p> - - <h3 id="online">Online Privacy Policy Only</h3> - - <p>This online privacy policy applies only to information collected through our site and not to information collected offline.</p> - - <h3 id="consent">Your Consent</h3> - - <p>By using our site, you consent to our web site privacy policy.</p> - - <h3 id="changes">Changes to our Privacy Policy</h3> - - <p>If we decide to change our privacy policy, we will post those changes on this page.</p> - - <p>This document is CC-BY-SA. It was last updated May 31, 2013.</p> - - <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p> title: Услови коришћења и политика приватности инстанце %{instance} themes: default: Мастодонт diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 8ce6b3100..f85ed6efb 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -656,74 +656,6 @@ sv: reblogged: boostad sensitive_content: Känsligt innehåll terms: - body_html: | - <h2>Integritetspolicy</h2> - - <h3 id="collect">Vilken information samlar vi in</h3> - - <p>Vi samlar in information från dig när du registrerar dig på vår webbplats och samlar in data när du deltar i forumet genom att läsa, skriva och utvärdera innehållet som delas här.</p> - - <p>När du registrerar dig på vår webbplats kan du bli ombedd att ange ditt namn och din e-postadress. Du kan dock besöka vår webbplats utan att registrera dig. Din e-postadress kommer att verifieras med ett e-postmeddelande som innehåller en unik länk. Om den länken besöks vet vi att du kontrollerar e-postadressen.</p> - - <p>När vi registrerar och postar registrerar vi den IP-adress som posten härstammar från. Vi kan också behålla serverns loggar som innehåller IP-adress för varje begäran till vår server.</p> - - <h3 id="use">Vad använder vi din information för?</h3> - - <p>Vilken som helst information vi samlar in från dig kan användas på något av följande sätt:</p> - - <ul> - <li>För att personifiera din upplevelse — Din information hjälper oss att bättre svara på dina individuella behov.</li> - <li>För att förbättra vår webbplats — Vi strävar kontinuerligt efter att förbättra våra erbjudanden på webbplatsen baserat på information och feedback vi mottar från dig.</li> - <li>För att förbättra kundtjänst — Din information hjälper oss att effektivt svara på dina kundserviceförfrågningar och supportbehov.</li> - <li>För att skicka periodiska e-postmeddelanden — Den e-postadress du anger kan användas för att skicka information, meddelanden som du begär om ändringar i ämnen eller som svar på ditt användarnamn, svara på förfrågningar och / eller andra förfrågningar eller frågor.</li> - </ul> - - <h3 id="protect">Hur skyddar vi din information?</h3> - - <p>Vi genomför en rad säkerhetsåtgärder för att upprätthålla säkerheten för din personliga information när du anger, lämnar in eller har tillgång till din personliga information.</p> - - <h3 id="data-retention">Vad är policyn för lagring av data?</h3> - - <p>Vi kommer att göra en ansträngning för:</p> - - <ul> - <li>Behåll serverloggar som innehåller IP-adressen för alla förfrågningar till den här servern inte mer än 90 dagar.</li> - <li>Behåll IP-adresserna i samband med registrerade användare och deras inlägg inte längre än 5 år.</li> - </ul> - - <h3 id="cookies">Använder vi cookies?</h3> - - <p>Ja. Cookies är små filer som en webbplats eller tjänstleverantör överför till datorns hårddisk via din webbläsare (om du tillåter). Dessa cookies tillåter webbplatsen att känna igen din webbläsare och, om du har ett registrerat konto, associerar det med ditt registrerade konto.</p> - - <p>Vi använder cookies för att förstå och spara dina inställningar för framtida besök och sammanställa sammanlagda data om webbplatsstrafik och webbplatsinteraktion så att vi kan erbjuda bättre sajtupplevelser och verktyg i framtiden. Vi kan komma överens med tredje parts tjänsteleverantörer för att hjälpa oss att bättre förstå våra besökare. Dessa tjänsteleverantörer får inte använda den information som samlas in för vår räkning utom för att hjälpa oss att bedriva och förbättra vår verksamhet.</p> - - <h3 id="disclose">Avslöjar vi information till utomstående parter?</h3> - - <p>Vi säljer inte, handlar eller på annat sätt överför dina personuppgifter till utomstående parter. Det här omfattar inte betrodda tredje parter som hjälper oss att driva vår webbplats, bedriva vår verksamhet eller service dig, så länge dessa parter är överens om att hålla denna information konfidentiell. Vi kan också släppa din information när vi anser att utgåvan är lämplig för att följa lagen, tillämpa vår webbplatspolicy eller skydda vår eller andra rättigheter, egendom eller säkerhet. Däremot kan personuppgifter som inte identifieras personligen lämnas till andra parter för marknadsföring, reklam eller annan användning.</p> - - <h3 id="third-party">Tredjepartslänkar</h3> - - <p>Ibland kan vi, efter eget gottfinnande, inkludera eller erbjuda produkter från tredje part eller tjänster på vår webbplats. Dessa tredje parts webbplatser har separata och oberoende sekretesspolicyer. Vi har därför inget ansvar eller ansvar för innehållet och aktiviteterna för dessa länkade webbplatser. Ändå försöker vi skydda integriteten på vår webbplats och välkomna eventuella återkopplingar om dessa webbplatser.</p> - - <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3> - - <p>Vår webbplats, produkter och tjänster riktas alla till personer som är minst 13 år gamla. Om den här servern är i USA, och du är under 13 år, enligt kraven i COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) ska du inte använda denna sida.</p> - - <h3 id="online">Endast online sekretesspolicy</h3> - - <p>Denna online sekretesspolicy gäller endast information som samlas in via vår webbplats och inte till information som samlas in offline.</p> - - <h3 id="consent">Ditt samtycke</h3> - - <p>Genom att använda vår webbplats godkänner du vår hemsida sekretesspolicy.</p> - - <h3 id="changes">Ändringar i vår sekretesspolicy</h3> - - <p>Om vi bestämmer oss för att ändra vår integritetspolicy, lägger vi in de ändringar på den här sidan.</p> - - <p>This document is CC-BY-SA. It was last updated May 31, 2013.</p> - - <p>Ursprungligen anpassad från <a href="https://github.com/discourse/discourse">Discourse integritetspolicy</a>.</p> title: "%{instance} Användarvillkor och Sekretesspolicy" themes: default: Mastodon diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 1254651cd..be868e6e7 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -623,74 +623,6 @@ zh-CN: reblogged: 转嘟 sensitive_content: 敏感内容 terms: - body_html: | - <h2>隐私权政策</h2> - - <h3 id="collect">我们收集什么信息?</h3> - - <p>我们从你在我们站点注册开始从你那开始收集信息,并收集关于你在论坛的阅读和写作的数据,并评估分享的内容。</p> - - <p>当在我们站点注册时,你可能被要求输入你的名字和邮件地址。然而你可以在不用注册的情况下访问站点。你的邮件地将通过一个独一无二的链接验证。如果链接被访问了,我们就知道你控制了该邮件地址。</p> - - <p>当已注册和发帖时,我们记录发布帖子时的 IP 地址。我们也可能保留服务器日志,其中包括了每一个向我们服务器的请求。</p> - - <h3 id="use">我们如何使用你的信息?</h3> - - <p>从你那收集的任何数据将以以下方式使用:</p> - - <ul> - <li>改进你的个人体验 — 你的信息帮助我们更好地满足你的个人需求。</li> - <li>改进我们的站点 — 我们基于信息和我们从你那收到的反馈不断地试图改进我们的站点。</li> - <li>改善我们的客户服务 — 你的信息帮助我们更有效地回应用户服务请求和支持。</li> - <li>用于发送阶段性的邮件 — 你提供的邮件地址可能用于接受信息、你想看到的通知或与你用户名有关的回复和询问,或是其他的请求和问题。</li> - </ul> - - <h3 id="protect">我们如何保护你的信息?</h3> - - <p>我们实现了一系列的安全措施保证你输入、提交或者访问你个人信息的数据安全。</p> - - <h3 id="data-retention">数据保存政策是什么?</h3> - - <p>我们将善意地:</p> - - <ul> - <li>保存 90 天内的所有向服务器的包含 IP 地址的请求。</li> - <li>保存 5 年内已注册用户和与他们的帖子有关的 IP 地址。</li> - </ul> - - <h3 id="cookies">我们使用 Cookie 吗?</h3> - - <p>是的。Cookie 是网站或它的服务商通过网页浏览器存储在你电脑硬盘上的小文件(如果你同意)。这些 Cookie 使站点能分辨你的浏览器,并且,如果你注册了一个账户,与你的注册账户关联。</p> - - <p>我们使用 Cookie 为之后的访问和编译一小段关于站点流量和交互的数据来判断并保存你的个人设置,这样我们可以在之后提供更好的站点体验和工具。我们可能使用第三方服务商来帮助我们更好地理解我们的站点访客。这些服务商是不允许代表我们使用收集的信息,除非是在帮助我们执行和改进我们的站点。</p> - - <h3 id="disclose">我们会在站外提供任何信息吗?</h3> - - <p>我们绝不销售、交易或任何向外转移你个人信息的行为。这不包括帮助我们管理站点、改进站点或给你提供服务的第三方团体,这些团体需要保证对这些信息保密。当我们认为提交你的信息符合法律、我们的站点政策或保护我们或其他人的权利、知识产权或安全时,我们也可能提交你的信息。然而,非个人访问信息可能供其他团体使用,用于市场、广告或其他用途。</p> - - <h3 id="third-party">第三方链接</h3> - - <p>偶尔地,根据我们的判断,我们可能在我们的站点上包括或提供第三方团体的产品或服务。这些第三方站点用于独立和不同的隐私政策。因此我们对链接到的站点或活动没有责任和权利。尽管如此,我们寻求保护我们的整个站点并且欢迎你给这些站点反馈。</p> - - <h3 id="coppa">儿童在线隐私保护法案合规</h3> - - <p>我们的站点、产品和服务提供给 13 岁以上的人们。如果服务器位于美国,并且你小于 13 岁,根据<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">儿童在线隐私保护法案合规</a>,不要使用这个站点。</p> - - <h3 id="online">仅用于在线隐私政策</h3> - - <p>这个线上隐私政策只适用于通过我们站点收集到的信息,并不包括线下收集的信息。</p> - - <h3 id="consent">你的同意</h3> - - <p>你使用站点的同时,代表你同意了我们网站的隐私政策。</p> - - <h3 id="changes">隐私政策的更改</h3> - - <p>如果我们决定更改我们的隐私政策,我们将在此页更新这些改变。</p> - - <p>文档以 CC-BY-SA 发布。最后更新时间为2013年5月31日。</p> - - <p>原文出自 <a href="https://github.com/discourse/discourse">Discourse 隐私权政策</a>。</p> title: "%{instance} 使用条款和隐私权政策" time: formats: diff --git a/config/routes.rb b/config/routes.rb index 1991dec0a..092a14f47 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -125,6 +125,7 @@ Rails.application.routes.draw do get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy # Remote follow + resource :remote_unfollow, only: [:create] resource :authorize_follow, only: [:show, :create] resource :share, only: [:show, :create] @@ -159,6 +160,7 @@ Rails.application.routes.draw do post :memorialize end + resource :change_email, only: [:show, :update] resource :reset, only: [:create] resource :silence, only: [:create, :destroy] resource :suspension, only: [:create, :destroy] diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index a6927eec3..1d6304864 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -33,7 +33,7 @@ module Mastodon end def source_base_url - 'https://github.com/tootsuite/mastodon' + 'https://github.com/glitch-soc/mastodon' end # specify git tag or commit hash here diff --git a/public/headers/original/missing.png b/public/headers/original/missing.png index fdc34289d..26b59e75a 100644 --- a/public/headers/original/missing.png +++ b/public/headers/original/missing.png Binary files differdiff --git a/spec/controllers/admin/change_email_controller_spec.rb b/spec/controllers/admin/change_email_controller_spec.rb new file mode 100644 index 000000000..50f94f835 --- /dev/null +++ b/spec/controllers/admin/change_email_controller_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +RSpec.describe Admin::ChangeEmailsController, type: :controller do + render_views + + let(:admin) { Fabricate(:user, admin: true) } + + before do + sign_in admin + end + + describe "GET #show" do + it "returns http success" do + account = Fabricate(:account) + user = Fabricate(:user, account: account) + + get :show, params: { account_id: account.id } + + expect(response).to have_http_status(:success) + end + end + + describe "GET #update" do + before do + allow(UserMailer).to receive(:confirmation_instructions).and_return(double('email', deliver_later: nil)) + end + + it "returns http success" do + account = Fabricate(:account) + user = Fabricate(:user, account: account) + + previous_email = user.email + + post :update, params: { account_id: account.id, user: { unconfirmed_email: 'test@example.com' } } + + user.reload + + expect(user.email).to eq previous_email + expect(user.unconfirmed_email).to eq 'test@example.com' + expect(user.confirmation_token).not_to be_nil + + expect(UserMailer).to have_received(:confirmation_instructions).with(user, user.confirmation_token, { to: 'test@example.com' }) + + expect(response).to redirect_to(admin_account_path(account.id)) + end + end +end diff --git a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb index 247420d08..efbef439a 100644 --- a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb @@ -28,6 +28,10 @@ describe Api::V1::Accounts::CredentialsController do note: "Hi!\n\nToot toot!", avatar: fixture_file_upload('files/avatar.gif', 'image/gif'), header: fixture_file_upload('files/attachment.jpg', 'image/jpeg'), + source: { + privacy: 'unlisted', + sensitive: true, + } } end @@ -42,6 +46,8 @@ describe Api::V1::Accounts::CredentialsController do expect(user.account.note).to eq("Hi!\n\nToot toot!") expect(user.account.avatar).to exist expect(user.account.header).to exist + expect(user.setting_default_privacy).to eq('unlisted') + expect(user.setting_default_sensitive).to eq(true) end it 'queues up an account update distribution' do diff --git a/spec/lib/user_settings_decorator_spec.rb b/spec/lib/user_settings_decorator_spec.rb index fee875373..462c5b124 100644 --- a/spec/lib/user_settings_decorator_spec.rb +++ b/spec/lib/user_settings_decorator_spec.rb @@ -69,5 +69,16 @@ describe UserSettingsDecorator do settings.update(values) expect(user.settings['system_font_ui']).to eq false end + + it 'decoerces setting values before applying' do + values = { + 'setting_delete_modal' => 'false', + 'setting_boost_modal' => 'true', + } + + settings.update(values) + expect(user.settings['delete_modal']).to eq false + expect(user.settings['boost_modal']).to eq true + end end end diff --git a/spec/models/custom_emoji_spec.rb b/spec/models/custom_emoji_spec.rb index bb150b837..87367df50 100644 --- a/spec/models/custom_emoji_spec.rb +++ b/spec/models/custom_emoji_spec.rb @@ -1,6 +1,30 @@ require 'rails_helper' RSpec.describe CustomEmoji, type: :model do + describe '#search' do + let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: shortcode) } + + subject { described_class.search(search_term) } + + context 'shortcode is exact' do + let(:shortcode) { 'blobpats' } + let(:search_term) { 'blobpats' } + + it 'finds emoji' do + is_expected.to include(custom_emoji) + end + end + + context 'shortcode is partial' do + let(:shortcode) { 'blobpats' } + let(:search_term) { 'blob' } + + it 'finds emoji' do + is_expected.to include(custom_emoji) + end + end + end + describe '#local?' do let(:custom_emoji) { Fabricate(:custom_emoji, domain: domain) } |