diff --git a/.circleci/config.yml b/.circleci/config.yml index 2d3ac26..79d39d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -64,6 +64,7 @@ workflows: branches: only: - develop + - pm-2539 # Production builds are exectuted only on tagged commits to the # master branch. diff --git a/.github/workflows/trivy.yaml b/.github/workflows/trivy.yaml new file mode 100644 index 0000000..7b9fa48 --- /dev/null +++ b/.github/workflows/trivy.yaml @@ -0,0 +1,34 @@ +name: Trivy Scanner + +permissions: + contents: read + security-events: write +on: + push: + branches: + - main + - dev + pull_request: +jobs: + trivy-scan: + name: Use Trivy + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run Trivy scanner in repo mode + uses: aquasecurity/trivy-action@0.33.1 + with: + scan-type: "fs" + ignore-unfixed: true + format: "sarif" + output: "trivy-results.sarif" + severity: "CRITICAL,HIGH,UNKNOWN" + scanners: vuln,secret,misconfig,license + github-pat: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: "trivy-results.sarif" diff --git a/src/auth/guards/roles.guard.ts b/src/auth/guards/roles.guard.ts index cdbd8e8..32a1188 100644 --- a/src/auth/guards/roles.guard.ts +++ b/src/auth/guards/roles.guard.ts @@ -48,7 +48,7 @@ export class RolesGuard implements CanActivate { .map((s: string) => s.trim()) .filter(Boolean); - const scopeOk = fallbackScopes.every((s) => scopes.includes(s)); + const scopeOk = fallbackScopes.some((s) => scopes.includes(s)); if (scopeOk) return true; } diff --git a/src/auth/guards/scopes.guard.ts b/src/auth/guards/scopes.guard.ts index 476151e..2913325 100644 --- a/src/auth/guards/scopes.guard.ts +++ b/src/auth/guards/scopes.guard.ts @@ -32,7 +32,7 @@ export class ScopesGuard implements CanActivate { .map((s: string) => s.trim()) .filter(Boolean); - const ok = required.every((s) => scopes.includes(s)); + const ok = required.some((s) => scopes.includes(s)); if (ok) return true; const fallbackRoles = this.reflector.getAllAndOverride(ROLES_KEY, [ diff --git a/src/common/members-lookup.service.ts b/src/common/members-lookup.service.ts index 66e2748..0432154 100644 --- a/src/common/members-lookup.service.ts +++ b/src/common/members-lookup.service.ts @@ -20,7 +20,14 @@ export class MembersLookupService { return; } // Create a dedicated Prisma client targeting the members DB - this.client = new PrismaClient({ datasources: { db: { url } } }); + this.client = new PrismaClient({ + transactionOptions: { + timeout: process.env.BA_SERVICE_PRISMA_TIMEOUT + ? parseInt(process.env.BA_SERVICE_PRISMA_TIMEOUT, 10) + : 10000, + }, + datasources: { db: { url } } + }); this.initialized = true; } diff --git a/src/common/prisma.service.ts b/src/common/prisma.service.ts index 952711f..2e4f63a 100644 --- a/src/common/prisma.service.ts +++ b/src/common/prisma.service.ts @@ -3,6 +3,16 @@ import { PrismaClient } from "@prisma/client"; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { + constructor() { + super({ + transactionOptions: { + timeout: process.env.BA_SERVICE_PRISMA_TIMEOUT + ? parseInt(process.env.BA_SERVICE_PRISMA_TIMEOUT, 10) + : 10000, + }, + }); + } + async onModuleInit() { await this.$connect(); }