Skip to content

Commit

Permalink
chore: ensure DTO parity between backend and frontend (#289)
Browse files Browse the repository at this point in the history
* chore: ensure DTO parity between backend and frontend
  • Loading branch information
mbystedt authored Dec 24, 2024
1 parent 421a435 commit ae49b49
Show file tree
Hide file tree
Showing 124 changed files with 1,666 additions and 520 deletions.
2 changes: 2 additions & 0 deletions docs/dev_dto_entities.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Data Transfer Objects (DTOs) encapsulate data exchanged with the back-end APIs.

The path `./ui/service` contains a copy of the back-end project, stripped of all files except the DTOs.

There is a script `./scripts/copy-dto.sh` that can be used to copy the dto files from the the back-end to the front-end.

## References

DTOs may only import from the following:
Expand Down
74 changes: 14 additions & 60 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
},
"dependencies": {
"@aws-sdk/client-kinesis": "^3.716.0",
"@mikro-orm/core": "^6.4.1",
"@mikro-orm/mongodb": "^6.4.1",
"@mikro-orm/core": "^6.4.2",
"@mikro-orm/mongodb": "^6.4.2",
"@mikro-orm/nestjs": "^6.0.2",
"@nestjs/axios": "^3.1.3",
"@nestjs/common": "^10.4.15",
Expand Down
21 changes: 21 additions & 0 deletions scripts/copy-dto.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash

# Source and destination directories
SOURCE_DIR="../src"
DEST_DIR="../ui/src/app/service"

# Ensure the destination directory exists
mkdir -p "$DEST_DIR"

# Find .dto.ts files and copy them while preserving directory structure
find "$SOURCE_DIR" -type f -name "*.dto.ts" | while read -r file; do
# Recreate directory structure in the destination
rel_path="${file#$SOURCE_DIR/}"
mkdir -p "$DEST_DIR/$(dirname "$rel_path")"
cp "$file" "$DEST_DIR/$rel_path"
done

# Remove empty folders in the destination directory
find "$DEST_DIR" -type d -empty -delete

echo "All .dto.ts files have been copied to $DEST_DIR"
5 changes: 4 additions & 1 deletion scripts/provision-app-quick-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,23 @@ echo "===> Install"
echo "===> ..."
echo "===> Install - Success!"

echo "===> Patch 1"
# Add install to action
ACTIONS_INSTALL_TOKEN=$(echo $RESPONSE | jq -r '.actions.install.token')
curl -s -X POST $BROKER_URL/v1/intention/action/patch \
-H 'Content-Type: application/json' \
-H 'X-Broker-Token: '"$ACTIONS_INSTALL_TOKEN"'' \
-d '{"cloud":{"target":{"propStrategy":"replace","prop":{"port": "5000", "something": "else"}}}}'


echo ""
echo "===> Patch 2"
ACTIONS_INSTALL_TOKEN=$(echo $RESPONSE | jq -r '.actions.install.token')
curl -s -X POST $BROKER_URL/v1/intention/action/patch \
-H 'Content-Type: application/json' \
-H 'X-Broker-Token: '"$ACTIONS_INSTALL_TOKEN"'' \
-d '{"cloud":{"target":{"propStrategy":"replace","prop":{"java_version": "8"}}}}'

echo ""
echo "===> Intention close"

# Use saved intention token to close intention
Expand Down
4 changes: 3 additions & 1 deletion src/access-logs.middleware.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { AuditService } from './audit/audit.service';

describe('AccessLogsMiddleware', () => {
it('should be defined', () => {
expect(new AccessLogsMiddleware(new AuditService(undefined))).toBeDefined();
expect(
new AccessLogsMiddleware(new AuditService(undefined, undefined)),
).toBeDefined();
});

it('should call recordHttpAccess upon use', () => {
Expand Down
3 changes: 2 additions & 1 deletion src/audit/audit.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';
import { AwsModule } from '../aws/aws.module';
import { UtilModule } from '../util/util.module';
import { AuditService } from './audit.service';
import { AuditStreamerService } from './audit-streamer.service';

Expand All @@ -8,7 +9,7 @@ import { AuditStreamerService } from './audit-streamer.service';
* used to output audit messages.
*/
@Module({
imports: [AwsModule],
imports: [AwsModule, UtilModule],
providers: [AuditService, AuditStreamerService],
exports: [AuditService],
})
Expand Down
12 changes: 9 additions & 3 deletions src/audit/audit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { EdgeEntity } from '../persistence/entity/edge.entity';
import { EdgeInsertDto } from '../persistence/dto/edge.dto';
import { VertexInsertDto } from '../persistence/dto/vertex.dto';
import { VertexEntity } from '../persistence/entity/vertex.entity';
import { UserRolesDto } from '../collection/dto/user-roles.dto';
import { ActionError } from '../intention/action.error';
import { IntentionEntity } from '../intention/entity/intention.entity';
import { ActionEmbeddable } from '../intention/entity/action.embeddable';
import { ArtifactEmbeddable } from '../intention/entity/artifact.embeddable';
import { UserEmbeddable } from '../intention/entity/user.embeddable';
import { APP_ENVIRONMENT } from '../constants';
import { UserUtil } from '../util/user.util';

const hostInfo = {
host: {
Expand All @@ -41,7 +41,10 @@ export class AuditService {
* Constructs the audit service
* @param stream The service used to persist audit logs
*/
constructor(private readonly stream: AuditStreamerService) {
constructor(
private readonly stream: AuditStreamerService,
private readonly userUtil: UserUtil,
) {
if (process.env.BROKER_AUDIT_INDEX_BROKER_AUDIT) {
this.metadataActivity['@metadata'] = {
index: process.env.BROKER_AUDIT_INDEX_BROKER_AUDIT,
Expand Down Expand Up @@ -868,7 +871,10 @@ export class AuditService {
}

return (ecsObj: any) => {
const loggedInUser = new UserRolesDto('', (req.user as any).userinfo);
const loggedInUser = this.userUtil.mapUserToUserRolesDto(
'',
(req.user as any).userinfo,
);
return merge(ecsObj, {
user: this.removeUndefined({
domain: loggedInUser.domain,
Expand Down
10 changes: 5 additions & 5 deletions src/auth/broker-jwt.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { IsNumber, IsString } from 'class-validator';

export class BrokerJwtDto {
@IsNumber()
exp: number;
exp!: number;
@IsNumber()
iat: number;
iat!: number;
@IsNumber()
nbf: number;
nbf!: number;
@IsString()
jti: string;
jti!: string;
@IsString()
sub: string;
sub!: string;
}
4 changes: 2 additions & 2 deletions src/collection/dto/collection-search-query.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export class CollectionSearchQuery {

@IsInt()
@Type(() => Number)
offset: number;
offset!: number;

@IsInt()
@Type(() => Number)
limit: number;
limit!: number;
}
5 changes: 3 additions & 2 deletions src/collection/dto/expiry-query.dto.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Transform, Type } from 'class-transformer';
import { IsBoolean, IsInt, IsOptional, Max } from 'class-validator';
import { DAYS_365_IN_SECONDS } from '../../constants';

export const DAYS_365_IN_SECONDS = 60 * 60 * 24 * 365;

export class ExpiryQuery {
@IsInt()
@Max(DAYS_365_IN_SECONDS)
@Type(() => Number)
expiration: number;
expiration!: number;

@IsBoolean()
@IsOptional()
Expand Down
4 changes: 2 additions & 2 deletions src/collection/dto/package-build-search-query.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export class PackageBuildSearchQuery {

@IsInt()
@Type(() => Number)
offset: number;
offset!: number;

@IsInt()
@Type(() => Number)
limit: number;
limit!: number;
}
29 changes: 1 addition & 28 deletions src/collection/dto/user-roles.dto.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,11 @@
import get from 'lodash.get';
import { UserImportDto } from './user-import.dto';
import {
OAUTH2_CLIENT_MAP_DOMAIN,
OAUTH2_CLIENT_MAP_EMAIL,
OAUTH2_CLIENT_MAP_GUID,
OAUTH2_CLIENT_MAP_NAME,
OAUTH2_CLIENT_MAP_USERNAME,
OAUTH2_CLIENT_MAP_ROLES,
OAUTH2_CLIENT_DOMAIN,
} from '../../constants';
import { UserEntity } from '../../persistence/entity/user.entity';

export class UserRolesDto extends UserImportDto {
alias?: any;
roles!: string[];

constructor(
public readonly vertex: string,
userInfo: any,
collection: UserEntity | undefined = undefined,
) {
constructor(public readonly vertex: string) {
super();
// Map or use static value
this.domain = OAUTH2_CLIENT_MAP_DOMAIN
? get(userInfo, OAUTH2_CLIENT_MAP_DOMAIN)
: OAUTH2_CLIENT_DOMAIN;
this.email = get(userInfo, OAUTH2_CLIENT_MAP_EMAIL);
this.guid = get(userInfo, OAUTH2_CLIENT_MAP_GUID);
this.name = get(userInfo, OAUTH2_CLIENT_MAP_NAME);
this.roles = get(userInfo, OAUTH2_CLIENT_MAP_ROLES, []);
this.username = get(userInfo, OAUTH2_CLIENT_MAP_USERNAME, '').toLowerCase();
if (collection) {
this.alias = collection.alias;
}
}

toUserImportDto(): UserImportDto {
Expand Down
11 changes: 8 additions & 3 deletions src/collection/user-collection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { UserRolesDto } from './dto/user-roles.dto';
import { VertexInsertDto } from '../persistence/dto/vertex.dto';
import { GithubService } from '../github/github.service';
import { AuthService } from '../auth/auth.service';
import { UserUtil } from '../util/user.util';

/**
* Assists with user collection activities
Expand All @@ -21,6 +22,7 @@ export class UserCollectionService {
private readonly authService: AuthService,
private readonly githubService: GithubService,
private readonly graphService: GraphService,
private readonly userUtil: UserUtil,
) {}

async lookupUserByGuid(guid: string): Promise<UserEntity> {
Expand All @@ -45,16 +47,19 @@ export class UserCollectionService {
}

async extractUserFromRequest(req: Request): Promise<UserRolesDto> {
const loggedInUser = new UserRolesDto('', (req.user as any).userinfo);
const loggedInUser = this.userUtil.mapUserToUserRolesDto(
'',
(req.user as any).userinfo,
);
const vertex = await this.upsertUser(req, loggedInUser.toUserImportDto());
const collection = await this.collectionRepository.getCollectionByVertexId(
'user',
vertex.toString(),
);
return new UserRolesDto(
return this.userUtil.mapUserToUserRolesDto(
vertex.toString(),
(req.user as any).userinfo,
collection,
collection?.alias,
);
}

Expand Down
Loading

0 comments on commit ae49b49

Please sign in to comment.