diff --git a/server/src/controllers/notification-admin.controller.ts b/server/src/controllers/notification-admin.controller.ts
index f3ce4cdac9..937244fc56 100644
--- a/server/src/controllers/notification-admin.controller.ts
+++ b/server/src/controllers/notification-admin.controller.ts
@@ -4,7 +4,7 @@ import { AuthDto } from 'src/dtos/auth.dto';
 import { TemplateDto, TemplateResponseDto, TestEmailResponseDto } from 'src/dtos/notification.dto';
 import { SystemConfigSmtpDto } from 'src/dtos/system-config.dto';
 import { Auth, Authenticated } from 'src/middleware/auth.guard';
-import { EmailTemplate } from 'src/repositories/notification.repository';
+import { EmailTemplate } from 'src/repositories/email.repository';
 import { NotificationService } from 'src/services/notification.service';
 
 @ApiTags('Notifications (Admin)')
diff --git a/server/src/emails/album-invite.email.tsx b/server/src/emails/album-invite.email.tsx
index 4bd7abc305..fdc189af97 100644
--- a/server/src/emails/album-invite.email.tsx
+++ b/server/src/emails/album-invite.email.tsx
@@ -2,7 +2,7 @@ import { Img, Link, Section, Text } from '@react-email/components';
 import * as React from 'react';
 import { ImmichButton } from 'src/emails/components/button.component';
 import ImmichLayout from 'src/emails/components/immich.layout';
