Skip to content

Commit 22e7003

Browse files
committed
prettier and tsx check pre-commit
1 parent cdcd528 commit 22e7003

22 files changed

Lines changed: 328 additions & 242 deletions

.husky/pre-commit

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Run TypeScript checking for backend-services
5+
(cd apps/backend-services && npx tsc --noEmit)
6+
7+
# Run Prettier formatting for backend-services
8+
(cd apps/backend-services && npm run format)
9+
110
# Run linting for backend-services
2-
cd apps/backend-services && npm run lint
11+
(cd apps/backend-services && npm run lint)
12+
13+
# Run TypeScript checking for frontend
14+
(cd apps/frontend && npx tsc --noEmit)
315

4-
# Run linting for frontend (when it has its own lint script)
5-
# cd ../frontend && npm run lint
16+
# Run linting for frontend
17+
(cd apps/frontend && npm run lint)

apps/backend-services/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"scripts": {
99
"build": "nest build",
1010
"build:prod": "NODE_ENV=production nest build",
11-
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
11+
"format": "prettier --write \"src/**/*.ts\"",
1212
"start": "nest start",
1313
"start:dev": "CHOKIDAR_USEPOLLING=true CHOKIDAR_INTERVAL=1000 nest start --watch --preserveWatchOutput",
1414
"start:prod": "node dist/main",
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
import { Module } from '@nestjs/common';
2-
import { ConfigModule } from '@nestjs/config';
3-
import { AuthModule } from './auth/auth.module';
4-
import { UploadModule } from './upload/upload.module';
5-
import { DatabaseModule } from './database/database.module';
6-
import { DocumentModule } from './document/document.module';
7-
import { QueueModule } from './queue/queue.module';
8-
import { OcrModule } from './ocr/ocr.module';
1+
import { Module } from "@nestjs/common";
2+
import { ConfigModule } from "@nestjs/config";
3+
import { AuthModule } from "./auth/auth.module";
4+
import { UploadModule } from "./upload/upload.module";
5+
import { DatabaseModule } from "./database/database.module";
6+
import { DocumentModule } from "./document/document.module";
7+
import { QueueModule } from "./queue/queue.module";
8+
import { OcrModule } from "./ocr/ocr.module";
99

1010
@Module({
1111
imports: [
1212
ConfigModule.forRoot({
1313
isGlobal: true,
14-
envFilePath: '.env',
14+
envFilePath: ".env",
1515
cache: true,
1616
}),
1717
AuthModule,
@@ -23,4 +23,3 @@ import { OcrModule } from './ocr/ocr.module';
2323
],
2424
})
2525
export class AppModule {}
26-

apps/backend-services/src/auth/auth.module.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Module } from '@nestjs/common';
2-
import { ConfigModule } from '@nestjs/config';
3-
import { APP_GUARD } from '@nestjs/core';
4-
import { BCGovAuthGuard } from './bcgov-auth.guard';
5-
import { RolesGuard } from './roles.guard';
1+
import { Module } from "@nestjs/common";
2+
import { ConfigModule } from "@nestjs/config";
3+
import { APP_GUARD } from "@nestjs/core";
4+
import { BCGovAuthGuard } from "./bcgov-auth.guard";
5+
import { RolesGuard } from "./roles.guard";
66

