ep_media_upload 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/index.js +22 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,8 +27,9 @@ Etherpad plugin for secure file uploads via S3 presigned URLs.
|
|
|
27
27
|
"expires": 900,
|
|
28
28
|
"downloadExpires": 300
|
|
29
29
|
},
|
|
30
|
-
"fileTypes": ["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "zip"],
|
|
31
|
-
"maxFileSize": 52428800
|
|
30
|
+
"fileTypes": ["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "zip", "mp3", "mp4", "wav", "mov"],
|
|
31
|
+
"maxFileSize": 52428800,
|
|
32
|
+
"inlineExtensions": ["mp3", "mp4", "wav", "mov", "webm", "ogg"]
|
|
32
33
|
}
|
|
33
34
|
```
|
|
34
35
|
|
|
@@ -49,6 +50,7 @@ Etherpad plugin for secure file uploads via S3 presigned URLs.
|
|
|
49
50
|
|--------|----------|---------|-------------|
|
|
50
51
|
| `fileTypes` | No | all | Array of allowed extensions (without dots) |
|
|
51
52
|
| `maxFileSize` | No | unlimited | Max file size in bytes |
|
|
53
|
+
| `inlineExtensions` | No | `[]` | Extensions to open inline in browser (streaming). Files not in this list will download. |
|
|
52
54
|
|
|
53
55
|
### Environment Variables
|
|
54
56
|
|
package/index.js
CHANGED
|
@@ -133,7 +133,7 @@ const EXTENSION_MIME_MAP = {
|
|
|
133
133
|
|
|
134
134
|
// Audio
|
|
135
135
|
mp3: ['audio/mpeg', 'audio/mp3'],
|
|
136
|
-
wav: ['audio/wav', 'audio/wave', 'audio/x-wav'],
|
|
136
|
+
wav: ['audio/wav', 'audio/wave', 'audio/x-wav', 'audio/vnd.wave'],
|
|
137
137
|
ogg: ['audio/ogg'],
|
|
138
138
|
m4a: ['audio/mp4', 'audio/x-m4a'],
|
|
139
139
|
flac: ['audio/flac'],
|
|
@@ -467,11 +467,30 @@ exports.expressCreateServer = (hookName, context) => {
|
|
|
467
467
|
const prefix = keyPrefix || '';
|
|
468
468
|
const key = `${prefix}${padId}/${fileId}`;
|
|
469
469
|
|
|
470
|
+
// Extract file extension to determine inline vs attachment disposition
|
|
471
|
+
const fileExtension = getValidExtension(fileId);
|
|
472
|
+
|
|
473
|
+
// Get inlineExtensions from config (extensions that should open in browser)
|
|
474
|
+
// Default behavior is download (attachment) for all files
|
|
475
|
+
const inlineExtensions = settings.ep_media_upload?.inlineExtensions || [];
|
|
476
|
+
const shouldOpenInline = fileExtension &&
|
|
477
|
+
Array.isArray(inlineExtensions) &&
|
|
478
|
+
inlineExtensions.map(e => e.toLowerCase()).includes(fileExtension.toLowerCase());
|
|
479
|
+
|
|
480
|
+
// Determine Content-Disposition based on extension config
|
|
481
|
+
// Extract filename for Content-Disposition header (UUID.ext -> use as filename)
|
|
482
|
+
const filename = fileId.replace(/[^\w\-_.]/g, '_'); // Sanitize for header
|
|
483
|
+
const disposition = shouldOpenInline
|
|
484
|
+
? `inline; filename="${filename}"`
|
|
485
|
+
: `attachment; filename="${filename}"`;
|
|
486
|
+
|
|
470
487
|
// Generate presigned GET URL with short expiry
|
|
488
|
+
// Use ResponseContentDisposition to override the stored header
|
|
471
489
|
const s3Client = new S3Client({ region });
|
|
472
490
|
const getCommand = new GetObjectCommand({
|
|
473
491
|
Bucket: bucket,
|
|
474
492
|
Key: key,
|
|
493
|
+
ResponseContentDisposition: disposition,
|
|
475
494
|
});
|
|
476
495
|
|
|
477
496
|
// Use downloadExpires from config, default to 300 seconds (5 minutes)
|
|
@@ -480,7 +499,8 @@ exports.expressCreateServer = (hookName, context) => {
|
|
|
480
499
|
|
|
481
500
|
// Log download request for audit trail
|
|
482
501
|
const username = req.session?.user?.username || 'anonymous';
|
|
483
|
-
|
|
502
|
+
const dispositionType = shouldOpenInline ? 'inline' : 'attachment';
|
|
503
|
+
logger.info(`[ep_media_upload] DOWNLOAD: author="${authorId}" user="${username}" ip="${clientIp}" pad="${padId}" file="${fileId}" disposition="${dispositionType}"`);
|
|
484
504
|
|
|
485
505
|
// Redirect to the presigned URL
|
|
486
506
|
return res.redirect(302, presignedGetUrl);
|
package/package.json
CHANGED