mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-19 05:55:34 +09:00
chore(repo): prune dead code and duplicate abstractions (#3413)
This commit is contained in:
1 parent
c17091768c
commit
c9fdf8fead
2937 files changed
+42233
-176793
No files matched your search
@@ -10,28 +10,8 @@ export interface SentEmailRecord {
|
||||
metadata: Record<string, string>;
|
||||
}
|
||||
|
||||
function maskToken(token: string): string {
|
||||
if (token.length <= 8) {
|
||||
return '*'.repeat(token.length);
|
||||
}
|
||||
return `${token.slice(0, 4)}...${token.slice(-4)}`;
|
||||
}
|
||||
|
||||
const noopLogger = {info: (_message: string) => {}};
|
||||
|
||||
export class TestEmailService implements IEmailService {
|
||||
private readonly sentEmails: Array<SentEmailRecord> = [];
|
||||
private readonly logger: {
|
||||
info: (message: string) => void;
|
||||
};
|
||||
|
||||
constructor(options?: {
|
||||
logger?: {
|
||||
info: (message: string) => void;
|
||||
};
|
||||
}) {
|
||||
this.logger = options?.logger ?? noopLogger;
|
||||
}
|
||||
|
||||
listSentEmails(): Array<SentEmailRecord> {
|
||||
return [...this.sentEmails];
|
||||
@@ -43,51 +23,41 @@ export class TestEmailService implements IEmailService {
|
||||
|
||||
async sendPasswordResetEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
resetToken: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Password reset email sent to ${email} for user ${username}, token: ${maskToken(resetToken)}`);
|
||||
return this.record(email, 'password_reset', {token: resetToken});
|
||||
}
|
||||
|
||||
async sendEmailVerification(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
verificationToken: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Email verification sent to ${email} for user ${username}, token: ${maskToken(verificationToken)}`,
|
||||
);
|
||||
return this.record(email, 'email_verification', {token: verificationToken});
|
||||
}
|
||||
|
||||
async sendIpAuthorizationEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
authorizationToken: string,
|
||||
ipAddress: string,
|
||||
location: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`IP authorization email sent to ${email} for user ${username}, IP: ${ipAddress}, location: ${location}`,
|
||||
);
|
||||
return this.record(email, 'ip_authorization', {token: authorizationToken, ip: ipAddress, location});
|
||||
}
|
||||
|
||||
async sendAccountTempBannedEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
reason: string | null,
|
||||
durationHours: number,
|
||||
bannedUntil: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Temp ban email sent to ${email} for user ${username}, ${durationHours}h until ${bannedUntil.toISOString()}`,
|
||||
);
|
||||
return this.record(email, 'account_temp_banned', {
|
||||
reason: reason ?? '',
|
||||
duration_hours: durationHours.toString(10),
|
||||
@@ -97,14 +67,11 @@ export class TestEmailService implements IEmailService {
|
||||
|
||||
async sendAccountScheduledForDeletionEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
reason: string | null,
|
||||
deletionDate: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Scheduled deletion email sent to ${email} for user ${username}, date: ${deletionDate.toISOString()}`,
|
||||
);
|
||||
return this.record(email, 'account_scheduled_deletion', {
|
||||
reason: reason ?? '',
|
||||
deletion_date: deletionDate.toISOString(),
|
||||
@@ -113,24 +80,20 @@ export class TestEmailService implements IEmailService {
|
||||
|
||||
async sendSelfDeletionScheduledEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
deletionDate: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Self deletion email sent to ${email} for user ${username}, date: ${deletionDate.toISOString()}`);
|
||||
return this.record(email, 'self_deletion_scheduled', {deletion_date: deletionDate.toISOString()});
|
||||
}
|
||||
|
||||
async sendAccountDeletionRequestedEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
reason: string | null,
|
||||
deletionDate: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Requested deletion email sent to ${email} for user ${username}, date: ${deletionDate.toISOString()}`,
|
||||
);
|
||||
return this.record(email, 'account_deletion_scheduled_requested', {
|
||||
reason: reason ?? '',
|
||||
deletion_date: deletionDate.toISOString(),
|
||||
@@ -139,45 +102,37 @@ export class TestEmailService implements IEmailService {
|
||||
|
||||
async sendAccountDeletionInactivityEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
reason: string | null,
|
||||
deletionDate: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Inactivity deletion email sent to ${email} for user ${username}, date: ${deletionDate.toISOString()}`,
|
||||
);
|
||||
return this.record(email, 'account_deletion_scheduled_inactivity', {
|
||||
reason: reason ?? '',
|
||||
deletion_date: deletionDate.toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
async sendAccountDeletionCancelledEmail(email: string, username: string, _locale?: string | null): Promise<boolean> {
|
||||
this.logger.info(`Deletion cancelled email sent to ${email} for user ${username}`);
|
||||
async sendAccountDeletionCancelledEmail(email: string, _username: string, _locale?: string | null): Promise<boolean> {
|
||||
return this.record(email, 'account_deletion_cancelled');
|
||||
}
|
||||
|
||||
async sendUnbanNotification(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
reason: string | null,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Unban notification sent to ${email} for user ${username}, reason: ${reason ?? 'none'}`);
|
||||
return this.record(email, 'unban_notification', {reason: reason ?? ''});
|
||||
}
|
||||
|
||||
async sendScheduledDeletionNotification(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
deletionDate: Date,
|
||||
reason: string | null,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Scheduled deletion notification sent to ${email} for user ${username}, date: ${deletionDate.toISOString()}`,
|
||||
);
|
||||
return this.record(email, 'scheduled_deletion_notification', {
|
||||
deletion_date: deletionDate.toISOString(),
|
||||
reason: reason ?? '',
|
||||
@@ -186,14 +141,11 @@ export class TestEmailService implements IEmailService {
|
||||
|
||||
async sendInactivityWarningEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
deletionDate: Date,
|
||||
lastActiveDate: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Inactivity warning sent to ${email} for user ${username}, deletion: ${deletionDate.toISOString()}`,
|
||||
);
|
||||
return this.record(email, 'inactivity_warning', {
|
||||
deletion_date: deletionDate.toISOString(),
|
||||
last_active_date: lastActiveDate.toISOString(),
|
||||
@@ -202,16 +154,13 @@ export class TestEmailService implements IEmailService {
|
||||
|
||||
async sendHarvestCompletedEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
downloadUrl: string,
|
||||
totalMessages: number,
|
||||
fileSize: number,
|
||||
expiresAt: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Harvest completed email sent to ${email} for user ${username}, ${totalMessages} messages, ${fileSize} bytes`,
|
||||
);
|
||||
return this.record(email, 'harvest_completed', {
|
||||
download_url: downloadUrl,
|
||||
total_messages: totalMessages.toString(10),
|
||||
@@ -220,19 +169,17 @@ export class TestEmailService implements IEmailService {
|
||||
});
|
||||
}
|
||||
|
||||
async sendGiftChargebackNotification(email: string, username: string, _locale?: string | null): Promise<boolean> {
|
||||
this.logger.info(`Gift chargeback notification sent to ${email} for user ${username}`);
|
||||
async sendGiftChargebackNotification(email: string, _username: string, _locale?: string | null): Promise<boolean> {
|
||||
return this.record(email, 'gift_chargeback_notification');
|
||||
}
|
||||
|
||||
async sendReportResolvedEmail(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
reportId: string,
|
||||
publicComment: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Report resolved email sent to ${email} for user ${username}, report: ${reportId}`);
|
||||
return this.record(email, 'report_resolved', {report_id: reportId, public_comment: publicComment});
|
||||
}
|
||||
|
||||
@@ -242,7 +189,6 @@ export class TestEmailService implements IEmailService {
|
||||
publicComment: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`DSA report resolved email sent to ${email}, report: ${reportId}`);
|
||||
return this.record(email, 'dsa_report_resolved', {report_id: reportId, public_comment: publicComment});
|
||||
}
|
||||
|
||||
@@ -252,7 +198,6 @@ export class TestEmailService implements IEmailService {
|
||||
targetKind: ReportReceivedTargetKind,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Report received email sent to ${email}, report: ${reportId}`);
|
||||
return this.record(email, 'report_received', {report_id: reportId, target_kind: targetKind});
|
||||
}
|
||||
|
||||
@@ -262,53 +207,47 @@ export class TestEmailService implements IEmailService {
|
||||
expiresAt: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`DSA report verification code sent to ${email}, code: ${maskToken(code)}`);
|
||||
return this.record(email, 'dsa_report_verification', {code, expires_at: expiresAt.toISOString()});
|
||||
}
|
||||
|
||||
async sendPasswordChangeVerification(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
code: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Password change verification sent to ${email} for user ${username}`);
|
||||
return this.record(email, 'password_change_verification', {code});
|
||||
}
|
||||
|
||||
async sendMfaBackupCodesVerification(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
code: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`MFA backup codes verification sent to ${email} for user ${username}`);
|
||||
return this.record(email, 'mfa_backup_codes_view', {code});
|
||||
}
|
||||
|
||||
async sendEmailChangeOriginal(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
code: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Email change original verification sent to ${email} for user ${username}`);
|
||||
return this.record(email, 'email_change_original', {code});
|
||||
}
|
||||
|
||||
async sendEmailChangeNew(email: string, username: string, code: string, _locale?: string | null): Promise<boolean> {
|
||||
this.logger.info(`Email change new verification sent to ${email} for user ${username}`);
|
||||
async sendEmailChangeNew(email: string, _username: string, code: string, _locale?: string | null): Promise<boolean> {
|
||||
return this.record(email, 'email_change_new', {code});
|
||||
}
|
||||
|
||||
async sendEmailChangeRevert(
|
||||
email: string,
|
||||
username: string,
|
||||
_username: string,
|
||||
newEmail: string,
|
||||
token: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(`Email change revert notice sent to ${email} for user ${username}`);
|
||||
return this.record(email, 'email_change_revert', {token, new_email: newEmail});
|
||||
}
|
||||
|
||||
@@ -319,9 +258,6 @@ export class TestEmailService implements IEmailService {
|
||||
expiresAt: Date,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Donation magic link sent to ${email}, token: ${maskToken(token)}, expires: ${expiresAt.toISOString()}`,
|
||||
);
|
||||
return this.record(email, 'donation_magic_link', {
|
||||
token,
|
||||
manage_url: manageUrl,
|
||||
@@ -337,9 +273,6 @@ export class TestEmailService implements IEmailService {
|
||||
manageUrl: string,
|
||||
_locale?: string | null,
|
||||
): Promise<boolean> {
|
||||
this.logger.info(
|
||||
`Donation confirmation sent to ${email}, amount: ${amountCents / 100} ${currency.toUpperCase()}/${interval}`,
|
||||
);
|
||||
return this.record(email, 'donation_confirmation', {
|
||||
amount: (amountCents / 100).toString(),
|
||||
currency: currency.toUpperCase(),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {identityLocale} from '@fluxer/i18n/src/normalization/IdentityLocale';
|
||||
import {compileMessage} from '@fluxer/i18n/src/runtime/CompileMessage';
|
||||
import {createStaticI18n} from '@fluxer/i18n/src/runtime/CreateStaticI18n';
|
||||
import type {I18nResult} from '@fluxer/i18n/src/runtime/I18nTypes';
|
||||
@@ -43,7 +42,6 @@ const emailI18n = createStaticI18n<EmailTemplateKey, EmailTemplate, Record<strin
|
||||
defaultLocale: DEFAULT_LOCALE,
|
||||
defaultMessages: EMAIL_I18N_MESSAGES,
|
||||
localeMessages: EMAIL_I18N_LOCALE_MESSAGES,
|
||||
normalizeLocale: (locale) => identityLocale(locale),
|
||||
onWarning: (message) => {
|
||||
if (message.startsWith('Unsupported locale, falling back to en-US:')) {
|
||||
console.warn(
|
||||
|
||||
@@ -95,20 +95,6 @@ const FIXTURE: {[K in EmailTemplateKey]: EmailTemplateVariables[K]} = {
|
||||
};
|
||||
|
||||
describe('EmailI18n locale files', () => {
|
||||
it.each(LOCALES)('%s loads without module errors', (locale) => {
|
||||
const template = getEmailTemplate(
|
||||
'email_verification',
|
||||
locale,
|
||||
{username: 'testuser', verifyUrl: 'https://example.com/verify'},
|
||||
'Fluxer',
|
||||
);
|
||||
expect(template.ok).toBe(true);
|
||||
});
|
||||
it.each(LOCALES)('%s has the same translation keys as the source catalog', (locale) => {
|
||||
const messagesKeys = Object.keys(EMAIL_I18N_MESSAGES).sort();
|
||||
const localeKeys = Object.keys(EMAIL_I18N_LOCALE_MESSAGES[locale]).sort();
|
||||
expect(localeKeys).toEqual(messagesKeys);
|
||||
});
|
||||
it.each(LOCALES)('%s keeps the source placeholders in every template', (locale) => {
|
||||
const messages: Partial<Record<EmailTemplateKey, {subject: string; body: string}>> =
|
||||
EMAIL_I18N_LOCALE_MESSAGES[locale];
|
||||
|
||||
Reference in new issue
Block a user