77
@Module({
88
imports: [ConfigModule],

apps/backend-services/src/auth/bcgov-auth.guard.ts

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import {
44
ExecutionContext,
55
UnauthorizedException,
66
ForbiddenException,
7-
} from '@nestjs/common';
8-
import { Request } from 'express';
9-
import { Reflector } from '@nestjs/core';
10-
import { ConfigService } from '@nestjs/config';
11-
import * as jwt from 'jsonwebtoken';
12-
import { JwksClient } from 'jwks-rsa';
13-
import { IS_PUBLIC_KEY } from './public.decorator';
7+
} from "@nestjs/common";
8+
import { Request } from "express";
9+
import { Reflector } from "@nestjs/core";
10+
import { ConfigService } from "@nestjs/config";
11+
import * as jwt from "jsonwebtoken";
12+
import { JwksClient } from "jwks-rsa";
13+
import { IS_PUBLIC_KEY } from "./public.decorator";
1414

1515
interface User {
1616
idir_username?: string;
@@ -20,7 +20,7 @@ interface User {
2020
[key: string]: unknown; // Allow additional properties from JWT
2121
}
2222

23-
declare module 'express' {
23+
declare module "express" {
2424
interface Request {
2525
user?: User;
2626
}
@@ -34,16 +34,20 @@ export class BCGovAuthGuard implements CanActivate {
3434
private configService: ConfigService,
3535
private reflector: Reflector,
3636
) {
37-
const ssoAuthServerUrl = this.configService.get<string>('SSO_AUTH_SERVER_URL');
37+
const ssoAuthServerUrl = this.configService.get<string>(
38+
"SSO_AUTH_SERVER_URL",
39+
);
3840

3941
// If SSO_AUTH_SERVER_URL includes the full OIDC path, extract the base realm URL
4042
let jwksUri: string;
41-
if (ssoAuthServerUrl.includes('/protocol/openid-connect')) {
43+
if (ssoAuthServerUrl.includes("/protocol/openid-connect")) {
4244
// SSO_AUTH_SERVER_URL is the full OIDC endpoint
43-
jwksUri = ssoAuthServerUrl.replace('/protocol/openid-connect', '') + '/protocol/openid-connect/certs';
45+
jwksUri =
46+
ssoAuthServerUrl.replace("/protocol/openid-connect", "") +
47+
"/protocol/openid-connect/certs";
4448
} else {
4549
// SSO_AUTH_SERVER_URL is the base Keycloak URL
46-
const realm = this.configService.get<string>('SSO_REALM');
50+
const realm = this.configService.get<string>("SSO_REALM");
4751
jwksUri = `${ssoAuthServerUrl}/realms/${realm}/protocol/openid-connect/certs`;
4852
}
4953

@@ -66,10 +70,10 @@ export class BCGovAuthGuard implements CanActivate {
6670
}
6771

6872
const request = context.switchToHttp().getRequest<Request>();
69-
const authHeader = request.headers['authorization'];
73+
const authHeader = request.headers["authorization"];
7074

71-
if (!authHeader || !authHeader.startsWith('Bearer ')) {
72-
throw new UnauthorizedException('No Bearer token provided');
75+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
76+
throw new UnauthorizedException("No Bearer token provided");
7377
}
7478

7579
const token = authHeader.substring(7);
@@ -80,7 +84,7 @@ export class BCGovAuthGuard implements CanActivate {
8084
request.user = user;
8185
return true;
8286
} catch {
83-
throw new ForbiddenException('Invalid token');
87+
throw new ForbiddenException("Invalid token");
8488
}
8589
}
8690

@@ -89,34 +93,39 @@ export class BCGovAuthGuard implements CanActivate {
8993
// Decode token header to get key ID
9094
const decoded = jwt.decode(token, { complete: true });
9195
if (!decoded || !decoded.header.kid) {
92-
throw new UnauthorizedException('Invalid token format');
96+
throw new UnauthorizedException("Invalid token format");
9397
}
9498

9599
// Get signing key
96100
const key = await this.jwksClient.getSigningKey(decoded.header.kid);
97101
const signingKey = key.getPublicKey();
98102

99103
// Determine the correct issuer
100-
const ssoAuthServerUrl = this.configService.get<string>('SSO_AUTH_SERVER_URL');
104+
const ssoAuthServerUrl = this.configService.get<string>(
105+
"SSO_AUTH_SERVER_URL",
106+
);
101107
let expectedIssuer: string;
102-
if (ssoAuthServerUrl.includes('/protocol/openid-connect')) {
108+
if (ssoAuthServerUrl.includes("/protocol/openid-connect")) {
103109
// SSO_AUTH_SERVER_URL is the full OIDC endpoint, issuer is the realm URL
104-
expectedIssuer = ssoAuthServerUrl.replace('/protocol/openid-connect', '');
110+
expectedIssuer = ssoAuthServerUrl.replace(
111+
"/protocol/openid-connect",
112+
"",
113+
);
105114
} else {
106115
// SSO_AUTH_SERVER_URL is the base Keycloak URL
107-
const realm = this.configService.get<string>('SSO_REALM');
116+
const realm = this.configService.get<string>("SSO_REALM");
108117
expectedIssuer = `${ssoAuthServerUrl}/realms/${realm}`;
109118
}
110119

111120
// Verify and decode token
112121
const verified = jwt.verify(token, signingKey, {
113-
algorithms: ['RS256'],
122+
algorithms: ["RS256"],
114123
issuer: expectedIssuer,
115124
});
116125

117126
return verified as User;
118127
} catch {
119-
throw new UnauthorizedException('Token validation failed');
128+
throw new UnauthorizedException("Token validation failed");
120129
}
121130
}
122131
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SetMetadata, MethodDecorator, ClassDecorator } from '@nestjs/common';
1+
import { SetMetadata } from "@nestjs/common";
22

3-
export const IS_PUBLIC_KEY = 'isPublic';
4-
export const Public = (): MethodDecorator & ClassDecorator => SetMetadata(IS_PUBLIC_KEY, true);
3+
export const IS_PUBLIC_KEY = "isPublic";
4+
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SetMetadata, MethodDecorator, ClassDecorator } from '@nestjs/common';
1+
import { SetMetadata } from "@nestjs/common";
22

3-
export const ROLES_KEY = 'roles';
4-
export const Roles = (...roles: string[]): MethodDecorator & ClassDecorator => SetMetadata(ROLES_KEY, roles);
3+
export const ROLES_KEY = "roles";
4+
export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);

apps/backend-services/src/auth/roles.guard.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
2-
import { Reflector } from '@nestjs/core';
3-
import { ROLES_KEY } from './roles.decorator';
1+
import {
2+
Injectable,
3+
CanActivate,
4+
ExecutionContext,
5+
ForbiddenException,
6+
} from "@nestjs/common";
7+
import { Reflector } from "@nestjs/core";
8+
import { ROLES_KEY } from "./roles.decorator";
49

510
@Injectable()
611
export class RolesGuard implements CanActivate {
712
constructor(private reflector: Reflector) {}
813

914
canActivate(context: ExecutionContext): boolean {
10-
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
11-
context.getHandler(),
12-
context.getClass(),
13-
]);
15+
const requiredRoles = this.reflector.getAllAndOverride<string[]>(
16+
ROLES_KEY,
17+
[context.getHandler(), context.getClass()],
18+
);
1419

1520
if (!requiredRoles) {
1621
return true;
@@ -20,13 +25,13 @@ export class RolesGuard implements CanActivate {
2025
const user = request.user;
2126

2227
if (!user || !user.roles) {
23-
throw new ForbiddenException('User has no roles');
28+
throw new ForbiddenException("User has no roles");
2429
}
2530

2631
const hasRole = requiredRoles.some((role) => user.roles.includes(role));
2732

2833
if (!hasRole) {
29-
throw new ForbiddenException('Insufficient permissions');
34+
throw new ForbiddenException("Insufficient permissions");
3035
}
3136

3237
return true;
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { Module } from '@nestjs/common';
2-
import { DatabaseService } from './database.service';
1+
import { Module } from "@nestjs/common";
2+
import { DatabaseService } from "./database.service";
33

44
@Module({
55
providers: [DatabaseService],
66
exports: [DatabaseService],
77
})
88
export class DatabaseModule {}
9-

0 commit comments

Comments
 (0)