Fix Mixed Content on file uploads: presigned URLs now use public domain
The backend was generating presigned S3 URLs pointing to the internal MinIO endpoint (http://minio:9000), which browsers block on HTTPS pages. - Add a second S3 client in upload.service.ts configured with FRONTEND_URL for generating browser-facing presigned URLs (both upload and download) - Add nginx proxy location for /indeedhub-private/ and /indeedhub-public/ paths that forwards to MinIO without rewriting (preserves S3v4 signatures) - Keep internal S3 client for server-side operations (copy, delete, etc.) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -21,14 +21,20 @@ import { getPrivateS3Url } from 'src/common/helper';
|
||||
@Injectable()
|
||||
export class UploadService {
|
||||
private s3: S3Client;
|
||||
|
||||
// Separate client for generating presigned URLs that browsers can reach.
|
||||
// Uses the public-facing FRONTEND_URL instead of the internal MinIO endpoint
|
||||
// so presigned URLs are https://domain/bucket/key instead of http://minio:9000/...
|
||||
private presignS3: S3Client;
|
||||
|
||||
constructor() {
|
||||
const s3Config: any = {
|
||||
region: process.env.AWS_REGION || 'us-east-1',
|
||||
credentials: {
|
||||
accessKeyId: process.env.AWS_ACCESS_KEY,
|
||||
secretAccessKey: process.env.AWS_SECRET_KEY,
|
||||
},
|
||||
const credentials = {
|
||||
accessKeyId: process.env.AWS_ACCESS_KEY,
|
||||
secretAccessKey: process.env.AWS_SECRET_KEY,
|
||||
};
|
||||
const region = process.env.AWS_REGION || 'us-east-1';
|
||||
|
||||
const s3Config: any = { region, credentials };
|
||||
|
||||
// MinIO compatibility: if S3_ENDPOINT is set, override the endpoint
|
||||
// and force path-style access (MinIO requires this)
|
||||
@@ -38,6 +44,21 @@ export class UploadService {
|
||||
}
|
||||
|
||||
this.s3 = new S3Client(s3Config);
|
||||
|
||||
// For presigned URLs served to the browser, use the public domain
|
||||
// so URLs are reachable over HTTPS (avoids Mixed Content errors).
|
||||
// Nginx proxies /indeedhub-*/ paths to MinIO internally.
|
||||
const presignEndpoint = process.env.FRONTEND_URL;
|
||||
if (presignEndpoint && process.env.S3_ENDPOINT) {
|
||||
this.presignS3 = new S3Client({
|
||||
region,
|
||||
credentials,
|
||||
endpoint: presignEndpoint,
|
||||
forcePathStyle: true,
|
||||
});
|
||||
} else {
|
||||
this.presignS3 = this.s3;
|
||||
}
|
||||
}
|
||||
|
||||
async initialize({
|
||||
@@ -72,7 +93,7 @@ export class UploadService {
|
||||
PartNumber: index + 1,
|
||||
});
|
||||
promises.push(
|
||||
getSignedUrl(this.s3, command, {
|
||||
getSignedUrl(this.presignS3, command, {
|
||||
expiresIn: 60 * 60 * 24 * 7,
|
||||
}),
|
||||
);
|
||||
@@ -180,7 +201,7 @@ export class UploadService {
|
||||
Bucket: process.env.S3_PRIVATE_BUCKET_NAME,
|
||||
Key: key,
|
||||
});
|
||||
return getSignedUrl(this.s3, command, {
|
||||
return getSignedUrl(this.presignS3, command, {
|
||||
expiresIn: expires ?? 60 * 60 * 24 * 7,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user