mirror of
https://github.com/yingziwu/mastodon.git
synced 2026-02-04 03:25:14 +00:00
Merge tag 'v4.2.15'
This commit is contained in:
commit
18aa575996
10 changed files with 121 additions and 72 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -2,6 +2,18 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [4.2.15] - 2025-01-16
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix insufficient validation of account URIs ([GHSA-5wxh-3p65-r4g6](https://github.com/mastodon/mastodon/security/advisories/GHSA-5wxh-3p65-r4g6))
|
||||||
|
- Update dependencies
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix `libyaml` missing from `Dockerfile` build stage (#33591 by @vmstan)
|
||||||
|
- Fix deletion of unconfirmed users with Webauthn set (#33186 by @ClearlyClaire)
|
||||||
|
|
||||||
## [4.2.14] - 2024-02-03
|
## [4.2.14] - 2024-02-03
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ RUN apt-get update && \
|
||||||
libgdbm-dev \
|
libgdbm-dev \
|
||||||
libgmp-dev \
|
libgmp-dev \
|
||||||
libssl-dev \
|
libssl-dev \
|
||||||
|
libyaml-dev \
|
||||||
libyaml-0-2 \
|
libyaml-0-2 \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
libreadline8 \
|
libreadline8 \
|
||||||
|
|
|
||||||
117
Gemfile.lock
117
Gemfile.lock
|
|
@ -28,47 +28,47 @@ GIT
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (7.0.8.6)
|
actioncable (7.0.8.7)
|
||||||
actionpack (= 7.0.8.6)
|
actionpack (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailbox (7.0.8.6)
|
actionmailbox (7.0.8.7)
|
||||||
actionpack (= 7.0.8.6)
|
actionpack (= 7.0.8.7)
|
||||||
activejob (= 7.0.8.6)
|
activejob (= 7.0.8.7)
|
||||||
activerecord (= 7.0.8.6)
|
activerecord (= 7.0.8.7)
|
||||||
activestorage (= 7.0.8.6)
|
activestorage (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
actionmailer (7.0.8.6)
|
actionmailer (7.0.8.7)
|
||||||
actionpack (= 7.0.8.6)
|
actionpack (= 7.0.8.7)
|
||||||
actionview (= 7.0.8.6)
|
actionview (= 7.0.8.7)
|
||||||
activejob (= 7.0.8.6)
|
activejob (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (7.0.8.6)
|
actionpack (7.0.8.7)
|
||||||
actionview (= 7.0.8.6)
|
actionview (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
rack (~> 2.0, >= 2.2.4)
|
rack (~> 2.0, >= 2.2.4)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||||
actiontext (7.0.8.6)
|
actiontext (7.0.8.7)
|
||||||
actionpack (= 7.0.8.6)
|
actionpack (= 7.0.8.7)
|
||||||
activerecord (= 7.0.8.6)
|
activerecord (= 7.0.8.7)
|
||||||
activestorage (= 7.0.8.6)
|
activestorage (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (7.0.8.6)
|
actionview (7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
|
|
@ -78,22 +78,22 @@ GEM
|
||||||
activemodel (>= 4.1, < 7.1)
|
activemodel (>= 4.1, < 7.1)
|
||||||
case_transform (>= 0.2)
|
case_transform (>= 0.2)
|
||||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||||
activejob (7.0.8.6)
|
activejob (7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (7.0.8.6)
|
activemodel (7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
activerecord (7.0.8.6)
|
activerecord (7.0.8.7)
|
||||||
activemodel (= 7.0.8.6)
|
activemodel (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
activestorage (7.0.8.6)
|
activestorage (7.0.8.7)
|
||||||
actionpack (= 7.0.8.6)
|
actionpack (= 7.0.8.7)
|
||||||
activejob (= 7.0.8.6)
|
activejob (= 7.0.8.7)
|
||||||
activerecord (= 7.0.8.6)
|
activerecord (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
mini_mime (>= 1.1.0)
|
mini_mime (>= 1.1.0)
|
||||||
activesupport (7.0.8.6)
|
activesupport (7.0.8.7)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
|
|
@ -469,7 +469,7 @@ GEM
|
||||||
net-protocol
|
net-protocol
|
||||||
net-ssh (7.1.0)
|
net-ssh (7.1.0)
|
||||||
nio4r (2.7.4)
|
nio4r (2.7.4)
|
||||||
nokogiri (1.16.7)
|
nokogiri (1.16.8)
|
||||||
mini_portile2 (~> 2.8.2)
|
mini_portile2 (~> 2.8.2)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nsa (0.3.0)
|
nsa (0.3.0)
|
||||||
|
|
@ -550,20 +550,20 @@ GEM
|
||||||
rack
|
rack
|
||||||
rack-test (2.1.0)
|
rack-test (2.1.0)
|
||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rails (7.0.8.6)
|
rails (7.0.8.7)
|
||||||
actioncable (= 7.0.8.6)
|
actioncable (= 7.0.8.7)
|
||||||
actionmailbox (= 7.0.8.6)
|
actionmailbox (= 7.0.8.7)
|
||||||
actionmailer (= 7.0.8.6)
|
actionmailer (= 7.0.8.7)
|
||||||
actionpack (= 7.0.8.6)
|
actionpack (= 7.0.8.7)
|
||||||
actiontext (= 7.0.8.6)
|
actiontext (= 7.0.8.7)
|
||||||
actionview (= 7.0.8.6)
|
actionview (= 7.0.8.7)
|
||||||
activejob (= 7.0.8.6)
|
activejob (= 7.0.8.7)
|
||||||
activemodel (= 7.0.8.6)
|
activemodel (= 7.0.8.7)
|
||||||
activerecord (= 7.0.8.6)
|
activerecord (= 7.0.8.7)
|
||||||
activestorage (= 7.0.8.6)
|
activestorage (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 7.0.8.6)
|
railties (= 7.0.8.7)
|
||||||
rails-controller-testing (1.0.5)
|
rails-controller-testing (1.0.5)
|
||||||
actionpack (>= 5.0.1.rc1)
|
actionpack (>= 5.0.1.rc1)
|
||||||
actionview (>= 5.0.1.rc1)
|
actionview (>= 5.0.1.rc1)
|
||||||
|
|
@ -572,15 +572,15 @@ GEM
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
minitest
|
minitest
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.6.0)
|
rails-html-sanitizer (1.6.2)
|
||||||
loofah (~> 2.21)
|
loofah (~> 2.21)
|
||||||
nokogiri (~> 1.14)
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||||
rails-i18n (7.0.7)
|
rails-i18n (7.0.7)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 6.0.0, < 8)
|
railties (>= 6.0.0, < 8)
|
||||||
railties (7.0.8.6)
|
railties (7.0.8.7)
|
||||||
actionpack (= 7.0.8.6)
|
actionpack (= 7.0.8.7)
|
||||||
activesupport (= 7.0.8.6)
|
activesupport (= 7.0.8.7)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
|
|
@ -743,7 +743,7 @@ GEM
|
||||||
test-prof (1.2.3)
|
test-prof (1.2.3)
|
||||||
thor (1.3.2)
|
thor (1.3.2)
|
||||||
tilt (2.2.0)
|
tilt (2.2.0)
|
||||||
timeout (0.4.2)
|
timeout (0.4.3)
|
||||||
tpm-key_attestation (0.12.0)
|
tpm-key_attestation (0.12.0)
|
||||||
bindata (~> 2.4)
|
bindata (~> 2.4)
|
||||||
openssl (> 2.0)
|
openssl (> 2.0)
|
||||||
|
|
@ -800,7 +800,8 @@ GEM
|
||||||
railties (>= 5.2)
|
railties (>= 5.2)
|
||||||
semantic_range (>= 2.3.0)
|
semantic_range (>= 2.3.0)
|
||||||
websocket (1.2.9)
|
websocket (1.2.9)
|
||||||
websocket-driver (0.7.6)
|
websocket-driver (0.7.7)
|
||||||
|
base64
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
wisper (2.0.1)
|
wisper (2.0.1)
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ class DeliveryFailureTracker
|
||||||
urls.reject do |url|
|
urls.reject do |url|
|
||||||
host = Addressable::URI.parse(url).normalized_host
|
host = Addressable::URI.parse(url).normalized_host
|
||||||
unavailable_domains_map[host]
|
unavailable_domains_map[host]
|
||||||
|
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
|
||||||
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
SUBDOMAINS_RATELIMIT = 10
|
SUBDOMAINS_RATELIMIT = 10
|
||||||
DISCOVERIES_PER_REQUEST = 400
|
DISCOVERIES_PER_REQUEST = 400
|
||||||
|
|
||||||
|
VALID_URI_SCHEMES = %w(http https).freeze
|
||||||
|
|
||||||
# Should be called with confirmed valid JSON
|
# Should be called with confirmed valid JSON
|
||||||
# and WebFinger-resolved username and domain
|
# and WebFinger-resolved username and domain
|
||||||
def call(username, domain, json, options = {})
|
def call(username, domain, json, options = {})
|
||||||
|
|
@ -96,16 +98,28 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_immediate_protocol_attributes!
|
def set_immediate_protocol_attributes!
|
||||||
@account.inbox_url = @json['inbox'] || ''
|
@account.inbox_url = valid_collection_uri(@json['inbox'])
|
||||||
@account.outbox_url = @json['outbox'] || ''
|
@account.outbox_url = valid_collection_uri(@json['outbox'])
|
||||||
@account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
|
@account.shared_inbox_url = valid_collection_uri(@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox'])
|
||||||
@account.followers_url = @json['followers'] || ''
|
@account.followers_url = valid_collection_uri(@json['followers'])
|
||||||
@account.url = url || @uri
|
@account.url = url || @uri
|
||||||
@account.uri = @uri
|
@account.uri = @uri
|
||||||
@account.actor_type = actor_type
|
@account.actor_type = actor_type
|
||||||
@account.created_at = @json['published'] if @json['published'].present?
|
@account.created_at = @json['published'] if @json['published'].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid_collection_uri(uri)
|
||||||
|
uri = uri.first if uri.is_a?(Array)
|
||||||
|
uri = uri['id'] if uri.is_a?(Hash)
|
||||||
|
return '' unless uri.is_a?(String)
|
||||||
|
|
||||||
|
parsed_uri = Addressable::URI.parse(uri)
|
||||||
|
|
||||||
|
VALID_URI_SCHEMES.include?(parsed_uri.scheme) && parsed_uri.host.present? ? parsed_uri : ''
|
||||||
|
rescue Addressable::URI::InvalidURIError
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
def set_immediate_attributes!
|
def set_immediate_attributes!
|
||||||
@account.featured_collection_url = @json['featured'] || ''
|
@account.featured_collection_url = @json['featured'] || ''
|
||||||
@account.devices_url = @json['devices'] || ''
|
@account.devices_url = @json['devices'] || ''
|
||||||
|
|
@ -268,10 +282,11 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def collection_info(type)
|
def collection_info(type)
|
||||||
return [nil, nil] if @json[type].blank?
|
collection_uri = valid_collection_uri(@json[type])
|
||||||
|
return [nil, nil] if collection_uri.blank?
|
||||||
return @collections[type] if @collections.key?(type)
|
return @collections[type] if @collections.key?(type)
|
||||||
|
|
||||||
collection = fetch_resource_without_id_validation(@json[type])
|
collection = fetch_resource_without_id_validation(collection_uri)
|
||||||
|
|
||||||
total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
|
total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
|
||||||
has_first_page = collection.is_a?(Hash) && collection['first'].present?
|
has_first_page = collection.is_a?(Hash) && collection['first'].present?
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class Scheduler::UserCleanupScheduler
|
||||||
User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|
|
User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|
|
||||||
# We have to do it separately because of missing database constraints
|
# We have to do it separately because of missing database constraints
|
||||||
AccountModerationNote.where(target_account_id: batch.map(&:account_id)).delete_all
|
AccountModerationNote.where(target_account_id: batch.map(&:account_id)).delete_all
|
||||||
|
WebauthnCredential.where(user_id: batch.map(&:id)).delete_all
|
||||||
Account.where(id: batch.map(&:account_id)).delete_all
|
Account.where(id: batch.map(&:account_id)).delete_all
|
||||||
User.where(id: batch.map(&:id)).delete_all
|
User.where(id: batch.map(&:id)).delete_all
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ services:
|
||||||
|
|
||||||
web:
|
web:
|
||||||
build: .
|
build: .
|
||||||
image: ghcr.io/mastodon/mastodon:v4.2.14
|
image: ghcr.io/mastodon/mastodon:v4.2.15
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
||||||
|
|
@ -77,7 +77,7 @@ services:
|
||||||
|
|
||||||
streaming:
|
streaming:
|
||||||
build: .
|
build: .
|
||||||
image: ghcr.io/mastodon/mastodon:v4.2.14
|
image: ghcr.io/mastodon/mastodon:v4.2.15
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: node ./streaming
|
command: node ./streaming
|
||||||
|
|
@ -95,7 +95,7 @@ services:
|
||||||
|
|
||||||
sidekiq:
|
sidekiq:
|
||||||
build: .
|
build: .
|
||||||
image: ghcr.io/mastodon/mastodon:v4.2.14
|
image: ghcr.io/mastodon/mastodon:v4.2.15
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bundle exec sidekiq
|
command: bundle exec sidekiq
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ module Mastodon
|
||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
14
|
15
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_prerelease
|
def default_prerelease
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ describe DeliveryFailureTracker do
|
||||||
Fabricate(:unavailable_domain, domain: 'foo.bar')
|
Fabricate(:unavailable_domain, domain: 'foo.bar')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'removes URLs that are unavailable' do
|
it 'removes URLs that are bogus or unavailable' do
|
||||||
results = described_class.without_unavailable(['http://example.com/good/inbox', 'http://foo.bar/unavailable/inbox'])
|
results = described_class.without_unavailable(['http://example.com/good/inbox', 'http://foo.bar/unavailable/inbox', '{foo:'])
|
||||||
|
|
||||||
expect(results).to include('http://example.com/good/inbox')
|
expect(results).to include('http://example.com/good/inbox')
|
||||||
expect(results).to_not include('http://foo.bar/unavailable/inbox')
|
expect(results).to_not include('http://foo.bar/unavailable/inbox')
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ describe Scheduler::UserCleanupScheduler do
|
||||||
let!(:old_unconfirmed_user) { Fabricate(:user) }
|
let!(:old_unconfirmed_user) { Fabricate(:user) }
|
||||||
let!(:confirmed_user) { Fabricate(:user) }
|
let!(:confirmed_user) { Fabricate(:user) }
|
||||||
let!(:moderation_note) { Fabricate(:account_moderation_note, account: Fabricate(:account), target_account: old_unconfirmed_user.account) }
|
let!(:moderation_note) { Fabricate(:account_moderation_note, account: Fabricate(:account), target_account: old_unconfirmed_user.account) }
|
||||||
|
let!(:webauthn_credential) { Fabricate(:webauthn_credential, user_id: old_unconfirmed_user.id) }
|
||||||
|
|
||||||
describe '#perform' do
|
describe '#perform' do
|
||||||
before do
|
before do
|
||||||
|
|
@ -18,8 +19,24 @@ describe Scheduler::UserCleanupScheduler do
|
||||||
confirmed_user.update!(confirmed_at: 1.day.ago)
|
confirmed_user.update!(confirmed_at: 1.day.ago)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'deletes the old unconfirmed user' do
|
it 'deletes the old unconfirmed user and metadata while preserving confirmed user and newer unconfirmed user' do
|
||||||
expect { subject.perform }.to change { User.exists?(old_unconfirmed_user.id) }.from(true).to(false)
|
expect { subject.perform }
|
||||||
|
.to change { User.exists?(old_unconfirmed_user.id) }
|
||||||
|
.from(true).to(false)
|
||||||
|
.and change { Account.exists?(old_unconfirmed_user.account_id) }
|
||||||
|
.from(true).to(false)
|
||||||
|
expect { moderation_note.reload }
|
||||||
|
.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
|
expect { webauthn_credential.reload }
|
||||||
|
.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
|
expect(User.exists?(new_unconfirmed_user.id))
|
||||||
|
.to be true
|
||||||
|
expect(User.exists?(confirmed_user.id))
|
||||||
|
.to be true
|
||||||
|
expect(Account.exists?(new_unconfirmed_user.account_id))
|
||||||
|
.to be true
|
||||||
|
expect(Account.exists?(confirmed_user.account_id))
|
||||||
|
.to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "deletes the old unconfirmed user's account" do
|
it "deletes the old unconfirmed user's account" do
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue