verifymail.io のレスポンスをキャッシュする (MisskeyIO#424)
This commit is contained in:
parent
253fc4591d
commit
258a17cb64
|
@ -7,6 +7,7 @@ import { URLSearchParams } from 'node:url';
|
||||||
import * as nodemailer from 'nodemailer';
|
import * as nodemailer from 'nodemailer';
|
||||||
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 Redis from 'ioredis';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
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';
|
||||||
|
@ -16,15 +17,24 @@ import type { 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 { RedisKVCache } from '@/misc/cache.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EmailService {
|
export class EmailService {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
|
private verifymailResponseCache: RedisKVCache<{
|
||||||
|
valid: boolean,
|
||||||
|
reason?: string | null,
|
||||||
|
}>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.config)
|
@Inject(DI.config)
|
||||||
private config: Config,
|
private config: Config,
|
||||||
|
|
||||||
|
@Inject(DI.redis)
|
||||||
|
private redisClient: Redis.Redis,
|
||||||
|
|
||||||
@Inject(DI.userProfilesRepository)
|
@Inject(DI.userProfilesRepository)
|
||||||
private userProfilesRepository: UserProfilesRepository,
|
private userProfilesRepository: UserProfilesRepository,
|
||||||
|
|
||||||
|
@ -34,6 +44,16 @@ export class EmailService {
|
||||||
private httpRequestService: HttpRequestService,
|
private httpRequestService: HttpRequestService,
|
||||||
) {
|
) {
|
||||||
this.logger = this.loggerService.getLogger('email');
|
this.logger = this.loggerService.getLogger('email');
|
||||||
|
this.verifymailResponseCache = new RedisKVCache<{
|
||||||
|
valid: boolean,
|
||||||
|
reason?: string | null,
|
||||||
|
}>(this.redisClient, 'verifymailResponse', {
|
||||||
|
lifetime: 1000 * 60 * 60 * 24 * 7, // 7d
|
||||||
|
memoryCacheLifetime: 1000 * 60 * 60 * 24 * 7, // 7d
|
||||||
|
fetcher: (key) => this.verifyMail(key),
|
||||||
|
toRedisConverter: (value) => JSON.stringify(value),
|
||||||
|
fromRedisConverter: (value) => JSON.parse(value),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
@ -190,7 +210,8 @@ export class EmailService {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (validated.valid && meta.enableVerifymailApi && meta.verifymailAuthKey != null) {
|
if (validated.valid && meta.enableVerifymailApi && meta.verifymailAuthKey != null) {
|
||||||
validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey);
|
const domain = emailAddress.split('@')[1];
|
||||||
|
validated = await this.verifymailResponseCache.fetch(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validated.valid && meta.enableTruemailApi && meta.truemailInstance && meta.truemailAuthKey != null) {
|
if (validated.valid && meta.enableTruemailApi && meta.truemailInstance && meta.truemailAuthKey != null) {
|
||||||
|
@ -230,11 +251,14 @@ export class EmailService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async verifyMail(emailAddress: string, verifymailAuthKey: string): Promise<{
|
private async verifyMail(domain: string): Promise<{
|
||||||
valid: boolean;
|
valid: boolean;
|
||||||
reason: 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | null;
|
reason: 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | null;
|
||||||
}> {
|
}> {
|
||||||
const endpoint = 'https://verifymail.io/api/' + emailAddress + '?key=' + verifymailAuthKey;
|
const meta = await this.metaService.fetch();
|
||||||
|
if (meta.verifymailAuthKey == null) throw new Error('verifymailAuthKey is not set');
|
||||||
|
|
||||||
|
const endpoint = 'https://verifymail.io/api/' + domain + '?key=' + meta.verifymailAuthKey;
|
||||||
const res = await this.httpRequestService.send(endpoint, {
|
const res = await this.httpRequestService.send(endpoint, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
|
|
Loading…
Reference in a new issue