Update SHA256 checksums and enhance Dockerfile configurations

- Updated SHA256 checksums for the latest portal backend and frontend tar.gz files to reflect new builds.
- Modified Dockerfile in both BFF and Portal applications to include additional TypeScript configuration files, improving build accuracy and consistency.
- Enhanced the docker-entrypoint.sh script to utilize the updated Prisma configuration for migrations, ensuring compatibility with the latest Prisma CLI changes.
- Improved error handling in Salesforce connection service to validate private key formats more robustly, enhancing security during JWT assertion creation.
This commit is contained in:
barsa 2025-12-12 16:42:54 +09:00
parent 3d56f2895f
commit a176f5d6ce
7 changed files with 28 additions and 11 deletions

View File

@ -40,7 +40,7 @@ RUN --mount=type=cache,id=pnpm-bff,target=/root/.local/share/pnpm/store \
FROM deps AS builder FROM deps AS builder
# Copy source files # Copy source files
COPY tsconfig.json tsconfig.base.json ./ COPY tsconfig.json tsconfig.base.json tsconfig.node.json ./
COPY packages/domain/ ./packages/domain/ COPY packages/domain/ ./packages/domain/
COPY apps/bff/ ./apps/bff/ COPY apps/bff/ ./apps/bff/

View File

@ -94,7 +94,8 @@ if [ "$RUN_MIGRATIONS" = "true" ] && [ -n "$DATABASE_URL" ]; then
# Change to app directory where schema is located # Change to app directory where schema is located
cd /app cd /app
if pnpm exec prisma migrate deploy --schema=prisma/schema.prisma; then # Prisma 7: schema can omit datasource url; Prisma CLI reads it from prisma.config.ts
if pnpm exec prisma migrate deploy --config prisma/prisma.config.ts; then
echo "✅ Migrations complete" echo "✅ Migrations complete"
else else
echo "⚠️ Migration failed - check database connectivity" echo "⚠️ Migration failed - check database connectivity"

View File

@ -4,7 +4,8 @@ import { ConfigService } from "@nestjs/config";
import { getErrorMessage } from "@bff/core/utils/error.util.js"; import { getErrorMessage } from "@bff/core/utils/error.util.js";
import { SalesforceRequestQueueService } from "@bff/core/queue/services/salesforce-request-queue.service.js"; import { SalesforceRequestQueueService } from "@bff/core/queue/services/salesforce-request-queue.service.js";
import jsforce from "jsforce"; import jsforce from "jsforce";
import { SignJWT, importPKCS8 } from "jose"; import { SignJWT } from "jose";
import { createPrivateKey } from "node:crypto";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
@ -132,14 +133,29 @@ export class SalesforceConnection {
const privateKey = await fs.readFile(resolvedKeyPath, "utf8"); const privateKey = await fs.readFile(resolvedKeyPath, "utf8");
// Validate private key format // Validate private key format
if (!privateKey.includes("BEGIN PRIVATE KEY") || privateKey.includes("[PLACEHOLDER")) { const isPkcs8 = privateKey.includes("BEGIN PRIVATE KEY");
const isPkcs1Rsa = privateKey.includes("BEGIN RSA PRIVATE KEY");
if ((!isPkcs8 && !isPkcs1Rsa) || privateKey.includes("[PLACEHOLDER")) {
const devMsg = const devMsg =
"Salesforce private key appears to be invalid or still contains placeholder content. Please replace with your actual private key."; "Salesforce private key appears to be invalid or still contains placeholder content. Expected a PEM key containing either 'BEGIN PRIVATE KEY' (PKCS8) or 'BEGIN RSA PRIVATE KEY' (PKCS1).";
throw new Error(isProd ? "Invalid Salesforce private key" : devMsg);
}
// Create JWT assertion (jose). Use Node crypto to support both PKCS8 and PKCS1 PEMs.
let key: ReturnType<typeof createPrivateKey>;
try {
key = createPrivateKey({ key: privateKey, format: "pem" });
} catch {
const devMsg =
"Salesforce private key could not be parsed. Ensure it is a valid RSA PEM (PKCS8 'BEGIN PRIVATE KEY' or PKCS1 'BEGIN RSA PRIVATE KEY').";
throw new Error(isProd ? "Invalid Salesforce private key" : devMsg);
}
if (key.asymmetricKeyType !== "rsa") {
const devMsg = `Salesforce private key must be RSA. Detected: ${key.asymmetricKeyType ?? "unknown"}`;
throw new Error(isProd ? "Invalid Salesforce private key" : devMsg); throw new Error(isProd ? "Invalid Salesforce private key" : devMsg);
} }
// Create JWT assertion using jose
const key = await importPKCS8(privateKey, "RS256");
const assertion = await new SignJWT({ sub: username }) const assertion = await new SignJWT({ sub: username })
.setProtectedHeader({ alg: "RS256" }) .setProtectedHeader({ alg: "RS256" })
.setIssuer(clientId) .setIssuer(clientId)

View File

@ -40,7 +40,7 @@ RUN --mount=type=cache,id=pnpm-portal,target=/root/.local/share/pnpm/store \
FROM deps AS builder FROM deps AS builder
# Copy source files # Copy source files
COPY tsconfig.json tsconfig.base.json ./ COPY tsconfig.json tsconfig.base.json tsconfig.node.json tsconfig.next.json ./
COPY packages/domain/ ./packages/domain/ COPY packages/domain/ ./packages/domain/
COPY apps/portal/ ./apps/portal/ COPY apps/portal/ ./apps/portal/

View File

@ -1,6 +1,6 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts"; import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@ -1 +1 @@
2b5865668763cce0781a0e6448ce2106f1736c27ade328b2da4920d6946ecce7 /home/barsa/projects/customer_portal/customer-portal/portal-backend.latest.tar.gz 1d758ef9ad60c480fcf34d5c1e6bd8b14215049ea524b61e5de828e74ba3170b /home/barsa/projects/customer_portal/customer-portal/portal-backend.latest.tar.gz

View File

@ -1 +1 @@
e37256f0aa756d9838bcc00d1fd2433db1d199e72b38595d0c986a7d85eb534e /home/barsa/projects/customer_portal/customer-portal/portal-frontend.latest.tar.gz 129107760c197bce5493d6a33837cbc812dd8ba1516ee6c37239431ce973a58c /home/barsa/projects/customer_portal/customer-portal/portal-frontend.latest.tar.gz