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:
parent
3d56f2895f
commit
a176f5d6ce
@ -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/
|
||||||
|
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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/
|
||||||
|
|
||||||
|
|||||||
2
apps/portal/next-env.d.ts
vendored
2
apps/portal/next-env.d.ts
vendored
@ -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.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user