mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
feat(server): email notifications (#8447)
* feat(server): add `react-mail` as mail template engine and `nodemailer` * feat(server): add `smtp` related configs to `SystemConfig` * feat(web): add page for SMTP settings * feat(server): add `react-email.adapter` This adapter render the React-Email into HTML and plain/text email. The output is set as the body of the email. * feat(server): add `MailRepository` and `MailService` Allow to use the NestJS-modules-mailer module to send SMTP emails. This is the base transport for the `NotificationRepository` * feat(server): register the job dispatcher and Job for async email This allows to queue email sending jobs for the `EmailService`. * feat(server): add `NotificationRepository` and `NotificationService` This act as a middleware to properly route the notification to the right transport. As POC I've only implemented a simple SMTP transport. * feat(server): add `welcome` email template * feat(server): add the first notification on `createUser` in `UserService` This trigger an event for the `NotificationRepository` that once processes by using the global config and per-user config will carry the payload to the right notification transport. * chore: clean up * chore: clean up web * fix: type errors" * fix package lock * fix mail sending, option to ignore certs * chore: open api * chore: clean up * remove unused import * feat: email feature flag * chore: remove unused interface * small styling --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com> Co-authored-by: Daniel Dietzler <mail@ddietzler.dev> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
4b86c7a298
commit
9bce3417e9
60 changed files with 6499 additions and 371 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsInt,
|
||||
IsNotEmpty,
|
||||
|
|
@ -43,6 +44,7 @@ class CronValidator implements ValidatorConstraintInterface {
|
|||
const isLibraryScanEnabled = (config: SystemConfigLibraryScanDto) => config.enabled;
|
||||
const isOAuthEnabled = (config: SystemConfigOAuthDto) => config.enabled;
|
||||
const isOAuthOverrideEnabled = (config: SystemConfigOAuthDto) => config.mobileOverrideEnabled;
|
||||
const isEmailNotificationEnabled = (config: SystemConfigSmtpDto) => config.enabled;
|
||||
|
||||
export class SystemConfigFFmpegDto {
|
||||
@IsInt()
|
||||
|
|
@ -202,6 +204,12 @@ class SystemConfigJobDto implements Record<ConcurrentQueueName, JobSettingsDto>
|
|||
@IsObject()
|
||||
@Type(() => JobSettingsDto)
|
||||
[QueueName.LIBRARY]!: JobSettingsDto;
|
||||
|
||||
@ApiProperty({ type: JobSettingsDto })
|
||||
@ValidateNested()
|
||||
@IsObject()
|
||||
@Type(() => JobSettingsDto)
|
||||
[QueueName.NOTIFICATION]!: JobSettingsDto;
|
||||
}
|
||||
|
||||
class SystemConfigLibraryScanDto {
|
||||
|
|
@ -358,6 +366,53 @@ class SystemConfigServerDto {
|
|||
loginPageMessage!: string;
|
||||
}
|
||||
|
||||
class SystemConfigSmtpTransportDto {
|
||||
@IsBoolean()
|
||||
ignoreCert!: boolean;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
host!: string;
|
||||
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
@Max(65_535)
|
||||
port!: number;
|
||||
|
||||
@IsString()
|
||||
username!: string;
|
||||
|
||||
@IsString()
|
||||
password!: string;
|
||||
}
|
||||
|
||||
class SystemConfigSmtpDto {
|
||||
@IsBoolean()
|
||||
enabled!: boolean;
|
||||
|
||||
@ValidateIf(isEmailNotificationEnabled)
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
from!: string;
|
||||
|
||||
@IsString()
|
||||
replyTo!: string;
|
||||
|
||||
@ValidateIf(isEmailNotificationEnabled)
|
||||
@Type(() => SystemConfigSmtpTransportDto)
|
||||
@ValidateNested()
|
||||
@IsObject()
|
||||
transport!: SystemConfigSmtpTransportDto;
|
||||
}
|
||||
|
||||
class SystemConfigNotificationsDto {
|
||||
@Type(() => SystemConfigSmtpDto)
|
||||
@ValidateNested()
|
||||
@IsObject()
|
||||
smtp!: SystemConfigSmtpDto;
|
||||
}
|
||||
|
||||
class SystemConfigStorageTemplateDto {
|
||||
@ValidateBoolean()
|
||||
enabled!: boolean;
|
||||
|
|
@ -512,6 +567,11 @@ export class SystemConfigDto implements SystemConfig {
|
|||
@IsObject()
|
||||
library!: SystemConfigLibraryDto;
|
||||
|
||||
@Type(() => SystemConfigNotificationsDto)
|
||||
@ValidateNested()
|
||||
@IsObject()
|
||||
notifications!: SystemConfigNotificationsDto;
|
||||
|
||||
@Type(() => SystemConfigServerDto)
|
||||
@ValidateNested()
|
||||
@IsObject()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue