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
10
mobile/openapi/lib/model/server_features_dto.dart
generated
10
mobile/openapi/lib/model/server_features_dto.dart
generated
|
|
@ -14,6 +14,7 @@ class ServerFeaturesDto {
|
|||
/// Returns a new [ServerFeaturesDto] instance.
|
||||
ServerFeaturesDto({
|
||||
required this.configFile,
|
||||
required this.email,
|
||||
required this.facialRecognition,
|
||||
required this.map,
|
||||
required this.oauth,
|
||||
|
|
@ -28,6 +29,8 @@ class ServerFeaturesDto {
|
|||
|
||||
bool configFile;
|
||||
|
||||
bool email;
|
||||
|
||||
bool facialRecognition;
|
||||
|
||||
bool map;
|
||||
|
|
@ -51,6 +54,7 @@ class ServerFeaturesDto {
|
|||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is ServerFeaturesDto &&
|
||||
other.configFile == configFile &&
|
||||
other.email == email &&
|
||||
other.facialRecognition == facialRecognition &&
|
||||
other.map == map &&
|
||||
other.oauth == oauth &&
|
||||
|
|
@ -66,6 +70,7 @@ class ServerFeaturesDto {
|
|||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(configFile.hashCode) +
|
||||
(email.hashCode) +
|
||||
(facialRecognition.hashCode) +
|
||||
(map.hashCode) +
|
||||
(oauth.hashCode) +
|
||||
|
|
@ -78,11 +83,12 @@ class ServerFeaturesDto {
|
|||
(trash.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'ServerFeaturesDto[configFile=$configFile, facialRecognition=$facialRecognition, map=$map, oauth=$oauth, oauthAutoLaunch=$oauthAutoLaunch, passwordLogin=$passwordLogin, reverseGeocoding=$reverseGeocoding, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, trash=$trash]';
|
||||
String toString() => 'ServerFeaturesDto[configFile=$configFile, email=$email, facialRecognition=$facialRecognition, map=$map, oauth=$oauth, oauthAutoLaunch=$oauthAutoLaunch, passwordLogin=$passwordLogin, reverseGeocoding=$reverseGeocoding, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, trash=$trash]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'configFile'] = this.configFile;
|
||||
json[r'email'] = this.email;
|
||||
json[r'facialRecognition'] = this.facialRecognition;
|
||||
json[r'map'] = this.map;
|
||||
json[r'oauth'] = this.oauth;
|
||||
|
|
@ -105,6 +111,7 @@ class ServerFeaturesDto {
|
|||
|
||||
return ServerFeaturesDto(
|
||||
configFile: mapValueOfType<bool>(json, r'configFile')!,
|
||||
email: mapValueOfType<bool>(json, r'email')!,
|
||||
facialRecognition: mapValueOfType<bool>(json, r'facialRecognition')!,
|
||||
map: mapValueOfType<bool>(json, r'map')!,
|
||||
oauth: mapValueOfType<bool>(json, r'oauth')!,
|
||||
|
|
@ -163,6 +170,7 @@ class ServerFeaturesDto {
|
|||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'configFile',
|
||||
'email',
|
||||
'facialRecognition',
|
||||
'map',
|
||||
'oauth',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue