diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index b6a32dd..0e7f346 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -2,8 +2,9 @@ import { Module } from '@nestjs/common'; import { AuthModule } from './auth/auth.module'; import { UserModule } from './user/user.module'; import { GrantModule } from './grant/grant.module'; +import { NotificationsModule } from './notifications/notifications.module'; @Module({ - imports: [AuthModule, UserModule, GrantModule], + imports: [AuthModule, UserModule, GrantModule, NotificationsModule], }) export class AppModule {} \ No newline at end of file diff --git a/backend/src/auth/auth.service.ts b/backend/src/auth/auth.service.ts index 1ea1107..6ec5210 100644 --- a/backend/src/auth/auth.service.ts +++ b/backend/src/auth/auth.service.ts @@ -1,12 +1,8 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, InternalServerErrorException, Logger, UnauthorizedException } from '@nestjs/common'; import AWS from 'aws-sdk'; import { table } from 'console'; import * as crypto from 'crypto'; -AWS.config.update({ - region: process.env.AWS_REGION, -}); - @Injectable() export class AuthService { private readonly logger = new Logger(AuthService.name); @@ -96,6 +92,7 @@ export class AuthService { challenge?: string; requiredAttributes?: string[]; username?: string; + message?: string; }> { const clientId = process.env.COGNITO_CLIENT_ID; const clientSecret = process.env.COGNITO_CLIENT_SECRET; @@ -206,13 +203,36 @@ export class AuthService { user = newUser; } - return { access_token: idToken, user }; + return { access_token: idToken, user, message: "Login Successful!" }; } catch (error: unknown) { - if (error instanceof Error) { + /* Login Failures */ + const cognitoError = error as AwsCognitoError; + + if (cognitoError.code) { + switch (cognitoError.code) { + case 'NotAuthorizedException': + this.logger.warn(`Login failed: ${cognitoError.message}`); + throw new UnauthorizedException('Incorrect username or password.'); + default: + this.logger.error( + `Login failed: ${cognitoError.message}`, + cognitoError.stack, + ); + throw new InternalServerErrorException( + 'An error occurred during login.', + ); + } + } else if (error instanceof Error) { + // Handle non-AWS errors this.logger.error('Login failed', error.stack); - throw new Error(error.message || 'Login failed'); + throw new InternalServerErrorException( + error.message || 'Login failed.', + ); } - throw new Error('An unknown error occurred during login'); + // Handle unknown errors + throw new InternalServerErrorException( + 'An unknown error occurred during login.', + ); } } diff --git a/backend/src/main.ts b/backend/src/main.ts index 6b6438c..b8ddad5 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -5,9 +5,11 @@ import AWS from 'aws-sdk'; /* ! */ async function bootstrap() { - AWS.config.update({ - region: process.env.AWS_REGION - }); + AWS.config.update({ + region: process.env.AWS_REGION, + accessKeyId: process.env.OPEN_HATCH, + secretAccessKey: process.env.CLOSED_HATCH + }); const app = await NestFactory.create(AppModule); app.enableCors(); await app.listen(3001); diff --git a/backend/src/notifications/notifcations.service.ts b/backend/src/notifications/notifcations.service.ts new file mode 100644 index 0000000..bf90de2 --- /dev/null +++ b/backend/src/notifications/notifcations.service.ts @@ -0,0 +1,14 @@ +// src/notifications/notifications.service.ts +import { Injectable } from '@nestjs/common'; +import * as AWS from 'aws-sdk'; + +// idk about name but maybe? +const TABLE_NAME = 'BCANNotifications'; + +@Injectable() +export class NotificationsService { + + // function to make a notification + + // function to find notifications by user id +} \ No newline at end of file diff --git a/backend/src/notifications/notifications.controller.ts b/backend/src/notifications/notifications.controller.ts new file mode 100644 index 0000000..c758aff --- /dev/null +++ b/backend/src/notifications/notifications.controller.ts @@ -0,0 +1,17 @@ +// src/notifications/notifications.controller.ts +import { Controller, Post, Body, Get, Query } from '@nestjs/common'; + +@Controller('notifications') +export class NotificationsController { + // constructor(private readonly notificationsService: NotificationsService) {} + + @Post() + async create(@Body() notification: Partial) { + // return this.notificationsService.create(notification); + } + + @Get() + async findByUser(@Query('userId') userId: string) { + // return this.notificationsService.findByUser(userId); + } +} \ No newline at end of file diff --git a/backend/src/notifications/notifications.module.ts b/backend/src/notifications/notifications.module.ts new file mode 100644 index 0000000..1f3400e --- /dev/null +++ b/backend/src/notifications/notifications.module.ts @@ -0,0 +1,11 @@ +// src/notifications/notifications.module.ts +import { Module } from '@nestjs/common'; +import { NotificationsController } from './notifications.controller'; +import { NotificationsService } from './notifcations.service'; + +@Module({ + providers: [NotificationsService], + controllers: [NotificationsController], + exports: [NotificationsService], +}) +export class NotificationsModule {} \ No newline at end of file diff --git a/backend/src/utils/error.ts b/backend/src/utils/error.ts new file mode 100644 index 0000000..739ad7c --- /dev/null +++ b/backend/src/utils/error.ts @@ -0,0 +1,4 @@ +interface AwsCognitoError extends Error { + code?: string; + [key: string]: any; // Allows for additional props +} \ No newline at end of file diff --git a/frontend/src/Login.tsx b/frontend/src/Login.tsx index 1964e7f..ebd65df 100644 --- a/frontend/src/Login.tsx +++ b/frontend/src/Login.tsx @@ -32,6 +32,7 @@ const Login = observer(() => { if (data.access_token) { setAuthentication(true, data.user, data.access_token); navigate('/dashboard'); + alert(data.message); // Alert wit message from backend indicating success } else { alert('Login failed. Please check your credentials.'); }