Ship file viewer, editor improvements, and private package releases
This commit is contained in:
1 parent
645914955c
commit
a4a31032b9
158 files changed
+10523
-137
No files matched your search
@@ -2,6 +2,9 @@ import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import type { AppConfig } from "@wrnexus/styles";
|
||||
import { viewerPlugin } from "@wrnexus/viewer/plugin";
|
||||
import { localBinaryConverter, firstOf, sameOriginSource } from "@wrnexus/viewer/convert";
|
||||
import { uploadedConversionSource } from "@wrnexus/viewer/uploader";
|
||||
|
||||
/**
|
||||
* App configuration. Optional — delete this file and the app still runs.
|
||||
@@ -13,6 +16,38 @@ import type { AppConfig } from "@wrnexus/styles";
|
||||
* framework-level headers and optional CORS.
|
||||
*/
|
||||
const config: AppConfig = {
|
||||
// Server-side previews for formats no browser renders (.docx, .psd, .mkv,
|
||||
// .zip). Each recipe needs its binary on the host — LibreOffice, ImageMagick,
|
||||
// ffmpeg, 7-Zip. A missing binary is not an error: that format simply keeps
|
||||
// its download card, so this is safe to leave enabled anywhere.
|
||||
plugins: [
|
||||
viewerPlugin({
|
||||
convert: {
|
||||
converters: [localBinaryConverter()],
|
||||
// Converted output inherits the access check of its input: only a valid
|
||||
// signed link opens an object, so a private report cannot be converted
|
||||
// into a public preview.
|
||||
resolveSource: firstOf(uploadedConversionSource(), sameOriginSource()),
|
||||
},
|
||||
uploads: {
|
||||
stores: ["media", "reports"],
|
||||
secret: process.env.VIEWER_FILE_SECRET ?? "example-app-development-secret-value",
|
||||
ttlMs: 5 * 60 * 1000,
|
||||
// DEMO ONLY. A real app checks the signed-in user against the object
|
||||
// here — this hook is the whole access control for private previews.
|
||||
authorize: () => true,
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
storage: {
|
||||
default: "media",
|
||||
stores: {
|
||||
media: { driver: "local", access: "public", dir: "uploads/public" },
|
||||
reports: { driver: "local", access: "private", dir: "uploads/private" },
|
||||
},
|
||||
},
|
||||
|
||||
head: [
|
||||
// --- Use a CSS framework via CDN (uncomment one) ---
|
||||
// Bootstrap:
|
||||
@@ -65,6 +100,17 @@ const config: AppConfig = {
|
||||
// Defaults already include CSP, COOP, X-Frame-Options, Trusted Types in
|
||||
// production, strong HSTS in production, nosniff, referrer policy, and a
|
||||
// restrictive Permissions-Policy. CORS is opt-in:
|
||||
|
||||
// The /file-viewer page embeds a same-origin PDF in a frame. The framework
|
||||
// defaults (`frame-ancestors 'none'` plus `X-Frame-Options: DENY`) stop an
|
||||
// app framing even its own assets, so same-origin framing is allowed here.
|
||||
// Cross-origin framing stays blocked.
|
||||
frameOptions: "SAMEORIGIN",
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
"frame-ancestors": ["'self'"],
|
||||
},
|
||||
},
|
||||
cors: {
|
||||
enabled: true,
|
||||
origin: ["http://localhost:5173", "http://localhost:3000"],
|
||||
|
||||
Reference in new issue
Block a user