wip
This commit is contained in:
parent
c88167adfb
commit
eda102f0f3
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue