Feature/4 pilots add (#20)
* changing api url to env variable * updating env variables * updating env variables * updating env variables * updating env variables * updating env variables * updating env variables * feature/4-pilots---add * feature/4-pilots---add * feature/4-pilots---add * feature/4-pilots---add * ad pilot * add pilot * add pilot * add pilot * add pilot * add pilot * adding pilots * add pilot * add pilot * add pilots * add pilot * add pilot * adding pilots * adding pilots * adding pilots * adding pilots * adding pilots * adding pilots * adding pilots * adding pilots * adding pilots * adding pilots * adding pilots * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * Testing menu button * Testing menu button * Testing menu button * Testing menu button * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot * adding pilot --------- Co-authored-by: Noah Spannbauer <nspannbauer@sensonix.com>
This commit was merged in pull request #20.
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
import { Controller, Get, Query } from '@nestjs/common';
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Headers,
|
||||
Query,
|
||||
Res,
|
||||
StreamableFile
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
AppConfigService,
|
||||
MsGraphService,
|
||||
@@ -6,10 +13,17 @@ import {
|
||||
} from '@noahspan/noahspan-modules';
|
||||
import { FeatureFlagValue } from '@azure/app-configuration';
|
||||
import { Public } from '@noahspan/noahspan-modules';
|
||||
import { Person } from '@microsoft/microsoft-graph-types';
|
||||
import { AppService } from './app.service';
|
||||
import { createReadStream } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { arrayBuffer } from 'stream/consumers';
|
||||
import type { Response } from 'express';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(
|
||||
private readonly appService: AppService,
|
||||
private readonly appConfigService: AppConfigService,
|
||||
private readonly msGraphService: MsGraphService
|
||||
) {}
|
||||
@@ -37,21 +51,58 @@ export class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get('profilePhoto')
|
||||
async getProfilePhoto(@Query() query: any): Promise<any> {}
|
||||
@Get('userPhoto')
|
||||
async getProfilePhoto(@Headers() headers: any): Promise<StreamableFile> {
|
||||
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(@Query() query: any) {
|
||||
async getUserProfile(@Headers() headers: any) {
|
||||
try {
|
||||
const username: string = query.username;
|
||||
const graphToken: string = await this.msGraphService.getMsGraphAuth(
|
||||
headers.authorization.replace('Bearer ', ''),
|
||||
['user.read']
|
||||
);
|
||||
const client: MsGraphClient =
|
||||
await this.msGraphService.getMsGraphClient();
|
||||
const userProfile = await client.api(`users/${username}`).get();
|
||||
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<Person[]> {
|
||||
try {
|
||||
const accessToken: string = headers.authorization.replace('Bearer ', '');
|
||||
const personSearchResults: Person[] =
|
||||
await this.appService.getPersonSearchResults(accessToken, search);
|
||||
console.log(personSearchResults);
|
||||
return personSearchResults;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ import {
|
||||
} from '@noahspan/noahspan-modules';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { APP_GUARD } from '@nestjs/core';
|
||||
import { PilotModule } from './pilot/pilot.module';
|
||||
import { APP_FILTER } from '@nestjs/core';
|
||||
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -28,7 +31,8 @@ import { APP_GUARD } from '@nestjs/core';
|
||||
tenantId: process.env.TENANT_ID,
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET
|
||||
})
|
||||
}),
|
||||
PilotModule
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [
|
||||
@@ -36,6 +40,10 @@ import { APP_GUARD } from '@nestjs/core';
|
||||
provide: APP_GUARD,
|
||||
useClass: AuthGuard
|
||||
},
|
||||
{
|
||||
provide: APP_FILTER,
|
||||
useClass: HttpExceptionFilter
|
||||
},
|
||||
AppService
|
||||
]
|
||||
})
|
||||
|
||||
@@ -1,8 +1,44 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { MsGraphService, MsGraphClient } from '@noahspan/noahspan-modules';
|
||||
import { Person } from '@microsoft/microsoft-graph-types';
|
||||
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
constructor(private readonly msGraphService: MsGraphService) {}
|
||||
|
||||
getHello(): string {
|
||||
return 'Hello World!';
|
||||
}
|
||||
|
||||
async getPersonSearchResults(
|
||||
accessToken: string,
|
||||
search: string
|
||||
): Promise<Person[]> {
|
||||
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(`me/people/?$search=${search}`)
|
||||
.get();
|
||||
let personResults: Person[];
|
||||
|
||||
if (results.value) {
|
||||
personResults = results.value.filter((result: Person) => {
|
||||
if (result.userPrincipalName !== null) {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
personResults = [];
|
||||
}
|
||||
|
||||
return personResults;
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
api/src/customError/CustomError.ts
Normal file
9
api/src/customError/CustomError.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class CustomError extends Error {
|
||||
statusCode: number;
|
||||
|
||||
constructor(message, name, statusCode) {
|
||||
super(message);
|
||||
this.name = name;
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
||||
26
api/src/filters/http-exception.filter.ts
Normal file
26
api/src/filters/http-exception.filter.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import {
|
||||
ExceptionFilter,
|
||||
Catch,
|
||||
ArgumentsHost,
|
||||
HttpException
|
||||
} from '@nestjs/common';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
@Catch(HttpException)
|
||||
export class HttpExceptionFilter implements ExceptionFilter {
|
||||
catch(excpetion: HttpException, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse<Response>();
|
||||
const request = ctx.getRequest<Request>();
|
||||
const status = excpetion.getStatus();
|
||||
console.log(excpetion.cause);
|
||||
|
||||
response.status(status).json({
|
||||
name: excpetion.cause,
|
||||
message: excpetion.message,
|
||||
statusCode: status,
|
||||
timestamp: new Date().toISOString(),
|
||||
path: request.url
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,25 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
||||
import { InternalServerErrorException } from '@nestjs/common';
|
||||
|
||||
async function bootstrap() {
|
||||
const httpService = new HttpService();
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
app.useGlobalFilters(new HttpExceptionFilter());
|
||||
httpService.axiosRef.interceptors.response.use(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
console.error('Internal server error exception', error);
|
||||
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
);
|
||||
|
||||
await app.listen(3000);
|
||||
}
|
||||
bootstrap();
|
||||
|
||||
7
api/src/pilot/certificate/certificate.entity.ts
Normal file
7
api/src/pilot/certificate/certificate.entity.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export class Certificate {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
type: string;
|
||||
issueDate: Date;
|
||||
number?: string;
|
||||
}
|
||||
37
api/src/pilot/certificate/certificate.service.ts
Normal file
37
api/src/pilot/certificate/certificate.service.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Repository, InjectRepository } from '@nestjs/azure-database';
|
||||
import { Certificate } from './certificate.entity';
|
||||
|
||||
@Injectable()
|
||||
export class CertificateService {
|
||||
private readonly partitionKey: string = 'certificate';
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Certificate)
|
||||
private readonly certificateRepository: Repository<Certificate>
|
||||
) {}
|
||||
|
||||
async find(rowKey: string): Promise<Certificate> {
|
||||
return await this.certificateRepository.find(this.partitionKey, rowKey);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Certificate[]> {
|
||||
return await this.certificateRepository.findAll();
|
||||
}
|
||||
|
||||
async create(certificate: Certificate): Promise<Certificate> {
|
||||
return await this.certificateRepository.create(certificate);
|
||||
}
|
||||
|
||||
async update(rowKey: string, certificate: Certificate): Promise<Certificate> {
|
||||
return await this.certificateRepository.update(
|
||||
this.partitionKey,
|
||||
rowKey,
|
||||
certificate
|
||||
);
|
||||
}
|
||||
|
||||
async delete(rowKey: string): Promise<void> {
|
||||
await this.certificateRepository.delete(this.partitionKey, rowKey);
|
||||
}
|
||||
}
|
||||
6
api/src/pilot/endorsement/endorsement.entity.ts
Normal file
6
api/src/pilot/endorsement/endorsement.entity.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export class Endorsement {
|
||||
partitionkey: string;
|
||||
rowKey: string;
|
||||
type: string;
|
||||
issueDate: Date;
|
||||
}
|
||||
37
api/src/pilot/endorsement/endosement.service.ts
Normal file
37
api/src/pilot/endorsement/endosement.service.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { InjectRepository, Repository } from '@nestjs/azure-database';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endorsement } from './endorsement.entity';
|
||||
|
||||
@Injectable()
|
||||
export class EndosementService {
|
||||
private readonly partitionKey: string = 'endorsement';
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Endorsement)
|
||||
private readonly endorsementRepository: Repository<Endorsement>
|
||||
) {}
|
||||
|
||||
async find(rowKey: string): Promise<Endorsement> {
|
||||
return await this.endorsementRepository.find(this.partitionKey, rowKey);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Endorsement[]> {
|
||||
return await this.endorsementRepository.findAll();
|
||||
}
|
||||
|
||||
async create(endorsement: Endorsement): Promise<Endorsement> {
|
||||
return await this.endorsementRepository.create(endorsement);
|
||||
}
|
||||
|
||||
async update(rowKey: string, endorsement: Endorsement): Promise<Endorsement> {
|
||||
return await this.endorsementRepository.update(
|
||||
this.partitionKey,
|
||||
rowKey,
|
||||
endorsement
|
||||
);
|
||||
}
|
||||
|
||||
async delete(rowKey: string): Promise<void> {
|
||||
await this.endorsementRepository.delete(this.partitionKey, rowKey);
|
||||
}
|
||||
}
|
||||
10
api/src/pilot/info/pilot-info.dto.ts
Normal file
10
api/src/pilot/info/pilot-info.dto.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export class PilotInfoDto {
|
||||
id: string;
|
||||
name: string;
|
||||
address: string;
|
||||
city: string;
|
||||
state: string;
|
||||
postalCode: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
}
|
||||
12
api/src/pilot/info/pilot-info.entity.ts
Normal file
12
api/src/pilot/info/pilot-info.entity.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export class PilotInfoEntity {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
id: string;
|
||||
name: string;
|
||||
address?: string;
|
||||
city?: string;
|
||||
state?: string;
|
||||
postalCode?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
}
|
||||
83
api/src/pilot/info/pilot-info.service.ts
Normal file
83
api/src/pilot/info/pilot-info.service.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PilotInfoDto } from './pilot-info.dto';
|
||||
import { PilotInfoEntity } from './pilot-info.entity';
|
||||
import { TableClient, TableService } from '@noahspan/noahspan-modules';
|
||||
import { odata, RestError, TableInsertEntityHeaders } from '@azure/data-tables';
|
||||
import { CustomError } from '../../customError/CustomError';
|
||||
|
||||
@Injectable()
|
||||
export class PilotInfoService {
|
||||
private readonly partitionKey: string = 'info';
|
||||
|
||||
constructor(private readonly tableService: TableService) {}
|
||||
|
||||
// async find(rowKey: string): Promise<PilotInfo> {
|
||||
// return await this.pilotInfoRepository.find(this.partitionKey, rowKey);
|
||||
// }
|
||||
|
||||
async findAll(): Promise<PilotInfoEntity[]> {
|
||||
try {
|
||||
const client: TableClient =
|
||||
await this.tableService.getTableClient('Pilots');
|
||||
const entities = await client.listEntities({
|
||||
queryOptions: { filter: odata`PartitionKey eq 'pilot'` }
|
||||
});
|
||||
const pilots: PilotInfoEntity[] = [];
|
||||
|
||||
for await (const entity of entities) {
|
||||
const pilot: PilotInfoEntity = {
|
||||
partitionKey: entity.partitionKey,
|
||||
rowKey: entity.rowKey,
|
||||
id: entity.id.toString(),
|
||||
name: entity.name.toString()
|
||||
};
|
||||
|
||||
pilots.push(pilot);
|
||||
}
|
||||
|
||||
return pilots;
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async create(pilotInfoData: PilotInfoDto): Promise<TableInsertEntityHeaders> {
|
||||
const client: TableClient =
|
||||
await this.tableService.getTableClient('Pilots');
|
||||
const pilotInfo: PilotInfoEntity = new PilotInfoEntity();
|
||||
|
||||
Object.assign(pilotInfo, pilotInfoData);
|
||||
pilotInfo.partitionKey = 'pilot';
|
||||
pilotInfo.rowKey = pilotInfo.id;
|
||||
|
||||
try {
|
||||
return await client.createEntity(pilotInfo);
|
||||
} catch (error) {
|
||||
const restError: RestError = error as RestError;
|
||||
|
||||
throw new CustomError(
|
||||
restError.details['odataError']['message']['value'],
|
||||
restError.details['odataError']['code'],
|
||||
restError.statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// async update(rowKey: string, pilotInfo: PilotInfo): Promise<PilotInfo> {
|
||||
// return await this.pilotInfoRepository.update(
|
||||
// this.partitionKey,
|
||||
// rowKey,
|
||||
// pilotInfo
|
||||
// );
|
||||
// }
|
||||
|
||||
// async delete(rowKey: string): Promise<void> {
|
||||
// await this.pilotInfoRepository.delete(this.partitionKey, rowKey);
|
||||
// }
|
||||
}
|
||||
6
api/src/pilot/medical/medical.entity.ts
Normal file
6
api/src/pilot/medical/medical.entity.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export class Medical {
|
||||
partitionKey: string;
|
||||
rowKey: string;
|
||||
certificateClass: string;
|
||||
certificateExpiration: Date;
|
||||
}
|
||||
33
api/src/pilot/medical/medical.service.ts
Normal file
33
api/src/pilot/medical/medical.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Repository, InjectRepository } from '@nestjs/azure-database';
|
||||
import { Medical } from './medical.entity';
|
||||
|
||||
@Injectable()
|
||||
export class MedicalService {
|
||||
private readonly partitionKey: string = 'medical';
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Medical)
|
||||
private readonly profileRepository: Repository<Medical>
|
||||
) {}
|
||||
|
||||
async find(rowKey: string): Promise<Medical> {
|
||||
return this.profileRepository.find(this.partitionKey, rowKey);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Medical[]> {
|
||||
return this.profileRepository.findAll();
|
||||
}
|
||||
|
||||
async create(profile: Medical): Promise<Medical> {
|
||||
return this.profileRepository.create(profile);
|
||||
}
|
||||
|
||||
async update(rowKey: string, profile: Medical): Promise<Medical> {
|
||||
return this.profileRepository.update(this.partitionKey, rowKey, profile);
|
||||
}
|
||||
|
||||
async delete(rowKey: string) {
|
||||
return this.profileRepository.delete(this.partitionKey, rowKey);
|
||||
}
|
||||
}
|
||||
40
api/src/pilot/pilot.controller.ts
Normal file
40
api/src/pilot/pilot.controller.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Body, Controller, Get, HttpException, Post } from '@nestjs/common';
|
||||
import { PilotInfoService } from './info/pilot-info.service';
|
||||
import { PilotInfoDto } from './info/pilot-info.dto';
|
||||
import { TableInsertEntityHeaders } from '@azure/data-tables';
|
||||
import { CustomError } from '../customError/CustomError';
|
||||
import { PilotInfoEntity } from './info/pilot-info.entity';
|
||||
|
||||
@Controller('pilots')
|
||||
export class PilotController {
|
||||
constructor(private readonly pilotInfoService: PilotInfoService) {}
|
||||
|
||||
@Get()
|
||||
async findAll(): Promise<PilotInfoEntity[]> {
|
||||
try {
|
||||
const pilots: PilotInfoEntity[] = await this.pilotInfoService.findAll();
|
||||
|
||||
return pilots;
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Body() pilotInfoData: PilotInfoDto): Promise<void> {
|
||||
try {
|
||||
const response: TableInsertEntityHeaders =
|
||||
await this.pilotInfoService.create(pilotInfoData);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode, {
|
||||
cause: customError.name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
16
api/src/pilot/pilot.module.ts
Normal file
16
api/src/pilot/pilot.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PilotController } from './pilot.controller';
|
||||
import { TableModule } from '@noahspan/noahspan-modules';
|
||||
import { PilotInfoService } from './info/pilot-info.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TableModule.register({
|
||||
accountName: process.env.AZURE_STORAGE_ACCOUNT_NAME,
|
||||
accountKey: process.env.AZURE_STORAGE_ACCOUNT_KEY
|
||||
})
|
||||
],
|
||||
controllers: [PilotController],
|
||||
providers: [PilotInfoService]
|
||||
})
|
||||
export class PilotModule {}
|
||||
Reference in New Issue
Block a user