Skip to content

Commit 4abae69

Browse files
committed
Merge branch 'hotfix/26.1.2'
2 parents e220c87 + 37358cd commit 4abae69

12 files changed

Lines changed: 86 additions & 25 deletions

File tree

CHANGELOG

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
We follow the CalVer (https://calver.org/) versioning scheme: YY.MINOR.MICRO.
44

5+
26.1.2 (2026-01-05)
6+
===================
7+
8+
- Notifications Refactor Phase 2 - UAT Hotfix Part 2
9+
* Fix adding moderator email in admin
10+
* Fix preprint/registration withdrawal request email in digest
11+
* Fix subjects for schema response update emails
12+
* Update defauls for triggered emails
13+
514
26.1.1 (2026-01-02)
615
===================
716

admin/providers/views.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from django.shortcuts import redirect
22
from django.views.generic import TemplateView
33
from django.contrib import messages
4-
from osf.models import RegistrationProvider, OSFUser
4+
from osf.models import RegistrationProvider, OSFUser, CollectionProvider, NotificationType
5+
from website.settings import DOMAIN
56

67

78
class AddAdminOrModerator(TemplateView):
@@ -32,16 +33,41 @@ def post(self, request, *args, **kwargs):
3233
if target_user.has_groups(provider.group_names):
3334
messages.error(request, f'User with guid: {data["add-moderators-form"][0]} is already a moderator or admin')
3435
return redirect(f'{self.url_namespace}:add_admin_or_moderator', provider_id=provider.id)
36+
context = {}
37+
context['user_fullname'] = target_user.fullname
38+
context['referrer_fullname'] = self.request.user.username
39+
context['provider_name'] = provider.name
3540

3641
if 'admin' in data:
3742
provider.add_to_group(target_user, 'admin')
3843
target_type = 'admin'
44+
context['is_admin'] = True
3945
else:
4046
provider.add_to_group(target_user, 'moderator')
4147
target_type = 'moderator'
48+
context['is_admin'] = False
49+
50+
context['provider_name'] = provider.name
51+
context['provider__id'] = provider._id
52+
context['is_reviews_moderator_notification'] = True
53+
54+
if isinstance(provider, RegistrationProvider):
55+
provider_type_word = 'registries'
56+
context['notification_settings_url'] = f'{DOMAIN}registries/{provider._id}/moderation/settings'
57+
elif isinstance(provider, CollectionProvider):
58+
provider_type_word = 'collections'
59+
context['notification_settings_url'] = f'{DOMAIN}registries/{provider._id}/moderation/settings'
60+
else:
61+
provider_type_word = 'preprints'
62+
context['notification_settings_url'] = f'{DOMAIN}preprints/{provider._id}/moderation/notifications'
4263

64+
context['provider_url'] = f'{provider.domain or DOMAIN}{provider_type_word}/{(provider._id if not provider.domain else '').strip('/')}'
4365
messages.success(request, f'The following {target_type} was successfully added: {target_user.fullname} ({target_user.username})')
44-
66+
notification_type = NotificationType.Type.PROVIDER_MODERATOR_ADDED
67+
notification_type.instance.emit(
68+
user=target_user,
69+
event_context=context,
70+
)
4571
return redirect(f'{self.url_namespace}:add_admin_or_moderator', provider_id=provider.id)
4672

4773

admin_tests/preprint_providers/test_views.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from admin.base.forms import ImportFileForm
3232
from django.contrib.messages.storage.fallback import FallbackStorage
3333
import website
34+
from tests.utils import capture_notifications
3435

3536
pytestmark = pytest.mark.django_db
3637

@@ -504,7 +505,8 @@ def test_post_add(self, add_moderator_view, req, user, provider):
504505
messages = FallbackStorage(req)
505506
setattr(req, '_messages', messages)
506507

507-
res = add_moderator_view.post(req)
508+
with capture_notifications():
509+
res = add_moderator_view.post(req)
508510
assert res.status_code == 302
509511
assert user in provider.get_group('moderator').user_set.all()
510512

admin_tests/registration_providers/test_views.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
from django.contrib.messages.storage.fallback import FallbackStorage
2828
from osf.migrations import update_provider_auth_groups
29+
from tests.utils import capture_notifications
2930

3031
pytestmark = pytest.mark.django_db
3132

@@ -318,7 +319,8 @@ def test_post_add(self, add_moderator_view, req, user, provider):
318319
messages = FallbackStorage(req)
319320
setattr(req, '_messages', messages)
320321

321-
res = add_moderator_view.post(req)
322+
with capture_notifications():
323+
res = add_moderator_view.post(req)
322324
assert res.status_code == 302
323325
assert user in provider.get_group('moderator').user_set.all()
324326

notifications.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -583,28 +583,28 @@ notification_types:
583583
tests: ['api_tests/nodes/views/test_node_forks_list.py']
584584

585585
- name: node_schema_response_initiated
586-
subject: 'Schema Response Initiated'
586+
subject: 'Updates for {resource_type} {title} are in progress'
587587
__docs__: ...
588588
object_content_type_model_name: abstractnode
589589
template: 'website/templates/updates_initiated.html.mako'
590590
tests: ['osf_tests/test_schema_responses.py']
591591

592592
- name: node_schema_response_submitted
593-
subject: 'Schema Response Submitted'
593+
subject: 'Updates for {resource_type} {title} are pending Admin approval'
594594
__docs__: ...
595595
object_content_type_model_name: abstractnode
596596
template: 'website/templates/updates_pending_approval.html.mako'
597597
tests: ['osf_tests/test_schema_responses.py']
598598

599599
- name: node_schema_response_approved
600-
subject: 'Schema Response Approved'
600+
subject: 'The updates for {resource_type} {title} have been approved'
601601
__docs__: ...
602602
object_content_type_model_name: abstractnode
603603
template: 'website/templates/updates_approved.html.mako'
604604
tests: ['osf_tests/test_schema_responses.py']
605605

606606
- name: node_schema_response_rejected
607-
subject: 'Schema Response Rejected'
607+
subject: 'The updates for {resource_type} {title} were not accepted'
608608
__docs__: ...
609609
object_content_type_model_name: abstractnode
610610
template: 'website/templates/updates_rejected.html.mako'

notifications/listeners.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def reviews_withdraw_requests_notification_moderators(self, timestamp, context,
9393

9494
provider = resource.provider
9595
context['provider_id'] = provider.id
96+
context['requester_fullname'] = user.fullname
9697
# Set message
9798
context['message'] = f'has requested withdrawal of "{resource.title}".'
9899
# Set submission url

osf/utils/machines.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ def notify_submit(self, ev):
335335
context = self.get_context()
336336
if not self.auto_approval_allowed():
337337
context['reviewable'] = self.machineable.target
338+
context['requester_fullname'] = self.machineable.creator.fullname
338339
reviews_signals.email_withdrawal_requests.send(timestamp=timezone.now(), context=context)
339340
reviews_signals.reviews_email_withdrawal_requests.send(timestamp=timezone.now(), context=context)
340341

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "OSF",
3-
"version": "26.1.1",
3+
"version": "26.1.2",
44
"description": "Facilitating Open Science",
55
"repository": "https://github.com/CenterForOpenScience/osf.io",
66
"author": "Center for Open Science",

website/reviews/listeners.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def reviews_notification(self, creator, template, context, action):
2626
@reviews_signals.reviews_withdraw_requests_notification_moderators.connect
2727
def reviews_withdraw_requests_notification_moderators(self, timestamp, context, user, resource):
2828
context['referrer_fullname'] = user.fullname
29+
context['requester_fullname'] = user.fullname
2930
provider = resource.provider
3031
from osf.models import NotificationType
3132

website/settings/defaults.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,16 +180,19 @@ def parent_dir(path):
180180
}
181181
NOTIFICATION_TYPES_YAML = 'notifications.yaml'
182182

183-
# Triggered emails
183+
# Triggered emails - updated by Notification Refactor release
184184
OSF_HELP_LIST = 'Open Science Framework Help'
185-
WAIT_BETWEEN_MAILS = timedelta(days=7)
186-
NO_ADDON_WAIT_TIME = timedelta(weeks=8)
187-
NO_LOGIN_WAIT_TIME = timedelta(weeks=4)
188-
NO_LOGIN_OSF4M_WAIT_TIME = timedelta(weeks=6)
189-
190-
# Configuration for NO_LOGIN_EMAIL (NotificationType.Type.USER_NO_LOGIN)
185+
WAIT_BETWEEN_MAILS = timedelta(days=7) # Deprecated setting, used by deprecated `scripts.send_queued_mails`
186+
NO_ADDON_WAIT_TIME = timedelta(weeks=8) # 2 months for "Link an add-on to your OSF project" email
187+
NO_LOGIN_WAIT_TIME = timedelta(weeks=52) # 1 year for "We miss you at OSF" email
188+
NO_LOGIN_OSF4M_WAIT_TIME = timedelta(weeks=52) # 1 year for "We miss you at OSF" email to users created from OSF4M
189+
190+
# Configuration for "We miss you at OSF" email (`NotificationType.Type.USER_NO_LOGIN`)
191+
# Note: 1) we can gradually increase `MAX_DAILY_NO_LOGIN_EMAILS` to 10000, 100000, etc. or set it to `None` after we
192+
# have verified that users are not spammed by this email after NR release. 2) If we want to clean up database for those
193+
# already sent `USER_NO_LOGIN` emails, we need to adjust the cut-off time to the day we clean the DB.
191194
MAX_DAILY_NO_LOGIN_EMAILS = 1000
192-
NO_LOGIN_EMAIL_CUTOFF = datetime.datetime(2026, 1, 1)
195+
NO_LOGIN_EMAIL_CUTOFF = datetime.datetime(2026, 1, 5)
193196

194197
# TODO: Override in local.py
195198
MAILGUN_API_KEY = None

0 commit comments

Comments
 (0)