forked from didirus/AstralRinth
* Migration * Fixup db models * Redis * Stuff * Switch PKs to BIGSERIALs, insert to notifications_deliveries when inserting notifications * Queue, templates * Query cache * Fixes, fixtures * Perf, cache template data & HTML bodies * Notification type configuration, ResetPassword notification type * Reset password * Query cache * Clippy + fmt * Traces, fix typo, fix user email in ResetPassword * send_email * Models, db * Remove dead code, adjust notification settings in migration * Clippy fmt * Delete dead code, fixes * Fmt * Update apps/labrinth/src/queue/email.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com> * Remove old fixtures * Unify email retry delay * Fix type * External notifications * Remove `notifications_types_preference_restrictions`, as user notification preferences is out of scope for this PR * Query cache, fmt, clippy * Fix join in get_many_user_exposed_on_site * Remove migration comment * Query cache * Update html body urls * Remove comment * Add paymentfailed.service variable to PaymentFailed notification variant * Fix compile error * Fix deleting notifications * Update apps/labrinth/src/database/models/user_item.rs Co-authored-by: Josiah Glosson <soujournme@gmail.com> Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com> * Update apps/labrinth/src/database/models/user_item.rs Co-authored-by: Josiah Glosson <soujournme@gmail.com> Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com> * Update Cargo.toml Co-authored-by: Josiah Glosson <soujournme@gmail.com> Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com> * Update apps/labrinth/migrations/20250902133943_notification-extension.sql Co-authored-by: Josiah Glosson <soujournme@gmail.com> Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com> * Address review comments * Fix compliation * Update apps/labrinth/src/database/models/users_notifications_preferences_item.rs Co-authored-by: Josiah Glosson <soujournme@gmail.com> Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com> * Use strfmt to format emails * Configurable Reply-To * Configurable Reply-To * Refactor for email background task * Send some emails inline * Fix account creation email check * Revert "Use strfmt to format emails" This reverts commit e0d6614afe51fa6349918377e953ba294c34ae0b. * Reintroduce fill_template * Set password reset email inline * Process more emails per index * clippy fmt * Query cache --------- Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Josiah Glosson <soujournme@gmail.com>
255 lines
13 KiB
SQL
255 lines
13 KiB
SQL
CREATE TABLE notifications_deliveries (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
notification_id BIGINT NOT NULL REFERENCES notifications(id),
|
|
channel VARCHAR(32) NOT NULL,
|
|
user_id BIGINT NOT NULL REFERENCES users(id),
|
|
delivery_priority INTEGER NOT NULL,
|
|
status VARCHAR(32) NOT NULL,
|
|
next_attempt timestamptz NOT NULL,
|
|
attempt_count INTEGER NOT NULL,
|
|
|
|
UNIQUE (notification_id, channel)
|
|
);
|
|
|
|
CREATE INDEX idx_notifications_deliveries_composite_queue
|
|
ON notifications_deliveries(channel, status, next_attempt ASC, delivery_priority DESC)
|
|
INCLUDE (notification_id, user_id);
|
|
|
|
CREATE INDEX idx_notifications_deliveries_user_id
|
|
ON notifications_deliveries(user_id);
|
|
|
|
CREATE TABLE users_notifications_preferences (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT REFERENCES users(id),
|
|
channel VARCHAR(32) NOT NULL,
|
|
notification_type VARCHAR(32) NOT NULL,
|
|
enabled BOOL NOT NULL
|
|
);
|
|
|
|
CREATE INDEX idx_users_notifications_preferences_user_id
|
|
ON users_notifications_preferences(user_id);
|
|
|
|
CREATE UNIQUE INDEX idx_users_notifications_preferences_partial_contextual_uniq
|
|
ON users_notifications_preferences(COALESCE(user_id, -1), channel, notification_type);
|
|
|
|
CREATE TABLE notifications_types (
|
|
name VARCHAR(32) PRIMARY KEY,
|
|
delivery_priority INTEGER NOT NULL,
|
|
expose_in_user_preferences BOOL NOT NULL,
|
|
expose_in_site_notifications BOOL NOT NULL
|
|
);
|
|
|
|
CREATE TABLE notifications_templates (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
channel VARCHAR(32) NOT NULL,
|
|
notification_type VARCHAR(32) NOT NULL REFERENCES notifications_types(name),
|
|
subject_line TEXT NOT NULL,
|
|
body_fetch_url TEXT NOT NULL,
|
|
plaintext_fallback TEXT NOT NULL
|
|
);
|
|
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('reset_password', 3, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('project_update', 1, TRUE, TRUE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('team_invite', 1, TRUE, TRUE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('organization_invite', 1, TRUE, TRUE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('status_change', 1, TRUE, TRUE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('moderator_message', 1, TRUE, TRUE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('legacy_markdown', 1, FALSE, TRUE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('unknown', 1, FALSE, TRUE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('verify_email', 3, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('auth_provider_added', 2, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('auth_provider_removed', 2, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('two_factor_enabled', 2, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('two_factor_removed', 2, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('password_changed', 2, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('password_removed', 2, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('email_changed', 2, FALSE, FALSE);
|
|
INSERT INTO notifications_types (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) VALUES ('payment_failed', 2, FALSE, FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'reset_password', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'project_update', FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'team_invite', FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'organization_invite', FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'status_change', FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'moderator_message', FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'legacy_markdown', FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'unknown', FALSE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'verify_email', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'auth_provider_added', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'auth_provider_removed', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'two_factor_enabled', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'two_factor_removed', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'password_changed', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'password_removed', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'email_changed', TRUE);
|
|
|
|
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
|
|
VALUES (NULL, 'email', 'payment_failed', TRUE);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'reset_password', 'Reset your Modrinth password', 'https://modrinth.com/email/reset-password',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'Please visit the link below to reset your password. If you did not request for your password to be reset, you can safely ignore this email.',
|
|
CHR(10),
|
|
'Reset your password: {resetpassword.url}'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'verify_email', 'Verify your Modrinth email', 'https://modrinth.com/email/verify-email',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'Please visit the link below to verify your Modrinth email. If the button does not work, you can copy the link and paste it into your browser. This link expires in 24 hours.',
|
|
CHR(10),
|
|
'Verify your email: {verifyemail.url}'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'auth_provider_added', 'Authentication method added', 'https://modrinth.com/email/auth-provider-added',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'When logging into Modrinth, you can now log in using the ', '{authprovider.name}', ' authentication provider.',
|
|
CHR(10),
|
|
'If you did not make this change, please contact us immediately by replying to this email or through our support portal at https://support.modrinth.com (using',
|
|
'the green chat bubble at the bottom of the page)'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'auth_provider_removed', 'Authentication method removed', 'https://modrinth.com/email/auth-provider-removed',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'When logging into Modrinth, you can no longer log in using the ', '{authprovider.name}', ' authentication provider.',
|
|
CHR(10),
|
|
'If you did not make this change, please contact us immediately by replying to this email or through our support portal at https://support.modrinth.com (using',
|
|
'the green chat bubble at the bottom of the page)'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'two_factor_enabled', 'Two-factor authentication enabled', 'https://modrinth.com/email/two-factor-enabled',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'When logging into Modrinth, you can now enter a code generated by your authenticator app in addition to entering your usual email address and password.',
|
|
CHR(10),
|
|
'If you did not make this change, please contact us immediately by replying to this email or through our support portal at https://support.modrinth.com (using',
|
|
'the green chat bubble at the bottom of the page)'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'two_factor_removed', 'Two-factor authentication removed', 'https://modrinth.com/email/two-factor-removed',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'When logging into Modrinth, you no longer need two-factor authentication to gain access.',
|
|
CHR(10),
|
|
'If you did not make this change, please contact us immediately by replying to this email or through our support portal at https://support.modrinth.com (using',
|
|
'the green chat bubble at the bottom of the page)'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'password_changed', 'Your Modrinth password was changed', 'https://modrinth.com/email/password-changed',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'Your password has been changed on your account.',
|
|
CHR(10),
|
|
'If you did not make this change, please contact us immediately by replying to this email or through our support portal at https://support.modrinth.com (using',
|
|
'the green chat bubble at the bottom of the page)'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'password_removed', 'Your Modrinth password was removed', 'https://modrinth.com/email/password-removed',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'Your password has been removed on your account.',
|
|
CHR(10),
|
|
'If you did not make this change, please contact us immediately by replying to this email or through our support portal at https://support.modrinth.com (using',
|
|
'the green chat bubble at the bottom of the page)'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'email_changed', 'Your Modrinth email was changed', 'https://modrinth.com/email/email-changed',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'Your Modrinth account email has been updated to {emailchanged.new_email}.',
|
|
CHR(10),
|
|
'If you did not make this change, please contact us immediately by replying to this email or through our support portal at https://support.modrinth.com (using',
|
|
'the green chat bubble at the bottom of the page)'
|
|
)
|
|
);
|
|
|
|
INSERT INTO notifications_templates (channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
|
|
VALUES (
|
|
'email', 'payment_failed', 'Payment Failed for Modrinth', 'https://modrinth.com/email/payment-failed',
|
|
CONCAT(
|
|
'Hi {user.name},',
|
|
CHR(10),
|
|
CHR(10),
|
|
'Our attempt to collect payment for {paymentfailed.amount} from the payment card on file was unsuccessful. Please update your billing settings to avoid service termination.',
|
|
CHR(10),
|
|
'Update billing settings: {billing.url}'
|
|
)
|
|
); |