This commit is contained in:
syuilo 2024-09-21 20:58:36 +09:00
parent c88167adfb
commit eda102f0f3
2 changed files with 26 additions and 33 deletions

View File

@ -8,16 +8,14 @@ import * as nodemailer from 'nodemailer';
import juice from 'juice'; import juice from 'juice';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { validate as validateEmail } from 'deep-email-validator'; import { validate as validateEmail } from 'deep-email-validator';
import { MetaService } from '@/core/MetaService.js';
import { UtilityService } from '@/core/UtilityService.js'; import { UtilityService } from '@/core/UtilityService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import type Logger from '@/logger.js'; import type Logger from '@/logger.js';
import type { UserProfilesRepository } from '@/models/_.js'; import type { MiMeta, UserProfilesRepository } from '@/models/_.js';
import { LoggerService } from '@/core/LoggerService.js'; import { LoggerService } from '@/core/LoggerService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { HttpRequestService } from '@/core/HttpRequestService.js'; import { HttpRequestService } from '@/core/HttpRequestService.js';
import { QueueService } from '@/core/QueueService.js';
@Injectable() @Injectable()
export class EmailService { export class EmailService {
@ -27,38 +25,37 @@ export class EmailService {
@Inject(DI.config) @Inject(DI.config)
private config: Config, private config: Config,
@Inject(DI.meta)
private meta: MiMeta,
@Inject(DI.userProfilesRepository) @Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository, private userProfilesRepository: UserProfilesRepository,
private metaService: MetaService,
private loggerService: LoggerService, private loggerService: LoggerService,
private utilityService: UtilityService, private utilityService: UtilityService,
private httpRequestService: HttpRequestService, private httpRequestService: HttpRequestService,
private queueService: QueueService,
) { ) {
this.logger = this.loggerService.getLogger('email'); this.logger = this.loggerService.getLogger('email');
} }
@bindThis @bindThis
public async sendEmail(to: string, subject: string, html: string, text: string) { public async sendEmail(to: string, subject: string, html: string, text: string) {
const meta = await this.metaService.fetch(true); if (!this.meta.enableEmail) return;
if (!meta.enableEmail) return;
const iconUrl = `${this.config.url}/static-assets/mi-white.png`; const iconUrl = `${this.config.url}/static-assets/mi-white.png`;
const emailSettingUrl = `${this.config.url}/settings/email`; const emailSettingUrl = `${this.config.url}/settings/email`;
const enableAuth = meta.smtpUser != null && meta.smtpUser !== ''; const enableAuth = this.meta.smtpUser != null && this.meta.smtpUser !== '';
const transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
host: meta.smtpHost, host: this.meta.smtpHost,
port: meta.smtpPort, port: this.meta.smtpPort,
secure: meta.smtpSecure, secure: this.meta.smtpSecure,
ignoreTLS: !enableAuth, ignoreTLS: !enableAuth,
proxy: this.config.proxySmtp, proxy: this.config.proxySmtp,
auth: enableAuth ? { auth: enableAuth ? {
user: meta.smtpUser, user: this.meta.smtpUser,
pass: meta.smtpPass, pass: this.meta.smtpPass,
} : undefined, } : undefined,
} as any); } as any);
@ -127,7 +124,7 @@ export class EmailService {
<body> <body>
<main> <main>
<header> <header>
<img src="${ meta.logoImageUrl ?? meta.iconUrl ?? iconUrl }"/> <img src="${ this.meta.logoImageUrl ?? this.meta.iconUrl ?? iconUrl }"/>
</header> </header>
<article> <article>
<h1>${ subject }</h1> <h1>${ subject }</h1>
@ -148,7 +145,7 @@ export class EmailService {
try { try {
// TODO: htmlサニタイズ // TODO: htmlサニタイズ
const info = await transporter.sendMail({ const info = await transporter.sendMail({
from: meta.email!, from: this.meta.email!,
to: to, to: to,
subject: subject, subject: subject,
text: text, text: text,
@ -167,8 +164,6 @@ export class EmailService {
available: boolean; available: boolean;
reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned' | 'network' | 'blacklist'; reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned' | 'network' | 'blacklist';
}> { }> {
const meta = await this.metaService.fetch();
const exist = await this.userProfilesRepository.countBy({ const exist = await this.userProfilesRepository.countBy({
emailVerified: true, emailVerified: true,
email: emailAddress, email: emailAddress,
@ -186,11 +181,11 @@ export class EmailService {
reason?: string | null, reason?: string | null,
} = { valid: true, reason: null }; } = { valid: true, reason: null };
if (meta.enableActiveEmailValidation) { if (this.meta.enableActiveEmailValidation) {
if (meta.enableVerifymailApi && meta.verifymailAuthKey != null) { if (this.meta.enableVerifymailApi && this.meta.verifymailAuthKey != null) {
validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey); validated = await this.verifyMail(emailAddress, this.meta.verifymailAuthKey);
} else if (meta.enableTruemailApi && meta.truemailInstance && meta.truemailAuthKey != null) { } else if (this.meta.enableTruemailApi && this.meta.truemailInstance && this.meta.truemailAuthKey != null) {
validated = await this.trueMail(meta.truemailInstance, emailAddress, meta.truemailAuthKey); validated = await this.trueMail(this.meta.truemailInstance, emailAddress, this.meta.truemailAuthKey);
} else { } else {
validated = await validateEmail({ validated = await validateEmail({
email: emailAddress, email: emailAddress,
@ -220,7 +215,7 @@ export class EmailService {
} }
const emailDomain: string = emailAddress.split('@')[1]; const emailDomain: string = emailAddress.split('@')[1];
const isBanned = this.utilityService.isBlockedHost(meta.bannedEmailDomains, emailDomain); const isBanned = this.utilityService.isBlockedHost(this.meta.bannedEmailDomains, emailDomain);
if (isBanned) { if (isBanned) {
return { return {

View File

@ -10,8 +10,7 @@ import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import type { Packed } from '@/misc/json-schema.js'; import type { Packed } from '@/misc/json-schema.js';
import { getNoteSummary } from '@/misc/get-note-summary.js'; import { getNoteSummary } from '@/misc/get-note-summary.js';
import type { MiSwSubscription, SwSubscriptionsRepository } from '@/models/_.js'; import type { MiMeta, MiSwSubscription, SwSubscriptionsRepository } from '@/models/_.js';
import { MetaService } from '@/core/MetaService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { RedisKVCache } from '@/misc/cache.js'; import { RedisKVCache } from '@/misc/cache.js';
@ -54,13 +53,14 @@ export class PushNotificationService implements OnApplicationShutdown {
@Inject(DI.config) @Inject(DI.config)
private config: Config, private config: Config,
@Inject(DI.meta)
private meta: MiMeta,
@Inject(DI.redis) @Inject(DI.redis)
private redisClient: Redis.Redis, private redisClient: Redis.Redis,
@Inject(DI.swSubscriptionsRepository) @Inject(DI.swSubscriptionsRepository)
private swSubscriptionsRepository: SwSubscriptionsRepository, private swSubscriptionsRepository: SwSubscriptionsRepository,
private metaService: MetaService,
) { ) {
this.subscriptionsCache = new RedisKVCache<MiSwSubscription[]>(this.redisClient, 'userSwSubscriptions', { this.subscriptionsCache = new RedisKVCache<MiSwSubscription[]>(this.redisClient, 'userSwSubscriptions', {
lifetime: 1000 * 60 * 60 * 1, // 1h lifetime: 1000 * 60 * 60 * 1, // 1h
@ -73,14 +73,12 @@ export class PushNotificationService implements OnApplicationShutdown {
@bindThis @bindThis
public async pushNotification<T extends keyof PushNotificationsTypes>(userId: string, type: T, body: PushNotificationsTypes[T]) { public async pushNotification<T extends keyof PushNotificationsTypes>(userId: string, type: T, body: PushNotificationsTypes[T]) {
const meta = await this.metaService.fetch(); if (!this.meta.enableServiceWorker || this.meta.swPublicKey == null || this.meta.swPrivateKey == null) return;
if (!meta.enableServiceWorker || meta.swPublicKey == null || meta.swPrivateKey == null) return;
// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録 // アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
push.setVapidDetails(this.config.url, push.setVapidDetails(this.config.url,
meta.swPublicKey, this.meta.swPublicKey,
meta.swPrivateKey); this.meta.swPrivateKey);
const subscriptions = await this.subscriptionsCache.fetch(userId); const subscriptions = await this.subscriptionsCache.fetch(userId);