From c19b8aa855c5d3bbfad290a594d82715df370766 Mon Sep 17 00:00:00 2001 From: noahspannbauer Date: Wed, 19 Feb 2025 00:16:05 +0000 Subject: [PATCH] Feature/6 pilots delete (#42) * adding pilot delete * adding pilot delete * adding pilot delete --- api/package.json | 9 +- api/src/app.controller.ts | 82 -------- api/src/app.module.ts | 28 +-- api/src/app.service.ts | 49 ----- api/src/log/log.controller.ts | 5 +- api/src/msGraph/ms-graph.interface.ts | 5 - api/src/msGraph/ms-graph.module-definition.ts | 4 - api/src/msGraph/ms-graph.module.ts | 9 - api/src/msGraph/ms-graph.service.ts | 41 ---- api/src/pilot/medical/medical.service.ts | 52 ++--- api/src/pilot/pilot.controller.ts | 1 - app/src/components/logForm/ILogFormState.ts | 4 +- app/src/components/logForm/LogForm.tsx | 16 +- app/src/components/logForm/reducer.tsx | 9 +- app/src/components/logbook/ILogbookState.ts | 3 +- app/src/components/logbook/Logbook.tsx | 38 ++-- app/src/components/logbook/reducer.ts | 9 +- app/src/components/pilotForm/PilotForm.tsx | 2 +- app/src/components/pilots/Pilots.tsx | 52 +++-- .../pilots/PilotsState.interface.ts | 5 +- app/src/components/pilots/reducer.ts | 11 +- app/src/components/siteNav/SiteNav.tsx | 43 +--- app/src/interfaces/Alert.interface.ts | 4 + pnpm-lock.yaml | 189 ++++++++---------- 24 files changed, 220 insertions(+), 450 deletions(-) delete mode 100644 api/src/app.controller.ts delete mode 100644 api/src/app.service.ts delete mode 100644 api/src/msGraph/ms-graph.interface.ts delete mode 100644 api/src/msGraph/ms-graph.module-definition.ts delete mode 100644 api/src/msGraph/ms-graph.module.ts delete mode 100644 api/src/msGraph/ms-graph.service.ts create mode 100644 app/src/interfaces/Alert.interface.ts diff --git a/api/package.json b/api/package.json index fc3e29b..b0d967f 100644 --- a/api/package.json +++ b/api/package.json @@ -19,23 +19,18 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { - "@azure/app-configuration": "^1.8.0", - "@azure/data-tables": "^13.2.2", - "@azure/msal-node": "^2.16.2", "@microsoft/microsoft-graph-client": "^3.0.7", "@nestjs/axios": "^3.0.3", - "@nestjs/azure-database": "^3.0.0", "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.2.2", "@nestjs/core": "^10.0.0", "@nestjs/passport": "^10.0.3", "@nestjs/platform-express": "^10.0.0", "@noahspan/azure-database": "^3.1.2", + "@noahspan/noahspan-modules": "^0.9.2", "@schematics/angular": "^17.3.7", "dotenv": "^16.4.7", - "express-jwt": "^8.5.1", - "passport-azure-ad": "^4.3.5", - "reflect-metadata": "0.1.13", + "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", "uuid": "^10.0.0" }, diff --git a/api/src/app.controller.ts b/api/src/app.controller.ts deleted file mode 100644 index 370506f..0000000 --- a/api/src/app.controller.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - Controller, - Get, - Headers, - Query, - StreamableFile, - UseGuards -} from '@nestjs/common'; -import { Client as MsGraphClient } from '@microsoft/microsoft-graph-client'; -import { MsGraphService } from './msGraph/ms-graph.service' -import { Person } from '@microsoft/microsoft-graph-types'; -import { AppService } from './app.service'; -import { AuthGuard } from '@nestjs/passport'; - -@Controller() -@UseGuards(AuthGuard('azure-ad')) -export class AppController { - constructor( - private readonly appService: AppService, - private readonly msGraphService: MsGraphService - ) {} - - @Get('userPhoto') - async getProfilePhoto(@Headers() headers: any): Promise { - try { - const graphToken: string = await this.msGraphService.getMsGraphAuth( - headers.authorization.replace('Bearer ', ''), - ['user.read'] - ); - const client: MsGraphClient = - await this.msGraphService.getMsGraphClientDelegated(graphToken); - const blob: Blob = await client.api(`me/photos('48x48')/$value`).get(); - const arrayBuffer: ArrayBuffer = await blob.arrayBuffer(); - const buffer: Buffer = Buffer.from(arrayBuffer); - - return new StreamableFile(buffer, { - type: 'application/json', - disposition: `attachment; filename="user_photo.png"` - }); - } catch (error) { - return error; - } - } - - @Get('userProfile') - async getUserProfile(@Headers() headers: any): Promise { - try { - const graphToken: string = await this.msGraphService.getMsGraphAuth( - headers.authorization.replace('Bearer ', ''), - ['user.read'] - ); - const client: MsGraphClient = - await this.msGraphService.getMsGraphClientDelegated(graphToken); - const userProfile = await client.api(`me`).get(); - - return userProfile; - } catch (error) { - return error; - } - } - - @Get('personSearch') - async searchUsers( - @Headers() headers: any, - @Query('search') search: any - ): Promise { - try { - const accessToken: string = headers.authorization.replace('Bearer ', ''); - const personSearchResults: any[] = - await this.appService.getPersonSearchResults(accessToken, search); - - return personSearchResults; - } catch (error) { - return error; - } - } - - @Get('hello') - async getHello(): Promise { - return this.appService.getHello(); - } -} diff --git a/api/src/app.module.ts b/api/src/app.module.ts index 0e19396..39fdd58 100644 --- a/api/src/app.module.ts +++ b/api/src/app.module.ts @@ -1,19 +1,17 @@ import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; -import { AuthModule } from './auth/auth.module'; -import { MsGraphModule } from './msGraph/ms-graph.module'; import { FeatureFlagModule } from './featureFlag/feature-flag.module' import { LogModule } from './log/log.module'; import { PilotModule } from './pilot/pilot.module'; -import { APP_FILTER } from '@nestjs/core'; +import { APP_FILTER, APP_GUARD, Reflector } from '@nestjs/core'; import { HttpExceptionFilter } from './filters/http-exception.filter'; import { ConfigModule, ConfigService } from '@nestjs/config'; +import { AuthGuard, AuthModule, UserModule } from '@noahspan/noahspan-modules'; import configuration from './config/configuration'; @Module({ imports: [ AuthModule.registerAsync({ + inject: [ConfigService], imports: [ConfigModule], useFactory: async (configService: ConfigService) => { return { @@ -22,33 +20,35 @@ import configuration from './config/configuration'; tenantId: configService.get('tenantId') }; }, - inject: [ConfigService] }), ConfigModule.forRoot({ load: [configuration] }), FeatureFlagModule, LogModule, - MsGraphModule.registerAsync({ + PilotModule, + UserModule.registerAsync({ + inject: [ConfigService], imports: [ConfigModule], useFactory: async (configService: ConfigService) => { return { clientId: configService.get('clientId'), clientSecret: configService.get('clientSecret'), tenantId: configService.get('tenantId') - }; - }, - inject: [ConfigService] - }), - PilotModule + } + } + }) ], - controllers: [AppController], providers: [ { provide: APP_FILTER, useClass: HttpExceptionFilter }, - AppService + { + provide: APP_GUARD, + useClass: AuthGuard + }, + Reflector ] }) export class AppModule {} diff --git a/api/src/app.service.ts b/api/src/app.service.ts deleted file mode 100644 index c3435f7..0000000 --- a/api/src/app.service.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Injectable } from '@nestjs/common'; -// import { MsGraphService, MsGraphClient } from '@noahspan/noahspan-modules'; -import { Client as MsGraphClient } from '@microsoft/microsoft-graph-client'; -import { MsGraphService } from './msGraph/ms-graph.service'; - -@Injectable() -export class AppService { - constructor(private readonly msGraphService: MsGraphService) {} - - getHello(): string { - return JSON.stringify(process.env); - } - - async getPersonSearchResults( - accessToken: string, - search: string - ): Promise { - try { - const graphToken: string = await this.msGraphService.getMsGraphAuth( - accessToken, - ['user.read'] - ); - const client: MsGraphClient = - await this.msGraphService.getMsGraphClientDelegated(graphToken); - const results: any = await client - .api('users') - .header('ConsistencyLevel', 'eventual') - .search(`"displayName:${search}"`) - .orderby('displayName') - .select(['displayName', 'userPrincipalName']) - .get(); - let personResults: any[]; - - if (results.value) { - personResults = results.value.filter((result: any) => { - if (result.userPrincipalName !== null) { - return result; - } - }); - } else { - personResults = []; - } - - return personResults; - } catch (error) { - throw new Error(error); - } - } -} diff --git a/api/src/log/log.controller.ts b/api/src/log/log.controller.ts index 7ebd741..55aea0a 100644 --- a/api/src/log/log.controller.ts +++ b/api/src/log/log.controller.ts @@ -13,11 +13,10 @@ import { LogDto } from './log.dto'; import { Log } from './log.entity'; import { LogService } from './log.service'; import { CustomError } from '../error/customError'; -import { AuthGuard } from '@nestjs/passport'; +import { Public } from '@noahspan/noahspan-modules'; @Controller('logs') -@UseGuards(AuthGuard('azure-ad')) export class LogController { constructor(private readonly logService: LogService) {} @@ -35,7 +34,7 @@ export class LogController { } } - // @Public() + @Public() @Get() async findAll(): Promise { try { diff --git a/api/src/msGraph/ms-graph.interface.ts b/api/src/msGraph/ms-graph.interface.ts deleted file mode 100644 index c9d3aca..0000000 --- a/api/src/msGraph/ms-graph.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface MsGraphModuleOptions { - tenantId: string; - clientId: string; - clientSecret: string; -} \ No newline at end of file diff --git a/api/src/msGraph/ms-graph.module-definition.ts b/api/src/msGraph/ms-graph.module-definition.ts deleted file mode 100644 index fc706db..0000000 --- a/api/src/msGraph/ms-graph.module-definition.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ConfigurableModuleBuilder } from '@nestjs/common'; -import { MsGraphModuleOptions } from './ms-graph.interface'; - -export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new ConfigurableModuleBuilder().build() \ No newline at end of file diff --git a/api/src/msGraph/ms-graph.module.ts b/api/src/msGraph/ms-graph.module.ts deleted file mode 100644 index 308abac..0000000 --- a/api/src/msGraph/ms-graph.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Module } from '@nestjs/common'; -import { MsGraphService } from './ms-graph.service'; -import { ConfigurableModuleClass } from './ms-graph.module-definition'; - -@Module({ - providers: [MsGraphService], - exports: [MsGraphService] -}) -export class MsGraphModule extends ConfigurableModuleClass {} \ No newline at end of file diff --git a/api/src/msGraph/ms-graph.service.ts b/api/src/msGraph/ms-graph.service.ts deleted file mode 100644 index a41efa5..0000000 --- a/api/src/msGraph/ms-graph.service.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { MsGraphModuleOptions } from './ms-graph.interface'; -import { Client } from '@microsoft/microsoft-graph-client'; -import { AuthenticationResult, ConfidentialClientApplication, OnBehalfOfRequest } from '@azure/msal-node'; -import { MODULE_OPTIONS_TOKEN } from './ms-graph.module-definition'; - -@Injectable() -export class MsGraphService { - constructor(@Inject(MODULE_OPTIONS_TOKEN) private msGraphModuleOptions: MsGraphModuleOptions) {} - - async getMsGraphAuth(accessToken: string, scopes: string[]): Promise { - try { - const oboRequest: OnBehalfOfRequest = { - oboAssertion: accessToken, - scopes: scopes - } - const cca = new ConfidentialClientApplication({ - auth: { - clientId: this.msGraphModuleOptions.clientId, - clientSecret: this.msGraphModuleOptions.clientSecret, - authority: `https://login.microsoftonline.com/${this.msGraphModuleOptions.tenantId}` - } - }); - const authenticationResult: AuthenticationResult = await cca.acquireTokenOnBehalfOf(oboRequest); - - return authenticationResult.accessToken - } catch (error) { - return error - } - } - - async getMsGraphClientDelegated(accessToken): Promise { - const client = await Client.init({ - authProvider: (done) => { - done(null, accessToken); - } - }); - - return client; - } -} \ No newline at end of file diff --git a/api/src/pilot/medical/medical.service.ts b/api/src/pilot/medical/medical.service.ts index fe36a5b..61de861 100644 --- a/api/src/pilot/medical/medical.service.ts +++ b/api/src/pilot/medical/medical.service.ts @@ -1,33 +1,33 @@ -import { Injectable } from '@nestjs/common'; -import { Repository, InjectRepository } from '@noahspan/azure-database'; -import { Medical } from './medical.entity'; +// import { Injectable } from '@nestjs/common'; +// import { Repository, InjectRepository } from '@noahspan/azure-database'; +// import { Medical } from './medical.entity'; -@Injectable() -export class MedicalService { - private readonly partitionKey: string = 'medical'; +// @Injectable() +// export class MedicalService { +// private readonly partitionKey: string = 'medical'; - constructor( - @InjectRepository(Medical) - private readonly profileRepository: Repository - ) {} +// constructor( +// @InjectRepository(Medical) +// private readonly profileRepository: Repository +// ) {} - async find(rowKey: string): Promise { - return this.profileRepository.find(this.partitionKey, rowKey); - } +// async find(rowKey: string): Promise { +// return this.profileRepository.find(this.partitionKey, rowKey); +// } - async findAll(): Promise { - return this.profileRepository.findAll(); - } +// async findAll(): Promise { +// return this.profileRepository.findAll(); +// } - async create(profile: Medical): Promise { - return this.profileRepository.create(profile); - } +// async create(profile: Medical): Promise { +// return this.profileRepository.create(profile); +// } - async update(rowKey: string, profile: Medical): Promise { - return this.profileRepository.update(this.partitionKey, rowKey, profile); - } +// async update(rowKey: string, profile: Medical): Promise { +// return this.profileRepository.update(this.partitionKey, rowKey, profile); +// } - async delete(rowKey: string) { - return this.profileRepository.delete(this.partitionKey, rowKey); - } -} +// async delete(rowKey: string) { +// return this.profileRepository.delete(this.partitionKey, rowKey); +// } +// } diff --git a/api/src/pilot/pilot.controller.ts b/api/src/pilot/pilot.controller.ts index b766ab1..4b3b432 100644 --- a/api/src/pilot/pilot.controller.ts +++ b/api/src/pilot/pilot.controller.ts @@ -16,7 +16,6 @@ import { CustomError } from '../error/customError'; import { AuthGuard } from '@nestjs/passport' @Controller('pilots') -@UseGuards(AuthGuard('azure-ad')) export class PilotController { constructor(private readonly pilotService: PilotService) {} diff --git a/app/src/components/logForm/ILogFormState.ts b/app/src/components/logForm/ILogFormState.ts index d1bae57..e8a994b 100644 --- a/app/src/components/logForm/ILogFormState.ts +++ b/app/src/components/logForm/ILogFormState.ts @@ -1,5 +1,7 @@ +import { Alert } from "../../interfaces/Alert.interface"; + export interface ILogFormState { - error: string | undefined; + alert: Alert | undefined; isDisabled: boolean; isLoading: boolean; pilotOptions: { label: string; value: string }[]; diff --git a/app/src/components/logForm/LogForm.tsx b/app/src/components/logForm/LogForm.tsx index 8e6c50c..944fac5 100644 --- a/app/src/components/logForm/LogForm.tsx +++ b/app/src/components/logForm/LogForm.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useReducer, useState } from 'react'; +import React, { useEffect, useReducer } from 'react'; import { Accordion, AccordionDetails, @@ -19,7 +19,7 @@ import { import { useForm, Controller, FormProvider } from 'react-hook-form'; import { ILogFormProps } from './ILogFormProps'; import { initialState, reducer } from './reducer'; -import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; +import { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; import { useHttpClient } from '../../hooks/httpClient/UseHttpClient'; import { useAccessToken } from '../../hooks/accessToken/UseAcessToken'; import { useIsAuthenticated } from '@azure/msal-react'; @@ -97,7 +97,7 @@ const LogForm: React.FC = ({ } catch (error) { const axiosError = error as AxiosError; - dispatch({ type: 'SET_ERROR', payload: axiosError.message }); + dispatch({ type: 'SET_ALERT', payload: { severity: 'error', message: axiosError.message }}); } finally { dispatch({ type: 'SET_IS_LOADING', payload: false }); } @@ -127,7 +127,7 @@ const LogForm: React.FC = ({ } catch (error) { const axiosError = error as AxiosError; - dispatch({ type: 'SET_ERROR', payload: axiosError.message }); + dispatch({ type: 'SET_ALERT', payload: { severity: 'error', message: axiosError.message }}); } finally { dispatch({ type: 'SET_IS_LOADING', payload: false }); } @@ -173,16 +173,16 @@ const LogForm: React.FC = ({ - {state.error && ( + {state.alert && ( - dispatch({ type: 'SET_ERROR', payload: undefined }) + dispatch({ type: 'SET_ALERT', payload: undefined }) } - severity="error" + severity={state.alert.severity} sx={{ width: '100%' }} > - {state.error} + {state.alert.message} )} diff --git a/app/src/components/logForm/reducer.tsx b/app/src/components/logForm/reducer.tsx index 85cee0b..d41b4dc 100644 --- a/app/src/components/logForm/reducer.tsx +++ b/app/src/components/logForm/reducer.tsx @@ -1,14 +1,15 @@ +import { Alert } from '../../interfaces/Alert.interface'; import { ILogFormState } from './ILogFormState'; type Action = - | { type: 'SET_ERROR'; payload: string | undefined } + | { type: 'SET_ALERT'; payload: Alert | undefined } | { type: 'SET_IS_DISABLED'; payload: boolean } | { type: 'SET_IS_LOADING'; payload: boolean } | { type: 'SET_PILOT_OPTIONS'; payload: { label: string; value: string }[] } | { type: 'SET_SELECTED_ENTRY_PILOT_NAME'; payload: string }; export const initialState: ILogFormState = { - error: undefined, + alert: undefined, isDisabled: false, isLoading: true, pilotOptions: [], @@ -20,10 +21,10 @@ export const reducer = ( action: Action ): ILogFormState => { switch (action.type) { - case 'SET_ERROR': { + case 'SET_ALERT': { return { ...state, - error: action.payload + alert: action.payload }; } case 'SET_IS_DISABLED': { diff --git a/app/src/components/logbook/ILogbookState.ts b/app/src/components/logbook/ILogbookState.ts index f28b73d..31844b2 100644 --- a/app/src/components/logbook/ILogbookState.ts +++ b/app/src/components/logbook/ILogbookState.ts @@ -1,10 +1,11 @@ import { FormMode } from '../../enums/formMode'; +import { Alert } from '../../interfaces/Alert.interface'; import { ILogbookEntry } from './ILogbookEntry'; export interface ILogbookState { + alert: Alert | undefined; entries: ILogbookEntry[]; formMode: FormMode; - error: string | undefined; isConfirmDialogLoading: boolean; isConfirmDialogOpen: boolean; isFormOpen: boolean; diff --git a/app/src/components/logbook/Logbook.tsx b/app/src/components/logbook/Logbook.tsx index 5a18457..e8a33b7 100644 --- a/app/src/components/logbook/Logbook.tsx +++ b/app/src/components/logbook/Logbook.tsx @@ -31,19 +31,23 @@ const Logbook: React.FC = () => { try { dispatch({ type: 'SET_IS_LOADING', payload: true }); - const token = await getAccessToken(); - const config = isAuthenticated - ? { headers: { Authorization: `${token}` } } - : {}; - const response: AxiosResponse = await httpClient.get(`api/logs`, config); + const response: AxiosResponse = await httpClient.get(`api/logs`); console.log(response) - dispatch({ type: 'SET_ENTRIES', payload: response.data }); + if (response.data.length > 0) { + dispatch({ type: 'SET_ENTRIES', payload: response.data }); + + if (state.alert) { + dispatch({ type: 'SET_ALERT', payload: undefined}) + } + } else { + dispatch({ type: 'SET_ALERT', payload: { severity: 'info', message: 'No logbook entries found.'}}) + } } catch (error) { const axiosError = error as AxiosError; dispatch({ - type: 'SET_ERROR', - payload: `Loading of logbook entries failed with the following message: ${axiosError.message}` + type: 'SET_ALERT', + payload: { severity: 'error', message: `Loading of logbook entries failed with the following message: ${axiosError.message}`} }); } finally { dispatch({ type: 'SET_IS_LOADING', payload: false }); @@ -106,8 +110,8 @@ const Logbook: React.FC = () => { const axiosError = error as AxiosError; dispatch({ - type: 'SET_ERROR', - payload: `Loading of logbook entries failed with the following message: ${axiosError.message}` + type: 'SET_ALERT', + payload: { severity: 'error', message: `Loading of logbook entries failed with the following message: ${axiosError.message}`} }); } finally { dispatch({ type: 'SET_IS_CONFIRMATION_DIALOG_LOADING', payload: false }); @@ -363,10 +367,10 @@ const Logbook: React.FC = () => { ]; useEffect(() => { - if (isAuthenticated && !state.isFormOpen) { + if (!state.isFormOpen) { getLogbookEntries(); } - }, [isAuthenticated, state.isFormOpen]); + }, [state.isFormOpen]); return ( @@ -386,16 +390,16 @@ const Logbook: React.FC = () => { } - {!state.isLoading && state.error && ( + {!state.isLoading && state.alert && ( - dispatch({ type: 'SET_ERROR', payload: undefined }) + dispatch({ type: 'SET_ALERT', payload: undefined }) } - severity="error" + severity={state.alert.severity} sx={{ width: '100%' }} > - {state.error} + {state.alert.message} )} @@ -406,7 +410,7 @@ const Logbook: React.FC = () => { )} )} - {state.isLoading && !state.error && ( + {state.isLoading && !state.alert && ( <> diff --git a/app/src/components/logbook/reducer.ts b/app/src/components/logbook/reducer.ts index d676447..caff5ca 100644 --- a/app/src/components/logbook/reducer.ts +++ b/app/src/components/logbook/reducer.ts @@ -1,4 +1,5 @@ import { FormMode } from '../../enums/formMode'; +import { Alert } from '../../interfaces/Alert.interface'; import { ILogbookEntry } from './ILogbookEntry'; import { ILogbookState } from './ILogbookState'; @@ -11,7 +12,7 @@ type Action = }; } | { type: 'SET_ENTRIES'; payload: ILogbookEntry[] } - | { type: 'SET_ERROR'; payload: string | undefined } + | { type: 'SET_ALERT'; payload: Alert | undefined } | { type: 'SET_FORM_MODE'; payload: FormMode } | { type: 'SET_IS_CONFIRMATION_DIALOG_LOADING'; payload: boolean } | { type: 'SET_IS_LOADING'; payload: boolean } @@ -25,8 +26,8 @@ type Action = }; export const initialState: ILogbookState = { + alert: undefined, entries: [], - error: undefined, formMode: FormMode.CANCEL, isConfirmDialogLoading: false, isConfirmDialogOpen: false, @@ -53,10 +54,10 @@ export const reducer = ( entries: action.payload }; } - case 'SET_ERROR': { + case 'SET_ALERT': { return { ...state, - error: action.payload + alert: action.payload }; } case 'SET_FORM_MODE': { diff --git a/app/src/components/pilotForm/PilotForm.tsx b/app/src/components/pilotForm/PilotForm.tsx index cc44b7d..25f1c7a 100644 --- a/app/src/components/pilotForm/PilotForm.tsx +++ b/app/src/components/pilotForm/PilotForm.tsx @@ -66,7 +66,7 @@ const PilotForm: React.FC = ({ const searchString: string = value; const accessToken: string = await getAccessToken(); const response: AxiosResponse = await httpClient.get( - `api/personSearch?search=${searchString}`, + `api/user/search?search=${searchString}`, { headers: { Authorization: accessToken diff --git a/app/src/components/pilots/Pilots.tsx b/app/src/components/pilots/Pilots.tsx index 73635e6..0b27ad7 100644 --- a/app/src/components/pilots/Pilots.tsx +++ b/app/src/components/pilots/Pilots.tsx @@ -1,6 +1,7 @@ import { useEffect, useReducer, useState } from 'react'; import PilotForm from '../pilotForm/PilotForm'; import { + Alert, Box, Button, ColumnDef, @@ -34,7 +35,7 @@ const Pilots: React.FC = () => { const isAuthenticated = useIsAuthenticated(); const { getAccessToken } = useAccessToken(); - const getPilots = async (): Promise => { + const getPilots = async () => { try { const config = isAuthenticated ? { headers: { Authorization: await getAccessToken() } } @@ -43,11 +44,25 @@ const Pilots: React.FC = () => { `api/pilots`, config ); - const pilots: Pilot[] = response.data; + console.log(response.data) + if (response.data.length > 0) { + dispatch({ type: 'SET_PILOTS', payload: response.data }); - return pilots; + if (state.alert) { + dispatch({ type: 'SET_ALERT', payload: undefined }) + } + } else { + dispatch({ type: 'SET_ALERT', payload: { severity: 'info', message: 'No pilots found.' }}) + } } catch (error) { - throw new Error('broken'); + const axiosError = error as AxiosError; + + dispatch({ + type: 'SET_ALERT', + payload: { severity: 'error', message: `Loading of pilots failed with the following message: ${axiosError.message}`} + }) + } finally { + dispatch({ type: 'SET_IS_LOADING', payload: false }) } }; @@ -107,8 +122,8 @@ const Pilots: React.FC = () => { const axiosError = error as AxiosError; dispatch({ - type: 'SET_ERROR', - payload: `Loading of logbook entries failed with the following message: ${axiosError.message}` + type: 'SET_ALERT', + payload: { severity: 'error', message: `Loading of logbook entries failed with the following message: ${axiosError.message}`} }); } finally { dispatch({ type: 'SET_IS_CONFIRMATION_DIALOG_LOADING', payload: false }); @@ -140,18 +155,8 @@ const Pilots: React.FC = () => { ]; useEffect(() => { - const loadPilots = async () => { - try { - const pilots = await getPilots(); - - dispatch({ type: 'SET_PILOTS', payload: pilots }) - } catch (error) { - console.log(error); - } - }; - if (isAuthenticated && !state.isFormOpen) { - loadPilots(); + getPilots(); } }, [isAuthenticated, state.isFormOpen]); @@ -173,6 +178,19 @@ const Pilots: React.FC = () => { } + {!state.isLoading && state.alert && ( + + + dispatch({ type: 'SET_ALERT', payload: undefined }) + } + severity={state.alert.severity} + sx={{ width: '100%' }} + > + {state.alert.message} + + + )} {state.pilots.length > 0 && } diff --git a/app/src/components/pilots/PilotsState.interface.ts b/app/src/components/pilots/PilotsState.interface.ts index 21b35bd..3605f6a 100644 --- a/app/src/components/pilots/PilotsState.interface.ts +++ b/app/src/components/pilots/PilotsState.interface.ts @@ -1,13 +1,14 @@ import { FormMode } from "../../enums/formMode"; +import { Alert } from "../../interfaces/Alert.interface"; import { Pilot } from "./Pilot.interface"; export interface PilotsState { - pilots: Pilot[]; - error: string | undefined; + alert: Alert | undefined; isConfirmDialogLoading: boolean; isConfirmDialogOpen: boolean; isFormOpen: boolean; isLoading: boolean; formMode: FormMode; + pilots: Pilot[]; selectedPilotId: string | undefined; } \ No newline at end of file diff --git a/app/src/components/pilots/reducer.ts b/app/src/components/pilots/reducer.ts index 8d2ab2c..6dfe100 100644 --- a/app/src/components/pilots/reducer.ts +++ b/app/src/components/pilots/reducer.ts @@ -1,4 +1,5 @@ import { FormMode } from "../../enums/formMode"; +import { Alert } from "../../interfaces/Alert.interface"; import { Pilot } from "./Pilot.interface"; import { PilotsState } from './PilotsState.interface' @@ -11,7 +12,7 @@ type Action = } } | { type: 'SET_PILOTS'; payload: Pilot[] } - | { type: 'SET_ERROR'; payload: string | undefined } + | { type: 'SET_ALERT'; payload: Alert | undefined } | { type: 'SET_FORM_MODE'; payload: FormMode } | { type: 'SET_IS_CONFIRMATION_DIALOG_LOADING'; payload: boolean } | { type: 'SET_IS_LOADING'; payload: boolean } @@ -25,13 +26,13 @@ type Action = } export const initialState: PilotsState = { - pilots: [], - error: undefined, + alert: undefined, formMode: FormMode.CANCEL, isConfirmDialogLoading: false, isConfirmDialogOpen: false, isFormOpen: false, isLoading: false, + pilots: [], selectedPilotId: undefined } @@ -53,10 +54,10 @@ export const reducer = ( pilots: action.payload } } - case 'SET_ERROR': { + case 'SET_ALERT': { return { ...state, - error: action.payload + alert: action.payload } } case 'SET_FORM_MODE': { diff --git a/app/src/components/siteNav/SiteNav.tsx b/app/src/components/siteNav/SiteNav.tsx index 448db82..d112758 100644 --- a/app/src/components/siteNav/SiteNav.tsx +++ b/app/src/components/siteNav/SiteNav.tsx @@ -53,7 +53,7 @@ const SiteNav: React.FC = () => { }; const getUserProfile = async (accessToken: string): Promise => { try { - const response: AxiosResponse = await httpClient.get(`api/userProfile`, { + const response: AxiosResponse = await httpClient.get(`api/user/profile`, { headers: { Authorization: accessToken } @@ -67,7 +67,7 @@ const SiteNav: React.FC = () => { }; const getUserPhoto = async (accessToken: string): Promise => { try { - const response: AxiosResponse = await httpClient.get(`api/userPhoto`, { + const response: AxiosResponse = await httpClient.get(`api/user/photo`, { headers: { Authorization: accessToken }, @@ -98,45 +98,6 @@ const SiteNav: React.FC = () => { ); }; - // useEffect(() => { - // const callback = instance.addEventCallback( - // async (message: EventMessage) => { - // if (message.eventType === EventType.LOGIN_SUCCESS) { - // try { - // setLoading(true); - - // const eventPayload: EventPayloadExtended = - // message.payload as EventPayloadExtended; - // const userProfile: User = await getUserProfile( - // eventPayload.accessToken - // ); - // const userPhoto = await getUserPhoto(eventPayload.accessToken); - - // appContext.dispatch({ - // type: 'SET_USER_PROFILE', - // payload: userProfile - // }); - // } catch (error) { - // console.log(error); - // } finally { - // setLoading(false); - // } - // } - // } - // ); - - // instance.handleRedirectPromise().then((response) => { - // console.log(response) - // }) - - // return () => { - // if (callback) { - // instance.removeEventCallback(callback); - // appContext.dispatch({ type: 'SET_USER_PROFILE', payload: {} }); - // } - // }; - // }, []); - useEffect(() => { const setUserProfile = async () => { try { diff --git a/app/src/interfaces/Alert.interface.ts b/app/src/interfaces/Alert.interface.ts new file mode 100644 index 0000000..5bbdf16 --- /dev/null +++ b/app/src/interfaces/Alert.interface.ts @@ -0,0 +1,4 @@ +export interface Alert { + severity: 'success' | 'error' | 'info' | 'warning'; + message: string; +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d1c6aa3..eed4af1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,57 +48,42 @@ importers: api: dependencies: - '@azure/app-configuration': - specifier: ^1.8.0 - version: 1.8.0 - '@azure/data-tables': - specifier: ^13.2.2 - version: 13.3.0 - '@azure/msal-node': - specifier: ^2.16.2 - version: 2.16.2 '@microsoft/microsoft-graph-client': specifier: ^3.0.7 version: 3.0.7(@azure/identity@4.6.0) '@nestjs/axios': specifier: ^3.0.3 - version: 3.1.3(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(axios@1.7.9)(rxjs@7.8.1) - '@nestjs/azure-database': - specifier: ^3.0.0 - version: 3.0.0(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15) + version: 3.1.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.9)(rxjs@7.8.1) '@nestjs/common': specifier: ^10.0.0 - version: 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) + version: 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/config': specifier: ^3.2.2 - version: 3.3.0(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(rxjs@7.8.1) + version: 3.3.0(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(rxjs@7.8.1) '@nestjs/core': specifier: ^10.0.0 - version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1) + version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/passport': specifier: ^10.0.3 - version: 10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(passport@0.7.0) + version: 10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(passport@0.7.0) '@nestjs/platform-express': specifier: ^10.0.0 - version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15) + version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15) '@noahspan/azure-database': specifier: ^3.1.2 - version: 3.1.2(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15) + version: 3.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15) + '@noahspan/noahspan-modules': + specifier: ^0.9.2 + version: 0.9.2 '@schematics/angular': specifier: ^17.3.7 version: 17.3.11(chokidar@3.6.0) dotenv: specifier: ^16.4.7 version: 16.4.7 - express-jwt: - specifier: ^8.5.1 - version: 8.5.1 - passport-azure-ad: - specifier: ^4.3.5 - version: 4.3.5 reflect-metadata: - specifier: 0.1.13 - version: 0.1.13 + specifier: ^0.2.2 + version: 0.2.2 rxjs: specifier: ^7.8.1 version: 7.8.1 @@ -117,7 +102,7 @@ importers: version: 10.2.3(chokidar@3.6.0)(typescript@5.7.3) '@nestjs/testing': specifier: ^10.0.0 - version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15) + version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15) '@types/express': specifier: ^4.17.17 version: 4.17.21 @@ -291,6 +276,7 @@ packages: '@azure/msal-browser@4.0.1': resolution: {integrity: sha512-jqiwVJPArnEOUhmc+dvo481OP8b2PMcsu3EtGtxt7sxmKgFtdQyGDCndj+2me62JVG/HEgArEgKyMA7L0aNhdA==} engines: {node: '>=0.8.0'} + deprecated: A bug was identified in this release that coule be production impacting. Use 4.0.2 or later. '@azure/msal-browser@4.0.2': resolution: {integrity: sha512-bq6PasUpJgBSOSMeSlh8gXh4LZGgAaPoJFNcu5u0zxwueh+I8NpMb9oxlCfS/8CJHyXUhTUAMLSnvThemNdyQw==} @@ -1263,6 +1249,7 @@ packages: '@mui/base@5.0.0-beta.69': resolution: {integrity: sha512-r2YyGUXpZxj8rLAlbjp1x2BnMERTZ/dMqd9cClKj2OJ7ALAuiv/9X5E9eHfRc9o/dGRuLSMq/WTjREktJVjxVA==} engines: {node: '>=14.0.0'} + deprecated: This package has been replaced by @base-ui-components/react peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -1449,12 +1436,6 @@ packages: axios: ^1.3.1 rxjs: ^6.0.0 || ^7.0.0 - '@nestjs/azure-database@3.0.0': - resolution: {integrity: sha512-w/yGifKJNYtgrB11WWB6LD4aSflZuVhqDhyIffew3pXHffhqJcIw+7AiFzZr1gVV2cGLJy2J0QSNvHM1fLxS9Q==} - peerDependencies: - '@nestjs/common': ^9.0.0 || ^10.0.0 - '@nestjs/core': ^9.0.0 || ^10.0.0 - '@nestjs/cli@10.4.9': resolution: {integrity: sha512-s8qYd97bggqeK7Op3iD49X2MpFtW4LVNLAwXFkfbRxKME6IYT7X0muNTJ2+QfI8hpbNx9isWkrLWIp+g5FOhiA==} engines: {node: '>= 16.14'} @@ -1550,6 +1531,9 @@ packages: '@noahspan/noahspan-modules@0.5.9': resolution: {integrity: sha512-kkL9P/TNxuPp5T/gd6gTLAmAGi8SJD4MjTWtsrMvw4WWF69x69m2Nr2G6zCv9WLtFrm4NaJhF8I1MVVuNOCinw==} + '@noahspan/noahspan-modules@0.9.2': + resolution: {integrity: sha512-TU/qO7nNVo+3Ceap7dISUmDtAd/rnZnroCjCK82Zhk6rgj8tkazRhksdUemcdPyienQLJKBaUh6H/sZQNetC1Q==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -3456,8 +3440,8 @@ packages: debug: optional: true - for-each@0.3.4: - resolution: {integrity: sha512-kKaIINnFpzW6ffJNDjjyjrk21BkDx38c0xa/klsT8VzLCaMEefv4ZTacrcVR4DmgTeBra++jMDAfS/tS799YDw==} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} foreground-child@3.3.0: @@ -4635,8 +4619,8 @@ packages: popmotion@11.0.3: resolution: {integrity: sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==} - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} postcss-loader@7.3.4: @@ -4864,9 +4848,6 @@ packages: resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==} engines: {node: '>= 4'} - reflect-metadata@0.1.13: - resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} - reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -5042,8 +5023,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.7.0: - resolution: {integrity: sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==} + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} engines: {node: '>=10'} hasBin: true @@ -6972,21 +6953,12 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@nestjs/axios@3.1.3(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(axios@1.7.9)(rxjs@7.8.1)': + '@nestjs/axios@3.1.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.9)(rxjs@7.8.1)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) axios: 1.7.9 rxjs: 7.8.1 - '@nestjs/azure-database@3.0.0(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15)': - dependencies: - '@azure/cosmos': 4.2.0 - '@azure/data-tables': 13.3.0 - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1) - transitivePeerDependencies: - - supports-color - '@nestjs/cli@10.4.9': dependencies: '@angular-devkit/core': 17.3.11(chokidar@3.6.0) @@ -7013,14 +6985,6 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1)': - dependencies: - iterare: 1.2.1 - reflect-metadata: 0.1.13 - rxjs: 7.8.1 - tslib: 2.8.1 - uid: 2.0.2 - '@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)': dependencies: iterare: 1.2.1 @@ -7029,33 +6993,17 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 - '@nestjs/config@3.3.0(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(rxjs@7.8.1)': + '@nestjs/config@3.3.0(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(rxjs@7.8.1)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) dotenv: 16.4.5 dotenv-expand: 10.0.0 lodash: 4.17.21 rxjs: 7.8.1 - '@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1)': + '@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nuxtjs/opencollective': 0.3.2 - fast-safe-stringify: 2.1.1 - iterare: 1.2.1 - path-to-regexp: 3.3.0 - reflect-metadata: 0.1.13 - rxjs: 7.8.1 - tslib: 2.8.1 - uid: 2.0.2 - optionalDependencies: - '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15) - transitivePeerDependencies: - - encoding - - '@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)': - dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -7065,19 +7013,19 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15) + '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15) transitivePeerDependencies: - encoding - '@nestjs/passport@10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(passport@0.7.0)': + '@nestjs/passport@10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(passport@0.7.0)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) passport: 0.7.0 - '@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15)': + '@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) body-parser: 1.20.3 cors: 2.8.5 express: 4.21.2 @@ -7108,20 +7056,20 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)': + '@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15) + '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15) - '@noahspan/azure-database@3.1.2(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15)': + '@noahspan/azure-database@3.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)': dependencies: '@azure/cosmos': 4.2.0 '@azure/data-tables': 13.3.0 - '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@noahspan/noahspan-modules': 0.5.9 transitivePeerDependencies: - '@azure/msal-browser' @@ -7194,9 +7142,9 @@ snapshots: '@dapr/dapr': 3.4.1 '@microsoft/microsoft-graph-client': 3.0.7(@azure/identity@4.6.0) '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/passport': 10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(passport@0.7.0) - '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1))(@nestjs/core@10.4.15) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/passport': 10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(passport@0.7.0) + '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15) axios: 1.7.9 express-jwt: 8.5.1 jwks-rsa: 3.1.0 @@ -7217,6 +7165,33 @@ snapshots: - stream-browserify - supports-color + '@noahspan/noahspan-modules@0.9.2': + dependencies: + '@azure/identity': 4.6.0 + '@azure/msal-node': 2.16.2 + '@microsoft/microsoft-graph-client': 3.0.7(@azure/identity@4.6.0) + '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/passport': 10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(passport@0.7.0) + '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15) + axios: 1.7.9 + passport: 0.7.0 + passport-azure-ad: 4.3.5 + passport-jwt: 4.0.1 + reflect-metadata: 0.2.2 + rxjs: 7.8.1 + transitivePeerDependencies: + - '@azure/msal-browser' + - '@nestjs/microservices' + - '@nestjs/websockets' + - buffer + - class-transformer + - class-validator + - debug + - encoding + - stream-browserify + - supports-color + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7870,7 +7845,7 @@ snapshots: jsdoc-type-pratt-parser: 4.1.0 process: 0.11.10 recast: 0.23.9 - semver: 7.7.0 + semver: 7.7.1 util: 0.12.5 ws: 8.18.0 optionalDependencies: @@ -8488,7 +8463,7 @@ snapshots: available-typed-arrays@1.0.7: dependencies: - possible-typed-array-names: 1.0.0 + possible-typed-array-names: 1.1.0 axios@1.7.9: dependencies: @@ -9424,7 +9399,7 @@ snapshots: follow-redirects@1.15.9: {} - for-each@0.3.4: + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -10280,7 +10255,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.6.3 + semver: 7.7.1 jwa@1.4.1: dependencies: @@ -10475,7 +10450,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.6.3 + semver: 7.7.1 make-error@1.3.6: {} @@ -10833,7 +10808,7 @@ snapshots: style-value-types: 5.0.0 tslib: 2.8.1 - possible-typed-array-names@1.0.0: {} + possible-typed-array-names@1.1.0: {} postcss-loader@7.3.4(postcss@8.5.1)(typescript@5.7.3)(webpack@5.97.1(esbuild@0.18.20)): dependencies: @@ -11067,8 +11042,6 @@ snapshots: tiny-invariant: 1.3.3 tslib: 2.8.1 - reflect-metadata@0.1.13: {} - reflect-metadata@0.2.2: {} regenerator-runtime@0.14.1: {} @@ -11231,7 +11204,7 @@ snapshots: semver@7.6.3: {} - semver@7.7.0: {} + semver@7.7.1: {} send@0.19.0: dependencies: @@ -11805,7 +11778,7 @@ snapshots: available-typed-arrays: 1.0.7 call-bind: 1.0.8 call-bound: 1.0.3 - for-each: 0.3.4 + for-each: 0.3.5 gopd: 1.2.0 has-tostringtag: 1.0.2