refactor(storage): replace configureStorageApi with additive registration pattern
This commit is contained in:
@@ -10,9 +10,9 @@
|
|||||||
* - All other paths → session required; access governed by registered policies
|
* - All other paths → session required; access governed by registered policies
|
||||||
* - Unknown paths → denied
|
* - Unknown paths → denied
|
||||||
*
|
*
|
||||||
* Call configureStorageApi({ getPublicPrefixes, getAccessPolicies }) during
|
* Call registerStoragePolicies() and registerStoragePublicPrefixes() during
|
||||||
* initializeZen before the first request, following the same pattern as
|
* initializeZen before the first request, following the same pattern as
|
||||||
* configureRouter in core/api/runtime.js.
|
* registerFeatureRoutes in core/api/runtime.js.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|||||||
@@ -350,4 +350,4 @@ export {
|
|||||||
moveFile,
|
moveFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { configureStorageApi } from './storage-config.js';
|
export { registerStoragePolicies, registerStoragePublicPrefixes, clearStorageConfig } from './storage-config.js';
|
||||||
|
|||||||
@@ -1,21 +1,44 @@
|
|||||||
/**
|
/**
|
||||||
* Storage API runtime configuration.
|
* Storage API runtime configuration.
|
||||||
* Holds injected prefix/policy resolvers — same pattern as core/api/runtime.js.
|
*
|
||||||
* Imported by both api.js (reads) and index.js (exports configureStorageApi).
|
* Additive registration — mirrors core/api/runtime.js:
|
||||||
|
* registerStoragePolicies(policies) called by features during initializeZen()
|
||||||
|
* registerStoragePublicPrefixes(prefixes) called by features during initializeZen()
|
||||||
|
* clearStorageConfig() called by resetZenInitialization() / tests
|
||||||
|
*
|
||||||
|
* getStorageAccessPolicies() and getStoragePublicPrefixes() are read-only readers
|
||||||
|
* used internally by api.js — they are not re-exported from index.js.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let _getPublicPrefixes = () => [];
|
const POLICIES_KEY = Symbol.for('__ZEN_STORAGE_POLICIES__');
|
||||||
let _getAccessPolicies = () => [];
|
const PREFIXES_KEY = Symbol.for('__ZEN_STORAGE_PUBLIC_PREFIXES__');
|
||||||
|
|
||||||
export function configureStorageApi({ getPublicPrefixes, getAccessPolicies }) {
|
if (!globalThis[POLICIES_KEY]) globalThis[POLICIES_KEY] = [];
|
||||||
_getPublicPrefixes = getPublicPrefixes;
|
if (!globalThis[PREFIXES_KEY]) globalThis[PREFIXES_KEY] = [];
|
||||||
_getAccessPolicies = getAccessPolicies;
|
|
||||||
|
export function registerStoragePolicies(policies) {
|
||||||
|
if (!Array.isArray(policies)) {
|
||||||
|
throw new TypeError('registerStoragePolicies: policies must be an array');
|
||||||
|
}
|
||||||
|
globalThis[POLICIES_KEY].push(...policies);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerStoragePublicPrefixes(prefixes) {
|
||||||
|
if (!Array.isArray(prefixes)) {
|
||||||
|
throw new TypeError('registerStoragePublicPrefixes: prefixes must be an array');
|
||||||
|
}
|
||||||
|
globalThis[PREFIXES_KEY].push(...prefixes);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearStorageConfig() {
|
||||||
|
globalThis[POLICIES_KEY].length = 0;
|
||||||
|
globalThis[PREFIXES_KEY].length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStoragePublicPrefixes() {
|
export function getStoragePublicPrefixes() {
|
||||||
return _getPublicPrefixes();
|
return globalThis[PREFIXES_KEY];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStorageAccessPolicies() {
|
export function getStorageAccessPolicies() {
|
||||||
return _getAccessPolicies();
|
return globalThis[POLICIES_KEY];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Auth feature — storage access policies.
|
||||||
|
*
|
||||||
|
* Registered during initializeZen() via registerStoragePolicies().
|
||||||
|
* The auth feature owns its access rules; core/storage stays generic.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const storageAccessPolicies = [
|
||||||
|
// users/{userId}/... — seul le propriétaire ou un admin peut accéder
|
||||||
|
{ prefix: 'users', type: 'owner' },
|
||||||
|
];
|
||||||
@@ -15,8 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { configureRouter, registerFeatureRoutes, clearRouterConfig, clearFeatureRoutes } from '@zen/core/api';
|
import { configureRouter, registerFeatureRoutes, clearRouterConfig, clearFeatureRoutes } from '@zen/core/api';
|
||||||
|
import { registerStoragePolicies, clearStorageConfig } from '@zen/core/storage';
|
||||||
import { validateSession } from '../../features/auth/lib/session.js';
|
import { validateSession } from '../../features/auth/lib/session.js';
|
||||||
import { routes as authRoutes } from '../../features/auth/api.js';
|
import { routes as authRoutes } from '../../features/auth/api.js';
|
||||||
|
import { storageAccessPolicies } from '../../features/auth/storage-policies.js';
|
||||||
import { done, warn } from './logger.js';
|
import { done, warn } from './logger.js';
|
||||||
|
|
||||||
const ZEN_INIT_KEY = Symbol.for('__ZEN_INITIALIZED__');
|
const ZEN_INIT_KEY = Symbol.for('__ZEN_INITIALIZED__');
|
||||||
@@ -35,6 +37,7 @@ export async function initializeZen() {
|
|||||||
|
|
||||||
configureRouter({ resolveSession: validateSession });
|
configureRouter({ resolveSession: validateSession });
|
||||||
registerFeatureRoutes(authRoutes);
|
registerFeatureRoutes(authRoutes);
|
||||||
|
registerStoragePolicies(storageAccessPolicies);
|
||||||
|
|
||||||
done('ZEN: ready');
|
done('ZEN: ready');
|
||||||
|
|
||||||
@@ -45,5 +48,6 @@ export function resetZenInitialization() {
|
|||||||
globalThis[ZEN_INIT_KEY] = false;
|
globalThis[ZEN_INIT_KEY] = false;
|
||||||
clearRouterConfig();
|
clearRouterConfig();
|
||||||
clearFeatureRoutes();
|
clearFeatureRoutes();
|
||||||
|
clearStorageConfig();
|
||||||
warn('ZEN: initialization reset');
|
warn('ZEN: initialization reset');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user