Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@

e2e/npm-debug.log

angie.conf

proxy.js

start-proxy.js

start-proxy.sh
proxy.js
6 changes: 0 additions & 6 deletions package-lock.json

This file was deleted.

79 changes: 76 additions & 3 deletions src/API/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/API/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@nestjs-modules/mailer": "^1.6.1",
"@nestjs/apollo": "^12.2.0",
"@nestjs/axios": "^3.0.2",
"@nestjs/bull": "^11.0.5",
"@nestjs/bullmq": "^11.0.4",
"@nestjs/class-validator": "^0.13.4",
"@nestjs/common": "^10.0.0",
Expand All @@ -47,6 +48,7 @@
"@types/flat": "^5.0.2",
"apollo-server-express": "^3.9.0",
"axios": "^1.7.2",
"bull": "^4.16.5",
"bullmq": "^5.71.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",
Expand Down Expand Up @@ -85,6 +87,7 @@
"@nestjs/cli": "^9.1.5",
"@nestjs/schematics": "^9.0.3",
"@nestjs/testing": "^10.3.10",
"@types/bull": "^3.15.9",
"@types/express": "^4.17.13",
"@types/geojson": "^7946.0.8",
"@types/jest": "^27.5.0",
Expand Down Expand Up @@ -135,7 +138,6 @@
"src/db/migrations/*"
],
"coverageThreshold": {

"global": {
"branches": 70,
"lines": 85
Expand Down
4 changes: 3 additions & 1 deletion src/API/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { ScheduleModule } from '@nestjs/schedule';
import { BlobCleanupService } from './db/shared/blob-cleanup.service';
import { AzureBlobService } from './db/azure-blob/azure-blob.service';
import { CountryModule } from './db/country/country.module';
import { EmailRegistryModule } from './db/email-registry/email-registry.module';

@Module({
imports: [
Expand Down Expand Up @@ -78,7 +79,7 @@ import { CountryModule } from './db/country/country.module';
port: Number(process.env.EMAIL_PORT),
secure: false,
auth: {
user: process.env.EMAIL_FROM,
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASSWORD,
},
},
Expand All @@ -96,6 +97,7 @@ import { CountryModule } from './db/country/country.module';
ExportsModule,
FullOccurrenceDataModule,
CountryModule,
EmailRegistryModule,
],
controllers: [ConfigController],
providers: [AzureBlobService, BlobCleanupService],
Expand Down
1 change: 0 additions & 1 deletion src/API/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import { AllUserRolesResolver } from './user_role/all_user_roles.resolver';
import { HttpModule } from '@nestjs/axios';
import { CommunicationLog } from '../db/communication-log/entities/communication-log.entity';
import { EmailService } from '../email/email.service';

Check warning on line 17 in src/API/src/auth/auth.module.ts

View workflow job for this annotation

GitHub Actions / Build and Test API for test deployment environment

'EmailService' is defined but never used
import { EmailModule } from '../email/email.module';
import { CommunicationLogService } from 'src/db/communication-log/communication-log.service';

Expand All @@ -35,7 +35,6 @@
GqlAuthGuard,
AuthResolver,
AuthService,
EmailService,
CommunicationLogService,
Logger,
],
Expand Down
4 changes: 3 additions & 1 deletion src/API/src/dataset-upload/dataset-upload.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { DOI } from 'src/db/doi/entities/doi.entity';
import { EmailService } from '../email/email.service';
import { AzureBlobService } from 'src/db/azure-blob/azure-blob.service';
import { SharedModule } from 'src/db/shared/shared.module';
import { EmailModule } from 'src/email/email.module';

@Module({
controllers: [DatasetUploadController],
Expand All @@ -31,12 +32,13 @@ import { SharedModule } from 'src/db/shared/shared.module';
CommunicationLogService,
UploadedDatasetLogService,
DoiService,
EmailService,
//EmailService,
AzureBlobService,
Logger,
],
imports: [
HttpModule,
EmailModule,
SharedModule,
// DoiModule,
// UploadedDatasetModule,
Expand Down
20 changes: 8 additions & 12 deletions src/API/src/db/communication-log/mailer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ export const sendEmail = async (
subject: string,
message: string,
): Promise<EmailSendResponse> => {
// 1. Generic SMTP configuration reading directly from your environmental primitives
const transporter = nodemailer.createTransport({
service: 'gmail',
host: process.env.EMAIL_HOST,
port: Number(process.env.EMAIL_PORT),
secure: process.env.EMAIL_SECURE === 'true', // true for port 465, false for other ports
auth: {
user: process.env.EMAIL_FROM,
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASSWORD,
},
});
Expand All @@ -29,13 +32,6 @@ export const sendEmail = async (
html: message,
};

// transporter.sendMail(mailOptions, function (error, info) {
// if (error) {
// console.log(error);
// } else {
// console.log('Email sent: ' + info.response);
// }
// });
const res: EmailSendResponse = {
success: false,
info: null,
Expand All @@ -44,7 +40,6 @@ export const sendEmail = async (

if (process.env.NODE_ENV == 'test') {
console.warn('We are in test mode. So we are just mock sending emails');
// we are running tests, so we do not want to send an actual email
const mockInfo: SMTPTransport.SentMessageInfo = {
accepted: [recipients],
rejected: [],
Expand All @@ -66,10 +61,11 @@ export const sendEmail = async (
res.success = true;
res.info = info;
res.error = null;
} catch (error) {
} catch (error: any) {
res.success = false;
res.info = null;
res.error = error;
// Extracted message string prevents runtime serialization bugs in the response container
res.error = error?.message || String(error);
}
return res;
};
3 changes: 2 additions & 1 deletion src/API/src/db/doi/doi.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { UploadedModel } from '../uploaded-model/entities/uploaded-model.entity'

@Module({
imports: [
EmailModule,
HttpModule,
// forwardRef(() => UploadedDatasetModule),
TypeOrmModule.forFeature([
Expand All @@ -37,7 +38,7 @@ import { UploadedModel } from '../uploaded-model/entities/uploaded-model.entity'
providers: [
DoiResolver,
DoiService,
EmailService,
//EmailService,
AuthService,
UserRoleService,
CommunicationLogService,
Expand Down
21 changes: 21 additions & 0 deletions src/API/src/db/email-registry/dto/subscribe-email.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { IsEmail, IsString, IsBoolean, IsNotEmpty } from 'class-validator';

export class SubscribeEmailDto {
@IsString({ message: 'First name must be a text value.' })
@IsNotEmpty({ message: 'First name cannot be left blank.' })
first_name: string;

@IsString({ message: 'Last name must be a text value.' })
@IsNotEmpty({ message: 'Last name cannot be left blank.' })
last_name: string;

@IsEmail({}, { message: 'Please enter a valid email address.' })
@IsNotEmpty({ message: 'Email address is required.' })
email: string;

@IsBoolean({
message: 'Notifications enabled must be a true or false value.',
})
// Note: No @IsNotEmpty needed here, as false is a valid boolean value
notifications_enabled: boolean;
}
24 changes: 24 additions & 0 deletions src/API/src/db/email-registry/dto/subscription-response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Expose } from 'class-transformer';

export class SubscriptionResponseDto {
@Expose()
id: string;

@Expose()
first_name: string;

@Expose()
last_name: string;

@Expose()
email: string;

@Expose()
notifications_enabled: boolean;

@Expose()
account_status: string;

@Expose()
created_at?: Date;
}
27 changes: 27 additions & 0 deletions src/API/src/db/email-registry/dto/unsubscribe-email.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { InputType, Field } from '@nestjs/graphql';
import {
IsUUID,
IsNotEmpty,
IsString,
IsOptional,
MaxLength,
} from 'class-validator';

@InputType()
export class UnsubscribeEmailDto {
@Field() // 2. Add this to register the field in the schema
@IsNotEmpty({ message: 'The account identifier is required to unsubscribe.' })
@IsUUID('4', { message: 'Invalid account identifier format.' })
id: string;

@Field()
@IsNotEmpty({ message: 'The security token is required to unsubscribe.' })
@IsUUID('4', { message: 'Invalid security token format.' })
token: string;

@Field({ nullable: true })
@IsString({ message: 'The reason must be text.' })
@IsOptional()
@MaxLength(500, { message: 'Reason cannot exceed 500 characters.' })
reason?: string;
}
Loading
Loading