-import { AlbumInviteEmailProps } from 'src/repositories/notification.repository';
+import { AlbumInviteEmailProps } from 'src/repositories/email.repository';
 import { replaceTemplateTags } from 'src/utils/replace-template-tags';
 
 export const AlbumInviteEmail = ({
diff --git a/server/src/emails/album-update.email.tsx b/server/src/emails/album-update.email.tsx
index 2311e896e1..3bed3a5b36 100644
--- a/server/src/emails/album-update.email.tsx
+++ b/server/src/emails/album-update.email.tsx
@@ -2,7 +2,7 @@ import { Img, Link, Section, Text } from '@react-email/components';
 import * as React from 'react';
 import { ImmichButton } from 'src/emails/components/button.component';
 import ImmichLayout from 'src/emails/components/immich.layout';
-import { AlbumUpdateEmailProps } from 'src/repositories/notification.repository';
+import { AlbumUpdateEmailProps } from 'src/repositories/email.repository';
 import { replaceTemplateTags } from 'src/utils/replace-template-tags';
 
 export const AlbumUpdateEmail = ({
diff --git a/server/src/emails/test.email.tsx b/server/src/emails/test.email.tsx
index ac9bdbe0ea..0d87307080 100644
--- a/server/src/emails/test.email.tsx
+++ b/server/src/emails/test.email.tsx
@@ -1,7 +1,7 @@
 import { Link, Row, Text } from '@react-email/components';
 import * as React from 'react';
 import ImmichLayout from 'src/emails/components/immich.layout';
-import { TestEmailProps } from 'src/repositories/notification.repository';
+import { TestEmailProps } from 'src/repositories/email.repository';
 
 export const TestEmail = ({ baseUrl, displayName }: TestEmailProps) => (
   <ImmichLayout preview="This is a test email from Immich.">
diff --git a/server/src/emails/welcome.email.tsx b/server/src/emails/welcome.email.tsx
index 11a6602711..57e86ab252 100644
--- a/server/src/emails/welcome.email.tsx
+++ b/server/src/emails/welcome.email.tsx
@@ -2,7 +2,7 @@ import { Link, Section, Text } from '@react-email/components';
 import * as React from 'react';
 import { ImmichButton } from 'src/emails/components/button.component';
 import ImmichLayout from 'src/emails/components/immich.layout';
-import { WelcomeEmailProps } from 'src/repositories/notification.repository';
+import { WelcomeEmailProps } from 'src/repositories/email.repository';
 import { replaceTemplateTags } from 'src/utils/replace-template-tags';
 
 export const WelcomeEmail = ({ baseUrl, displayName, username, password, customTemplate }: WelcomeEmailProps) => {
diff --git a/server/src/repositories/notification.repository.spec.ts b/server/src/repositories/email.repository.spec.ts
similarity index 87%
rename from server/src/repositories/notification.repository.spec.ts
rename to server/src/repositories/email.repository.spec.ts
index 1d0770af6b..5640b26bf6 100644
--- a/server/src/repositories/notification.repository.spec.ts
+++ b/server/src/repositories/email.repository.spec.ts
@@ -1,13 +1,13 @@
+import { EmailRenderRequest, EmailRepository, EmailTemplate } from 'src/repositories/email.repository';
 import { LoggingRepository } from 'src/repositories/logging.repository';
-import { EmailRenderRequest, EmailTemplate, NotificationRepository } from 'src/repositories/notification.repository';
 import { automock } from 'test/utils';
 
-describe(NotificationRepository.name, () => {
-  let sut: NotificationRepository;
+describe(EmailRepository.name, () => {
+  let sut: EmailRepository;
 
   beforeEach(() => {
     // eslint-disable-next-line no-sparse-arrays
-    sut = new NotificationRepository(automock(LoggingRepository, { args: [, { getEnv: () => ({}) }], strict: false }));
+    sut = new EmailRepository(automock(LoggingRepository, { args: [, { getEnv: () => ({}) }], strict: false }));
   });
 
   describe('renderEmail', () => {
diff --git a/server/src/repositories/notification.repository.ts b/server/src/repositories/email.repository.ts
similarity index 97%
rename from server/src/repositories/notification.repository.ts
rename to server/src/repositories/email.repository.ts
index 91f03b928b..78c89b4a9d 100644
--- a/server/src/repositories/notification.repository.ts
+++ b/server/src/repositories/email.repository.ts
@@ -98,9 +98,9 @@ export type SendEmailResponse = {
 };
 
 @Injectable()
-export class NotificationRepository {
+export class EmailRepository {
   constructor(private logger: LoggingRepository) {
-    this.logger.setContext(NotificationRepository.name);
+    this.logger.setContext(EmailRepository.name);
   }
 
   verifySmtp(options: SmtpOptions): Promise<true> {
diff --git a/server/src/repositories/index.ts b/server/src/repositories/index.ts
index ef36a2b3f8..bd2e5c6774 100644
--- a/server/src/repositories/index.ts
+++ b/server/src/repositories/index.ts
@@ -11,6 +11,7 @@ import { CronRepository } from 'src/repositories/cron.repository';
 import { CryptoRepository } from 'src/repositories/crypto.repository';
 import { DatabaseRepository } from 'src/repositories/database.repository';
 import { DownloadRepository } from 'src/repositories/download.repository';
+import { EmailRepository } from 'src/repositories/email.repository';
 import { EventRepository } from 'src/repositories/event.repository';
 import { JobRepository } from 'src/repositories/job.repository';
 import { LibraryRepository } from 'src/repositories/library.repository';
@@ -21,7 +22,6 @@ import { MediaRepository } from 'src/repositories/media.repository';
 import { MemoryRepository } from 'src/repositories/memory.repository';
 import { MetadataRepository } from 'src/repositories/metadata.repository';
 import { MoveRepository } from 'src/repositories/move.repository';
-import { NotificationRepository } from 'src/repositories/notification.repository';
 import { OAuthRepository } from 'src/repositories/oauth.repository';
 import { PartnerRepository } from 'src/repositories/partner.repository';
 import { PersonRepository } from 'src/repositories/person.repository';
@@ -65,7 +65,7 @@ export const repositories = [
   MemoryRepository,
   MetadataRepository,
   MoveRepository,
-  NotificationRepository,
+  EmailRepository,
   OAuthRepository,
   PartnerRepository,
   PersonRepository,
diff --git a/server/src/services/base.service.ts b/server/src/services/base.service.ts
index 2fbdd6e4c0..23ddb1b63e 100644
--- a/server/src/services/base.service.ts
+++ b/server/src/services/base.service.ts
@@ -18,6 +18,7 @@ import { CronRepository } from 'src/repositories/cron.repository';
 import { CryptoRepository } from 'src/repositories/crypto.repository';
 import { DatabaseRepository } from 'src/repositories/database.repository';
 import { DownloadRepository } from 'src/repositories/download.repository';
+import { EmailRepository } from 'src/repositories/email.repository';
 import { EventRepository } from 'src/repositories/event.repository';
 import { JobRepository } from 'src/repositories/job.repository';
 import { LibraryRepository } from 'src/repositories/library.repository';
@@ -28,7 +29,6 @@ import { MediaRepository } from 'src/repositories/media.repository';
 import { MemoryRepository } from 'src/repositories/memory.repository';
 import { MetadataRepository } from 'src/repositories/metadata.repository';
 import { MoveRepository } from 'src/repositories/move.repository';
-import { NotificationRepository } from 'src/repositories/notification.repository';
 import { OAuthRepository } from 'src/repositories/oauth.repository';
 import { PartnerRepository } from 'src/repositories/partner.repository';
 import { PersonRepository } from 'src/repositories/person.repository';
@@ -70,6 +70,7 @@ export class BaseService {
     protected cryptoRepository: CryptoRepository,
     protected databaseRepository: DatabaseRepository,
     protected downloadRepository: DownloadRepository,
+    protected emailRepository: EmailRepository,
     protected eventRepository: EventRepository,
     protected jobRepository: JobRepository,
     protected libraryRepository: LibraryRepository,
@@ -79,7 +80,6 @@ export class BaseService {
     protected memoryRepository: MemoryRepository,
     protected metadataRepository: MetadataRepository,
     protected moveRepository: MoveRepository,
-    protected notificationRepository: NotificationRepository,
     protected oauthRepository: OAuthRepository,
     protected partnerRepository: PartnerRepository,
     protected personRepository: PersonRepository,
diff --git a/server/src/services/notification.service.spec.ts b/server/src/services/notification.service.spec.ts
index 85e425b11f..5830260753 100644
--- a/server/src/services/notification.service.spec.ts
+++ b/server/src/services/notification.service.spec.ts
@@ -3,7 +3,7 @@ import { defaults, SystemConfig } from 'src/config';
 import { AlbumUser } from 'src/database';
 import { SystemConfigDto } from 'src/dtos/system-config.dto';
 import { AssetFileType, JobName, JobStatus, UserMetadataKey } from 'src/enum';
-import { EmailTemplate } from 'src/repositories/notification.repository';
+import { EmailTemplate } from 'src/repositories/email.repository';
 import { NotificationService } from 'src/services/notification.service';
 import { INotifyAlbumUpdateJob } from 'src/types';
 import { albumStub } from 'test/fixtures/album.stub';
@@ -74,18 +74,18 @@ describe(NotificationService.name, () => {
       const oldConfig = configs.smtpDisabled;
       const newConfig = configs.smtpEnabled;
 
-      mocks.notification.verifySmtp.mockResolvedValue(true);
+      mocks.email.verifySmtp.mockResolvedValue(true);
       await expect(sut.onConfigValidate({ oldConfig, newConfig })).resolves.not.toThrow();
-      expect(mocks.notification.verifySmtp).toHaveBeenCalledWith(newConfig.notifications.smtp.transport);
+      expect(mocks.email.verifySmtp).toHaveBeenCalledWith(newConfig.notifications.smtp.transport);
     });
 
     it('validates smtp config when transport changes', async () => {
       const oldConfig = configs.smtpEnabled;
       const newConfig = configs.smtpTransport;
 
-      mocks.notification.verifySmtp.mockResolvedValue(true);
+      mocks.email.verifySmtp.mockResolvedValue(true);
       await expect(sut.onConfigValidate({ oldConfig, newConfig })).resolves.not.toThrow();
-      expect(mocks.notification.verifySmtp).toHaveBeenCalledWith(newConfig.notifications.smtp.transport);
+      expect(mocks.email.verifySmtp).toHaveBeenCalledWith(newConfig.notifications.smtp.transport);
     });
 
     it('skips smtp validation when there are no changes', async () => {
@@ -93,7 +93,7 @@ describe(NotificationService.name, () => {
       const newConfig = { ...configs.smtpEnabled };
 
       await expect(sut.onConfigValidate({ oldConfig, newConfig })).resolves.not.toThrow();
-      expect(mocks.notification.verifySmtp).not.toHaveBeenCalled();
+      expect(mocks.email.verifySmtp).not.toHaveBeenCalled();
     });
 
     it('skips smtp validation with DTO when there are no changes', async () => {
@@ -101,7 +101,7 @@ describe(NotificationService.name, () => {
       const newConfig = plainToInstance(SystemConfigDto, configs.smtpEnabled);
 
       await expect(sut.onConfigValidate({ oldConfig, newConfig })).resolves.not.toThrow();
-      expect(mocks.notification.verifySmtp).not.toHaveBeenCalled();
+      expect(mocks.email.verifySmtp).not.toHaveBeenCalled();
     });
 
     it('skips smtp validation when smtp is disabled', async () => {
@@ -109,14 +109,14 @@ describe(NotificationService.name, () => {
       const newConfig = { ...configs.smtpDisabled };
 
       await expect(sut.onConfigValidate({ oldConfig, newConfig })).resolves.not.toThrow();
-      expect(mocks.notification.verifySmtp).not.toHaveBeenCalled();
+      expect(mocks.email.verifySmtp).not.toHaveBeenCalled();
     });
 
     it('should fail if smtp configuration is invalid', async () => {
       const oldConfig = configs.smtpDisabled;
       const newConfig = configs.smtpEnabled;
 
-      mocks.notification.verifySmtp.mockRejectedValue(new Error('Failed validating smtp'));
+      mocks.email.verifySmtp.mockRejectedValue(new Error('Failed validating smtp'));
       await expect(sut.onConfigValidate({ oldConfig, newConfig })).rejects.toBeInstanceOf(Error);
     });
   });
@@ -248,7 +248,7 @@ describe(NotificationService.name, () => {
 
     it('should throw error if smtp validation fails', async () => {
       mocks.user.get.mockResolvedValue(userStub.admin);
-      mocks.notification.verifySmtp.mockRejectedValue('');
+      mocks.email.verifySmtp.mockRejectedValue('');
 
       await expect(sut.sendTestEmail('', configs.smtpTransport.notifications.smtp)).rejects.toThrow(
         'Failed to verify SMTP configuration',
@@ -257,16 +257,16 @@ describe(NotificationService.name, () => {
 
     it('should send email to default domain', async () => {
       mocks.user.get.mockResolvedValue(userStub.admin);
-      mocks.notification.verifySmtp.mockResolvedValue(true);
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
-      mocks.notification.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
+      mocks.email.verifySmtp.mockResolvedValue(true);
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
 
       await expect(sut.sendTestEmail('', configs.smtpTransport.notifications.smtp)).resolves.not.toThrow();
-      expect(mocks.notification.renderEmail).toHaveBeenCalledWith({
+      expect(mocks.email.renderEmail).toHaveBeenCalledWith({
         template: EmailTemplate.TEST_EMAIL,
         data: { baseUrl: 'https://my.immich.app', displayName: userStub.admin.name },
       });
-      expect(mocks.notification.sendEmail).toHaveBeenCalledWith(
+      expect(mocks.email.sendEmail).toHaveBeenCalledWith(
         expect.objectContaining({
           subject: 'Test email from Immich',
           smtp: configs.smtpTransport.notifications.smtp.transport,
@@ -276,17 +276,17 @@ describe(NotificationService.name, () => {
 
     it('should send email to external domain', async () => {
       mocks.user.get.mockResolvedValue(userStub.admin);
-      mocks.notification.verifySmtp.mockResolvedValue(true);
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.verifySmtp.mockResolvedValue(true);
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.systemMetadata.get.mockResolvedValue({ server: { externalDomain: 'https://demo.immich.app' } });
-      mocks.notification.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
+      mocks.email.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
 
       await expect(sut.sendTestEmail('', configs.smtpTransport.notifications.smtp)).resolves.not.toThrow();
-      expect(mocks.notification.renderEmail).toHaveBeenCalledWith({
+      expect(mocks.email.renderEmail).toHaveBeenCalledWith({
         template: EmailTemplate.TEST_EMAIL,
         data: { baseUrl: 'https://demo.immich.app', displayName: userStub.admin.name },
       });
-      expect(mocks.notification.sendEmail).toHaveBeenCalledWith(
+      expect(mocks.email.sendEmail).toHaveBeenCalledWith(
         expect.objectContaining({
           subject: 'Test email from Immich',
           smtp: configs.smtpTransport.notifications.smtp.transport,
@@ -296,18 +296,18 @@ describe(NotificationService.name, () => {
 
     it('should send email with replyTo', async () => {
       mocks.user.get.mockResolvedValue(userStub.admin);
-      mocks.notification.verifySmtp.mockResolvedValue(true);
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
-      mocks.notification.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
+      mocks.email.verifySmtp.mockResolvedValue(true);
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
 
       await expect(
         sut.sendTestEmail('', { ...configs.smtpTransport.notifications.smtp, replyTo: 'demo@immich.app' }),
       ).resolves.not.toThrow();
-      expect(mocks.notification.renderEmail).toHaveBeenCalledWith({
+      expect(mocks.email.renderEmail).toHaveBeenCalledWith({
         template: EmailTemplate.TEST_EMAIL,
         data: { baseUrl: 'https://my.immich.app', displayName: userStub.admin.name },
       });
-      expect(mocks.notification.sendEmail).toHaveBeenCalledWith(
+      expect(mocks.email.sendEmail).toHaveBeenCalledWith(
         expect.objectContaining({
           subject: 'Test email from Immich',
           smtp: configs.smtpTransport.notifications.smtp.transport,
@@ -325,7 +325,7 @@ describe(NotificationService.name, () => {
     it('should be successful', async () => {
       mocks.user.get.mockResolvedValue(userStub.admin);
       mocks.systemMetadata.get.mockResolvedValue({ server: {} });
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
 
       await expect(sut.handleUserSignup({ id: '' })).resolves.toBe(JobStatus.SUCCESS);
       expect(mocks.job.queue).toHaveBeenCalledWith({
@@ -390,7 +390,7 @@ describe(NotificationService.name, () => {
         ],
       });
       mocks.systemMetadata.get.mockResolvedValue({ server: {} });
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
 
       await expect(sut.handleAlbumInvite({ id: '', recipientId: '' })).resolves.toBe(JobStatus.SUCCESS);
       expect(mocks.job.queue).toHaveBeenCalledWith({
@@ -411,7 +411,7 @@ describe(NotificationService.name, () => {
         ],
       });
       mocks.systemMetadata.get.mockResolvedValue({ server: {} });
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.assetJob.getAlbumThumbnailFiles.mockResolvedValue([]);
 
       await expect(sut.handleAlbumInvite({ id: '', recipientId: '' })).resolves.toBe(JobStatus.SUCCESS);
@@ -440,7 +440,7 @@ describe(NotificationService.name, () => {
         ],
       });
       mocks.systemMetadata.get.mockResolvedValue({ server: {} });
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.assetJob.getAlbumThumbnailFiles.mockResolvedValue([
         { id: '1', type: AssetFileType.THUMBNAIL, path: 'path-to-thumb.jpg' },
       ]);
@@ -471,7 +471,7 @@ describe(NotificationService.name, () => {
         ],
       });
       mocks.systemMetadata.get.mockResolvedValue({ server: {} });
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.assetJob.getAlbumThumbnailFiles.mockResolvedValue([assetStub.image.files[2]]);
 
       await expect(sut.handleAlbumInvite({ id: '', recipientId: '' })).resolves.toBe(JobStatus.SUCCESS);
@@ -508,12 +508,12 @@ describe(NotificationService.name, () => {
         albumUsers: [{ user: { id: userStub.user1.id } } as AlbumUser],
       });
       mocks.user.get.mockResolvedValueOnce(userStub.user1);
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.assetJob.getAlbumThumbnailFiles.mockResolvedValue([]);
 
       await sut.handleAlbumUpdate({ id: '', recipientIds: [userStub.user1.id] });
       expect(mocks.user.get).toHaveBeenCalledWith(userStub.user1.id, { withDeleted: false });
-      expect(mocks.notification.renderEmail).not.toHaveBeenCalled();
+      expect(mocks.email.renderEmail).not.toHaveBeenCalled();
     });
 
     it('should skip recipient with disabled email notifications', async () => {
@@ -530,12 +530,12 @@ describe(NotificationService.name, () => {
           },
         ],
       });
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.assetJob.getAlbumThumbnailFiles.mockResolvedValue([]);
 
       await sut.handleAlbumUpdate({ id: '', recipientIds: [userStub.user1.id] });
       expect(mocks.user.get).toHaveBeenCalledWith(userStub.user1.id, { withDeleted: false });
-      expect(mocks.notification.renderEmail).not.toHaveBeenCalled();
+      expect(mocks.email.renderEmail).not.toHaveBeenCalled();
     });
 
     it('should skip recipient with disabled email notifications for the album update event', async () => {
@@ -552,12 +552,12 @@ describe(NotificationService.name, () => {
           },
         ],
       });
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.assetJob.getAlbumThumbnailFiles.mockResolvedValue([]);
 
       await sut.handleAlbumUpdate({ id: '', recipientIds: [userStub.user1.id] });
       expect(mocks.user.get).toHaveBeenCalledWith(userStub.user1.id, { withDeleted: false });
-      expect(mocks.notification.renderEmail).not.toHaveBeenCalled();
+      expect(mocks.email.renderEmail).not.toHaveBeenCalled();
     });
 
     it('should send email', async () => {
@@ -566,12 +566,12 @@ describe(NotificationService.name, () => {
         albumUsers: [{ user: { id: userStub.user1.id } } as AlbumUser],
       });
       mocks.user.get.mockResolvedValue(userStub.user1);
-      mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
+      mocks.email.renderEmail.mockResolvedValue({ html: '', text: '' });
       mocks.assetJob.getAlbumThumbnailFiles.mockResolvedValue([]);
 
       await sut.handleAlbumUpdate({ id: '', recipientIds: [userStub.user1.id] });
       expect(mocks.user.get).toHaveBeenCalledWith(userStub.user1.id, { withDeleted: false });
-      expect(mocks.notification.renderEmail).toHaveBeenCalled();
+      expect(mocks.email.renderEmail).toHaveBeenCalled();
       expect(mocks.job.queue).toHaveBeenCalled();
     });
 
@@ -599,24 +599,20 @@ describe(NotificationService.name, () => {
       mocks.systemMetadata.get.mockResolvedValue({
         notifications: { smtp: { enabled: true, from: 'test@immich.app' } },
       });
-      mocks.notification.sendEmail.mockResolvedValue({ messageId: '', response: '' });
+      mocks.email.sendEmail.mockResolvedValue({ messageId: '', response: '' });
 
       await expect(sut.handleSendEmail({ html: '', subject: '', text: '', to: '' })).resolves.toBe(JobStatus.SUCCESS);
-      expect(mocks.notification.sendEmail).toHaveBeenCalledWith(
-        expect.objectContaining({ replyTo: 'test@immich.app' }),
-      );
+      expect(mocks.email.sendEmail).toHaveBeenCalledWith(expect.objectContaining({ replyTo: 'test@immich.app' }));
     });
 
     it('should send mail with replyTo successfully', async () => {
       mocks.systemMetadata.get.mockResolvedValue({
         notifications: { smtp: { enabled: true, from: 'test@immich.app', replyTo: 'demo@immich.app' } },
       });
-      mocks.notification.sendEmail.mockResolvedValue({ messageId: '', response: '' });
+      mocks.email.sendEmail.mockResolvedValue({ messageId: '', response: '' });
 
       await expect(sut.handleSendEmail({ html: '', subject: '', text: '', to: '' })).resolves.toBe(JobStatus.SUCCESS);
-      expect(mocks.notification.sendEmail).toHaveBeenCalledWith(
-        expect.objectContaining({ replyTo: 'demo@immich.app' }),
-      );
+      expect(mocks.email.sendEmail).toHaveBeenCalledWith(expect.objectContaining({ replyTo: 'demo@immich.app' }));
     });
   });
 });
diff --git a/server/src/services/notification.service.ts b/server/src/services/notification.service.ts
index 2c4cc76756..2e456718ca 100644
--- a/server/src/services/notification.service.ts
+++ b/server/src/services/notification.service.ts
@@ -2,8 +2,8 @@ import { BadRequestException, Injectable } from '@nestjs/common';
 import { OnEvent, OnJob } from 'src/decorators';
 import { SystemConfigSmtpDto } from 'src/dtos/system-config.dto';
 import { AssetFileType, JobName, JobStatus, QueueName } from 'src/enum';
+import { EmailTemplate } from 'src/repositories/email.repository';
 import { ArgOf } from 'src/repositories/event.repository';
-import { EmailTemplate } from 'src/repositories/notification.repository';
 import { BaseService } from 'src/services/base.service';
 import { EmailImageAttachment, IEntityJob, INotifyAlbumUpdateJob, JobItem, JobOf } from 'src/types';
 import { getFilenameExtension } from 'src/utils/file';
@@ -28,7 +28,7 @@ export class NotificationService extends BaseService {
         newConfig.notifications.smtp.enabled &&
         !isEqualObject(oldConfig.notifications.smtp, newConfig.notifications.smtp)
       ) {
-        await this.notificationRepository.verifySmtp(newConfig.notifications.smtp.transport);
+        await this.emailRepository.verifySmtp(newConfig.notifications.smtp.transport);
       }
     } catch (error: Error | any) {
       this.logger.error(`Failed to validate SMTP configuration: ${error}`, error?.stack);
@@ -138,13 +138,13 @@ export class NotificationService extends BaseService {
     }
 
     try {
-      await this.notificationRepository.verifySmtp(dto.transport);
+      await this.emailRepository.verifySmtp(dto.transport);
     } catch (error) {
       throw new BadRequestException('Failed to verify SMTP configuration', { cause: error });
     }
 
     const { server } = await this.getConfig({ withCache: false });
-    const { html, text } = await this.notificationRepository.renderEmail({
+    const { html, text } = await this.emailRepository.renderEmail({
       template: EmailTemplate.TEST_EMAIL,
       data: {
         baseUrl: getExternalDomain(server),
@@ -152,7 +152,7 @@ export class NotificationService extends BaseService {
       },
       customTemplate: tempTemplate!,
     });
-    const { messageId } = await this.notificationRepository.sendEmail({
+    const { messageId } = await this.emailRepository.sendEmail({
       to: user.email,
       subject: 'Test email from Immich',
       html,
@@ -172,7 +172,7 @@ export class NotificationService extends BaseService {
 
     switch (name) {
       case EmailTemplate.WELCOME: {
-        const { html: _welcomeHtml } = await this.notificationRepository.renderEmail({
+        const { html: _welcomeHtml } = await this.emailRepository.renderEmail({
           template: EmailTemplate.WELCOME,
           data: {
             baseUrl: getExternalDomain(server),
@@ -187,7 +187,7 @@ export class NotificationService extends BaseService {
         break;
       }
       case EmailTemplate.ALBUM_UPDATE: {
-        const { html: _updateAlbumHtml } = await this.notificationRepository.renderEmail({
+        const { html: _updateAlbumHtml } = await this.emailRepository.renderEmail({
           template: EmailTemplate.ALBUM_UPDATE,
           data: {
             baseUrl: getExternalDomain(server),
@@ -203,7 +203,7 @@ export class NotificationService extends BaseService {
       }
 
       case EmailTemplate.ALBUM_INVITE: {
-        const { html } = await this.notificationRepository.renderEmail({
+        const { html } = await this.emailRepository.renderEmail({
           template: EmailTemplate.ALBUM_INVITE,
           data: {
             baseUrl: getExternalDomain(server),
@@ -235,7 +235,7 @@ export class NotificationService extends BaseService {
     }
 
     const { server, templates } = await this.getConfig({ withCache: true });
-    const { html, text } = await this.notificationRepository.renderEmail({
+    const { html, text } = await this.emailRepository.renderEmail({
       template: EmailTemplate.WELCOME,
       data: {
         baseUrl: getExternalDomain(server),
@@ -280,7 +280,7 @@ export class NotificationService extends BaseService {
     const attachment = await this.getAlbumThumbnailAttachment(album);
 
     const { server, templates } = await this.getConfig({ withCache: false });
-    const { html, text } = await this.notificationRepository.renderEmail({
+    const { html, text } = await this.emailRepository.renderEmail({
       template: EmailTemplate.ALBUM_INVITE,
       data: {
         baseUrl: getExternalDomain(server),
@@ -339,7 +339,7 @@ export class NotificationService extends BaseService {
         continue;
       }
 
-      const { html, text } = await this.notificationRepository.renderEmail({
+      const { html, text } = await this.emailRepository.renderEmail({
         template: EmailTemplate.ALBUM_UPDATE,
         data: {
           baseUrl: getExternalDomain(server),
@@ -374,7 +374,7 @@ export class NotificationService extends BaseService {
     }
 
     const { to, subject, html, text: plain } = data;
-    const response = await this.notificationRepository.sendEmail({
+    const response = await this.emailRepository.sendEmail({
       to,
       subject,
       html,
diff --git a/server/test/medium.factory.ts b/server/test/medium.factory.ts
index d3ab876e07..671a8a50ca 100644
--- a/server/test/medium.factory.ts
+++ b/server/test/medium.factory.ts
@@ -284,6 +284,7 @@ export const asDeps = (repositories: ServiceOverrides) => {
     repositories.crypto || getRepositoryMock('crypto'),
     repositories.database || getRepositoryMock('database'),
     repositories.downloadRepository,
+    repositories.email,
     repositories.event,
     repositories.job || getRepositoryMock('job'),
     repositories.library,
@@ -293,7 +294,6 @@ export const asDeps = (repositories: ServiceOverrides) => {
     repositories.memory || getRepositoryMock('memory'),
     repositories.metadata,
     repositories.move,
-    repositories.notification,
     repositories.oauth,
     repositories.partner || getRepositoryMock('partner'),
     repositories.person || getRepositoryMock('person'),
diff --git a/server/test/utils.ts b/server/test/utils.ts
index 52984d97a2..e1d979fbfe 100644
--- a/server/test/utils.ts
+++ b/server/test/utils.ts
@@ -18,6 +18,7 @@ import { CronRepository } from 'src/repositories/cron.repository';
 import { CryptoRepository } from 'src/repositories/crypto.repository';
 import { DatabaseRepository } from 'src/repositories/database.repository';
 import { DownloadRepository } from 'src/repositories/download.repository';
+import { EmailRepository } from 'src/repositories/email.repository';
 import { EventRepository } from 'src/repositories/event.repository';
 import { JobRepository } from 'src/repositories/job.repository';
 import { LibraryRepository } from 'src/repositories/library.repository';
@@ -28,7 +29,6 @@ import { MediaRepository } from 'src/repositories/media.repository';
 import { MemoryRepository } from 'src/repositories/memory.repository';
 import { MetadataRepository } from 'src/repositories/metadata.repository';
 import { MoveRepository } from 'src/repositories/move.repository';
-import { NotificationRepository } from 'src/repositories/notification.repository';
 import { OAuthRepository } from 'src/repositories/oauth.repository';
 import { PartnerRepository } from 'src/repositories/partner.repository';
 import { PersonRepository } from 'src/repositories/person.repository';
@@ -124,6 +124,7 @@ export type ServiceOverrides = {
   crypto: CryptoRepository;
   database: DatabaseRepository;
   downloadRepository: DownloadRepository;
+  email: EmailRepository;
   event: EventRepository;
   job: JobRepository;
   library: LibraryRepository;
@@ -134,7 +135,6 @@ export type ServiceOverrides = {
   memory: MemoryRepository;
   metadata: MetadataRepository;
   move: MoveRepository;
-  notification: NotificationRepository;
   oauth: OAuthRepository;
   partner: PartnerRepository;
   person: PersonRepository;
@@ -190,6 +190,7 @@ export const newTestService = <T extends BaseService>(
     config: newConfigRepositoryMock(),
     database: newDatabaseRepositoryMock(),
     downloadRepository: automock(DownloadRepository, { strict: false }),
+    email: automock(EmailRepository, { args: [loggerMock] }),
     // eslint-disable-next-line no-sparse-arrays
     event: automock(EventRepository, { args: [, , loggerMock], strict: false }),
     job: newJobRepositoryMock(),
@@ -201,7 +202,6 @@ export const newTestService = <T extends BaseService>(
     memory: automock(MemoryRepository),
     metadata: newMetadataRepositoryMock(),
     move: automock(MoveRepository, { strict: false }),
-    notification: automock(NotificationRepository, { args: [loggerMock] }),
     oauth: automock(OAuthRepository, { args: [loggerMock] }),
     partner: automock(PartnerRepository, { strict: false }),
     person: newPersonRepositoryMock(),
@@ -240,6 +240,7 @@ export const newTestService = <T extends BaseService>(
     overrides.crypto || (mocks.crypto as As<CryptoRepository>),
     overrides.database || (mocks.database as As<DatabaseRepository>),
     overrides.downloadRepository || (mocks.downloadRepository as As<DownloadRepository>),
+    overrides.email || (mocks.email as As<EmailRepository>),
     overrides.event || (mocks.event as As<EventRepository>),
     overrides.job || (mocks.job as As<JobRepository>),
     overrides.library || (mocks.library as As<LibraryRepository>),
@@ -249,7 +250,6 @@ export const newTestService = <T extends BaseService>(
     overrides.memory || (mocks.memory as As<MemoryRepository>),
     overrides.metadata || (mocks.metadata as As<MetadataRepository>),
     overrides.move || (mocks.move as As<MoveRepository>),
-    overrides.notification || (mocks.notification as As<NotificationRepository>),
     overrides.oauth || (mocks.oauth as As<OAuthRepository>),
     overrides.partner || (mocks.partner as As<PartnerRepository>),
     overrides.person || (mocks.person as As<PersonRepository>),