docs/feat: add storage policies to discovery and refactor utils
- Add `storagePublicPrefixes` and `storageAccessPolicies` fields to both internal and external module config loading in discovery.js - Add a module-level `MIME_TYPES` constant in storage/utils.js to avoid recreating the object on every `getMimeType` call - Remove unused `validateImageDimensions` export from storage/index.js - Remove dead `isFinite` check after `Math.min/max` in `getPresignedUrl` (result is always finite at that point) - Remove unused `warn` import from storage/utils.js - Add documentation rule in DEV.md: comments must always reflect the actual behavior of the code they describe
This commit is contained in:
@@ -11,40 +11,17 @@
|
||||
* import { getAllStoragePublicPrefixes, getAllStorageAccessPolicies } from '@zen/core/modules/storage';
|
||||
*/
|
||||
|
||||
import { getModule, getEnabledModules } from '@zen/core/core/modules';
|
||||
import { getPostsConfig } from './posts/config.js';
|
||||
import { getEnabledModules } from '@zen/core/core/modules';
|
||||
|
||||
/**
|
||||
* Compute public storage prefixes for the posts module from its type config.
|
||||
* Avoids importing module.config.js (which contains React lazy() calls).
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function getPostsPublicPrefixes() {
|
||||
if (process.env.ZEN_MODULE_POSTS !== 'true') return [];
|
||||
const config = getPostsConfig();
|
||||
return Object.values(config.types)
|
||||
.filter(t => t.public)
|
||||
.map(t => `posts/${t.key}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all storage public prefixes from every enabled module (internal + external).
|
||||
* Get all storage public prefixes from every enabled module.
|
||||
* @returns {string[]} Deduplicated list of public storage prefixes
|
||||
*/
|
||||
export function getAllStoragePublicPrefixes() {
|
||||
const prefixes = new Set();
|
||||
|
||||
// Internal modules — call server-only config helpers directly to avoid
|
||||
// importing module.config.js files that contain React lazy() references.
|
||||
for (const prefix of getPostsPublicPrefixes()) {
|
||||
prefixes.add(prefix);
|
||||
}
|
||||
|
||||
// External modules — runtime registry
|
||||
for (const mod of getEnabledModules()) {
|
||||
if (!mod.external) continue;
|
||||
const runtimeConfig = getModule(mod.name);
|
||||
for (const prefix of runtimeConfig?.storagePublicPrefixes ?? []) {
|
||||
for (const prefix of mod.storagePublicPrefixes ?? []) {
|
||||
prefixes.add(prefix);
|
||||
}
|
||||
}
|
||||
@@ -55,8 +32,12 @@ export function getAllStoragePublicPrefixes() {
|
||||
/**
|
||||
* Get all storage access policies from every enabled module.
|
||||
*
|
||||
* Policies for built-in features (auth, posts) are included directly.
|
||||
* External modules contribute via their `storageAccessPolicies` defineModule field.
|
||||
* Built-in: user files at users/{id}/... are always owner-scoped.
|
||||
* The auth feature is an always-on core feature with no module registration;
|
||||
* its policy is declared here as the single built-in entry.
|
||||
*
|
||||
* Additional policies are contributed by enabled modules via their
|
||||
* `storageAccessPolicies` defineModule field.
|
||||
*
|
||||
* Policy shape: { prefix: string, type: 'owner' | 'admin' }
|
||||
* 'owner' — pathParts[1] must match session.user.id, or role is 'admin'
|
||||
@@ -66,20 +47,12 @@ export function getAllStoragePublicPrefixes() {
|
||||
*/
|
||||
export function getAllStorageAccessPolicies() {
|
||||
const policies = [
|
||||
// Built-in auth feature — user files are owner-scoped
|
||||
// Built-in: user files are owner-scoped (auth feature, always enabled)
|
||||
{ prefix: 'users', type: 'owner' },
|
||||
];
|
||||
|
||||
// Posts module — non-public post paths require admin
|
||||
if (process.env.ZEN_MODULE_POSTS === 'true') {
|
||||
policies.push({ prefix: 'posts', type: 'admin' });
|
||||
}
|
||||
|
||||
// External modules
|
||||
for (const mod of getEnabledModules()) {
|
||||
if (!mod.external) continue;
|
||||
const runtimeConfig = getModule(mod.name);
|
||||
for (const policy of runtimeConfig?.storageAccessPolicies ?? []) {
|
||||
for (const policy of mod.storageAccessPolicies ?? []) {
|
||||
policies.push(policy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ export default defineModule({
|
||||
envVars: ['ZEN_MODULE_POSTS_TYPES'],
|
||||
|
||||
storagePublicPrefixes,
|
||||
storageAccessPolicies: [{ prefix: 'posts', type: 'admin' }],
|
||||
|
||||
// Array of sections — one per post type (server-side, env vars available)
|
||||
navigation: navigationSections,
|
||||
|
||||
Reference in New Issue
Block a user