@aphexcms/cms-core 8.1.0 → 9.0.0

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.
Files changed (202) hide show
  1. package/dist/api/api-keys.d.ts +8 -3
  2. package/dist/api/api-keys.d.ts.map +1 -1
  3. package/dist/api/schemas/assets.js +1 -1
  4. package/dist/api/schemas/documents.d.ts +0 -2
  5. package/dist/api/schemas/documents.d.ts.map +1 -1
  6. package/dist/api/schemas/documents.js +2 -8
  7. package/dist/api/schemas/instance.d.ts +6 -0
  8. package/dist/api/schemas/instance.d.ts.map +1 -0
  9. package/dist/api/schemas/instance.js +7 -0
  10. package/dist/api/schemas/user.js +1 -1
  11. package/dist/auth/auth-hooks.d.ts.map +1 -1
  12. package/dist/auth/auth-hooks.js +9 -3
  13. package/dist/cli/generate-types.d.ts.map +1 -1
  14. package/dist/cli/generate-types.js +1 -3
  15. package/dist/cli/generate-types.js.map +1 -1
  16. package/dist/components/AdminApp.svelte +9 -12
  17. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  18. package/dist/components/admin/DocumentEditor.svelte +47 -49
  19. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  20. package/dist/components/admin/MediaBrowser.svelte +7 -7
  21. package/dist/components/admin/fields/ArrayField.svelte +4 -2
  22. package/dist/components/admin/fields/FileField.svelte +1 -1
  23. package/dist/components/admin/fields/ImageField.svelte +1 -1
  24. package/dist/components/admin/fields/ReferenceField.svelte +5 -3
  25. package/dist/components/layout/OrganizationSwitcher.svelte +1 -1
  26. package/dist/components/layout/sidebar/NavMain.svelte +9 -1
  27. package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -1
  28. package/dist/db/interfaces/asset.d.ts +2 -4
  29. package/dist/db/interfaces/asset.d.ts.map +1 -1
  30. package/dist/db/interfaces/organization.d.ts +1 -1
  31. package/dist/db/interfaces/organization.d.ts.map +1 -1
  32. package/dist/field-access.d.ts.map +1 -1
  33. package/dist/field-access.js +5 -1
  34. package/dist/graphql/depth-limit.d.ts +8 -0
  35. package/dist/graphql/depth-limit.d.ts.map +1 -0
  36. package/dist/graphql/depth-limit.js +79 -0
  37. package/dist/graphql/index.d.ts.map +1 -1
  38. package/dist/graphql/index.js +12 -1
  39. package/dist/graphql/resolvers.d.ts.map +1 -1
  40. package/dist/graphql/resolvers.js +9 -11
  41. package/dist/hooks.d.ts +2 -0
  42. package/dist/hooks.d.ts.map +1 -1
  43. package/dist/hooks.js +5 -2
  44. package/dist/lib/api/api-keys.d.ts +8 -3
  45. package/dist/lib/api/api-keys.d.ts.map +1 -1
  46. package/dist/lib/api/api-keys.js.map +1 -1
  47. package/dist/lib/api/schemas/assets.js +1 -1
  48. package/dist/lib/api/schemas/assets.js.map +1 -1
  49. package/dist/lib/api/schemas/documents.d.ts +0 -2
  50. package/dist/lib/api/schemas/documents.d.ts.map +1 -1
  51. package/dist/lib/api/schemas/documents.js +2 -8
  52. package/dist/lib/api/schemas/documents.js.map +1 -1
  53. package/dist/lib/api/schemas/instance.d.ts +6 -0
  54. package/dist/lib/api/schemas/instance.d.ts.map +1 -0
  55. package/dist/lib/api/schemas/instance.js +8 -0
  56. package/dist/lib/api/schemas/instance.js.map +1 -0
  57. package/dist/lib/api/schemas/user.js +1 -1
  58. package/dist/lib/auth/auth-hooks.d.ts.map +1 -1
  59. package/dist/lib/auth/auth-hooks.js +9 -3
  60. package/dist/lib/auth/auth-hooks.js.map +1 -1
  61. package/dist/lib/db/interfaces/asset.d.ts +2 -4
  62. package/dist/lib/db/interfaces/asset.d.ts.map +1 -1
  63. package/dist/lib/db/interfaces/organization.d.ts +1 -1
  64. package/dist/lib/db/interfaces/organization.d.ts.map +1 -1
  65. package/dist/lib/field-access.d.ts.map +1 -1
  66. package/dist/lib/field-access.js +5 -1
  67. package/dist/lib/field-access.js.map +1 -1
  68. package/dist/lib/graphql/depth-limit.d.ts +8 -0
  69. package/dist/lib/graphql/depth-limit.d.ts.map +1 -0
  70. package/dist/lib/graphql/depth-limit.js +80 -0
  71. package/dist/lib/graphql/depth-limit.js.map +1 -0
  72. package/dist/lib/graphql/index.d.ts.map +1 -1
  73. package/dist/lib/graphql/index.js +12 -1
  74. package/dist/lib/graphql/index.js.map +1 -1
  75. package/dist/lib/graphql/resolvers.d.ts.map +1 -1
  76. package/dist/lib/graphql/resolvers.js +9 -11
  77. package/dist/lib/graphql/resolvers.js.map +1 -1
  78. package/dist/lib/hooks.d.ts +2 -0
  79. package/dist/lib/hooks.d.ts.map +1 -1
  80. package/dist/lib/hooks.js +5 -2
  81. package/dist/lib/hooks.js.map +1 -1
  82. package/dist/lib/local-api/collection-api.d.ts.map +1 -1
  83. package/dist/lib/local-api/collection-api.js +7 -9
  84. package/dist/lib/local-api/collection-api.js.map +1 -1
  85. package/dist/lib/local-api/index.d.ts +5 -1
  86. package/dist/lib/local-api/index.d.ts.map +1 -1
  87. package/dist/lib/local-api/index.js +12 -4
  88. package/dist/lib/local-api/index.js.map +1 -1
  89. package/dist/lib/routes/assets-cdn.d.ts.map +1 -1
  90. package/dist/lib/routes/assets-cdn.js +8 -3
  91. package/dist/lib/routes/assets-cdn.js.map +1 -1
  92. package/dist/lib/server/api/index.d.ts.map +1 -1
  93. package/dist/lib/server/api/index.js +18 -0
  94. package/dist/lib/server/api/index.js.map +1 -1
  95. package/dist/lib/server/api/routes/assets-bulk.d.ts.map +1 -1
  96. package/dist/lib/server/api/routes/assets-bulk.js +4 -0
  97. package/dist/lib/server/api/routes/assets-bulk.js.map +1 -1
  98. package/dist/lib/server/api/routes/assets-by-id.d.ts.map +1 -1
  99. package/dist/lib/server/api/routes/assets-by-id.js +7 -0
  100. package/dist/lib/server/api/routes/assets-by-id.js.map +1 -1
  101. package/dist/lib/server/api/routes/assets.d.ts.map +1 -1
  102. package/dist/lib/server/api/routes/assets.js +18 -9
  103. package/dist/lib/server/api/routes/assets.js.map +1 -1
  104. package/dist/lib/server/api/routes/document-versions.d.ts.map +1 -1
  105. package/dist/lib/server/api/routes/document-versions.js +8 -0
  106. package/dist/lib/server/api/routes/document-versions.js.map +1 -1
  107. package/dist/lib/server/api/routes/documents-by-id.d.ts.map +1 -1
  108. package/dist/lib/server/api/routes/documents-by-id.js +3 -3
  109. package/dist/lib/server/api/routes/documents-by-id.js.map +1 -1
  110. package/dist/lib/server/api/routes/documents-publish.d.ts.map +1 -1
  111. package/dist/lib/server/api/routes/documents-publish.js +2 -2
  112. package/dist/lib/server/api/routes/documents-publish.js.map +1 -1
  113. package/dist/lib/server/api/routes/documents-query.d.ts.map +1 -1
  114. package/dist/lib/server/api/routes/documents-query.js +2 -3
  115. package/dist/lib/server/api/routes/documents-query.js.map +1 -1
  116. package/dist/lib/server/api/routes/documents.d.ts.map +1 -1
  117. package/dist/lib/server/api/routes/documents.js +3 -5
  118. package/dist/lib/server/api/routes/documents.js.map +1 -1
  119. package/dist/lib/server/api/routes/organizations-invitations.d.ts.map +1 -1
  120. package/dist/lib/server/api/routes/organizations-invitations.js +1 -1
  121. package/dist/lib/server/api/routes/organizations-invitations.js.map +1 -1
  122. package/dist/lib/server/api/routes/organizations-members.d.ts.map +1 -1
  123. package/dist/lib/server/api/routes/organizations-members.js.map +1 -1
  124. package/dist/lib/server/index.d.ts +1 -0
  125. package/dist/lib/server/index.d.ts.map +1 -1
  126. package/dist/lib/server/index.js +2 -0
  127. package/dist/lib/server/index.js.map +1 -1
  128. package/dist/lib/services/asset-service.d.ts.map +1 -1
  129. package/dist/lib/services/asset-service.js +4 -2
  130. package/dist/lib/services/asset-service.js.map +1 -1
  131. package/dist/lib/services/references-service.d.ts.map +1 -1
  132. package/dist/lib/services/references-service.js.map +1 -1
  133. package/dist/lib/storage/adapters/local-storage-adapter.d.ts +4 -0
  134. package/dist/lib/storage/adapters/local-storage-adapter.d.ts.map +1 -1
  135. package/dist/lib/storage/adapters/local-storage-adapter.js +28 -6
  136. package/dist/lib/storage/adapters/local-storage-adapter.js.map +1 -1
  137. package/dist/lib/types/capabilities.d.ts +1 -0
  138. package/dist/lib/types/capabilities.d.ts.map +1 -1
  139. package/dist/lib/types/capabilities.js +3 -0
  140. package/dist/lib/types/capabilities.js.map +1 -1
  141. package/dist/lib/types/config.d.ts +16 -1
  142. package/dist/lib/types/config.d.ts.map +1 -1
  143. package/dist/lib/utils/logger.d.ts +8 -6
  144. package/dist/lib/utils/logger.d.ts.map +1 -1
  145. package/dist/lib/utils/logger.js +11 -2
  146. package/dist/lib/utils/logger.js.map +1 -1
  147. package/dist/lib/utils/mime-detect.d.ts.map +1 -1
  148. package/dist/lib/utils/mime-detect.js +21 -6
  149. package/dist/lib/utils/mime-detect.js.map +1 -1
  150. package/dist/lib/vite/index.d.ts.map +1 -1
  151. package/dist/lib/vite/index.js +4 -5
  152. package/dist/lib/vite/index.js.map +1 -1
  153. package/dist/local-api/collection-api.d.ts.map +1 -1
  154. package/dist/local-api/collection-api.js +7 -9
  155. package/dist/local-api/index.d.ts +5 -1
  156. package/dist/local-api/index.d.ts.map +1 -1
  157. package/dist/local-api/index.js +12 -4
  158. package/dist/routes/assets-cdn.d.ts.map +1 -1
  159. package/dist/routes/assets-cdn.js +8 -3
  160. package/dist/server/api/index.d.ts.map +1 -1
  161. package/dist/server/api/index.js +18 -0
  162. package/dist/server/api/routes/assets-bulk.d.ts.map +1 -1
  163. package/dist/server/api/routes/assets-bulk.js +4 -0
  164. package/dist/server/api/routes/assets-by-id.d.ts.map +1 -1
  165. package/dist/server/api/routes/assets-by-id.js +7 -0
  166. package/dist/server/api/routes/assets.d.ts.map +1 -1
  167. package/dist/server/api/routes/assets.js +18 -9
  168. package/dist/server/api/routes/document-versions.d.ts.map +1 -1
  169. package/dist/server/api/routes/document-versions.js +8 -0
  170. package/dist/server/api/routes/documents-by-id.d.ts.map +1 -1
  171. package/dist/server/api/routes/documents-by-id.js +3 -3
  172. package/dist/server/api/routes/documents-publish.d.ts.map +1 -1
  173. package/dist/server/api/routes/documents-publish.js +2 -2
  174. package/dist/server/api/routes/documents-query.d.ts.map +1 -1
  175. package/dist/server/api/routes/documents-query.js +2 -3
  176. package/dist/server/api/routes/documents.d.ts.map +1 -1
  177. package/dist/server/api/routes/documents.js +3 -5
  178. package/dist/server/api/routes/organizations-invitations.d.ts.map +1 -1
  179. package/dist/server/api/routes/organizations-invitations.js +1 -1
  180. package/dist/server/api/routes/organizations-members.d.ts.map +1 -1
  181. package/dist/server/index.d.ts +1 -0
  182. package/dist/server/index.d.ts.map +1 -1
  183. package/dist/server/index.js +2 -0
  184. package/dist/services/asset-service.d.ts.map +1 -1
  185. package/dist/services/asset-service.js +4 -2
  186. package/dist/services/references-service.d.ts.map +1 -1
  187. package/dist/storage/adapters/local-storage-adapter.d.ts +4 -0
  188. package/dist/storage/adapters/local-storage-adapter.d.ts.map +1 -1
  189. package/dist/storage/adapters/local-storage-adapter.js +28 -6
  190. package/dist/types/capabilities.d.ts +1 -0
  191. package/dist/types/capabilities.d.ts.map +1 -1
  192. package/dist/types/capabilities.js +3 -0
  193. package/dist/types/config.d.ts +16 -1
  194. package/dist/types/config.d.ts.map +1 -1
  195. package/dist/utils/logger.d.ts +8 -6
  196. package/dist/utils/logger.d.ts.map +1 -1
  197. package/dist/utils/logger.js +11 -2
  198. package/dist/utils/mime-detect.d.ts.map +1 -1
  199. package/dist/utils/mime-detect.js +21 -6
  200. package/dist/vite/index.d.ts.map +1 -1
  201. package/dist/vite/index.js +4 -5
  202. package/package.json +4 -5
@@ -3,6 +3,7 @@ import { zValidator } from '@hono/zod-validator';
3
3
  import { cmsLogger } from '../../../utils/logger.js';
4
4
  import { validateFile } from '../../../utils/mime-detect.js';
5
5
  import { listAssetsQuery } from '../../../api/schemas/assets.js';
6
+ import { hasCapability } from '../../../types/capabilities.js';
6
7
  export const assetsRouter = new Hono()
7
8
  .get('/', zValidator('query', listAssetsQuery, (result, c) => {
8
9
  if (!result.success) {
@@ -27,15 +28,15 @@ export const assetsRouter = new Hono()
27
28
  limit: q.limit ?? 20,
28
29
  offset: q.offset ?? 0
29
30
  };
30
- const [fetchedAssets, totalAssets] = await Promise.all([
31
+ const { databaseAdapter } = c.var.aphexCMS;
32
+ const [fetchedAssets, total] = await Promise.all([
31
33
  assetService.findAssets(auth.organizationId, filters),
32
- assetService.findAssets(auth.organizationId, {
33
- ...filters,
34
- limit: 999999,
35
- offset: 0
34
+ databaseAdapter.countAssets(auth.organizationId, {
35
+ assetType: filters.assetType,
36
+ mimeType: filters.mimeType,
37
+ search: filters.search
36
38
  })
37
39
  ]);
38
- const total = totalAssets.length;
39
40
  const pageSize = filters.limit || 20;
40
41
  const currentPage = Math.floor(filters.offset / pageSize) + 1;
41
42
  const totalPages = Math.ceil(total / pageSize);
@@ -68,6 +69,9 @@ export const assetsRouter = new Hono()
68
69
  if (!auth || auth.type === 'partial_session') {
69
70
  return c.json({ success: false, error: 'Unauthorized' }, 401);
70
71
  }
72
+ if (!hasCapability(auth, 'asset.upload')) {
73
+ return c.json({ success: false, error: 'Forbidden: asset.upload capability required' }, 403);
74
+ }
71
75
  const formData = await c.req.formData();
72
76
  const file = formData.get('file');
73
77
  if (!file) {
@@ -75,10 +79,14 @@ export const assetsRouter = new Hono()
75
79
  }
76
80
  const arrayBuffer = await file.arrayBuffer();
77
81
  const buffer = Buffer.from(arrayBuffer);
82
+ const SERVER_MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB hard limit
78
83
  const allowedMimeTypesRaw = formData.get('allowedMimeTypes');
79
84
  const maxSizeRaw = formData.get('maxSize');
80
85
  const allowedMimeTypes = allowedMimeTypesRaw ? JSON.parse(allowedMimeTypesRaw) : undefined;
81
- const maxSize = maxSizeRaw ? parseInt(maxSizeRaw, 10) : undefined;
86
+ const clientMaxSize = maxSizeRaw ? parseInt(maxSizeRaw, 10) : undefined;
87
+ const maxSize = clientMaxSize
88
+ ? Math.min(clientMaxSize, SERVER_MAX_FILE_SIZE)
89
+ : SERVER_MAX_FILE_SIZE;
82
90
  const validation = validateFile(buffer, file.name, file.type, {
83
91
  allowedMimeTypes,
84
92
  maxSize
@@ -86,18 +94,19 @@ export const assetsRouter = new Hono()
86
94
  if (!validation.valid) {
87
95
  return c.json({ success: false, error: validation.error }, 400);
88
96
  }
97
+ const safeMimeType = validation.detectedMimeType || 'application/octet-stream';
89
98
  const title = formData.get('title') || undefined;
90
99
  const description = formData.get('description') || undefined;
91
100
  const alt = formData.get('alt') || undefined;
92
101
  const creditLine = formData.get('creditLine') || undefined;
93
102
  const schemaType = formData.get('schemaType') || undefined;
94
103
  const fieldPath = formData.get('fieldPath') || undefined;
95
- const targetOrganizationId = formData.get('organizationId') || auth.organizationId;
104
+ const targetOrganizationId = auth.organizationId;
96
105
  const uploadData = {
97
106
  organizationId: targetOrganizationId,
98
107
  buffer,
99
108
  originalFilename: file.name,
100
- mimeType: file.type,
109
+ mimeType: safeMimeType,
101
110
  size: file.size,
102
111
  title,
103
112
  description,
@@ -1 +1 @@
1
- {"version":3,"file":"document-versions.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/document-versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,QAAQ,CAqJ/C,CAAC"}
1
+ {"version":3,"file":"document-versions.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/document-versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,QAAQ,CAiK/C,CAAC"}
@@ -2,6 +2,7 @@ import { Hono } from 'hono';
2
2
  import { zValidator } from '@hono/zod-validator';
3
3
  import { authToContext } from '../../../local-api/auth-helpers.js';
4
4
  import { cmsLogger } from '../../../utils/logger.js';
5
+ import { hasCapability } from '../../../types/capabilities.js';
5
6
  import { listVersionsQuery } from '../../../api/schemas/documents.js';
6
7
  export const documentVersionsRouter = new Hono()
7
8
  .get('/:id/versions', zValidator('query', listVersionsQuery, (result, c) => {
@@ -84,6 +85,13 @@ export const documentVersionsRouter = new Hono()
84
85
  })
85
86
  .post('/:id/versions/:version/restore', async (c) => {
86
87
  try {
88
+ const auth = c.var.auth;
89
+ if (!auth || auth.type === 'partial_session') {
90
+ return c.json({ success: false, error: 'Unauthorized' }, 401);
91
+ }
92
+ if (!hasCapability(auth, 'document.update')) {
93
+ return c.json({ success: false, error: 'Forbidden: document.update capability required' }, 403);
94
+ }
87
95
  const { localAPI, databaseAdapter } = c.var.aphexCMS;
88
96
  const context = authToContext(c.var.auth);
89
97
  const id = c.req.param('id');
@@ -1 +1 @@
1
- {"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-by-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CA6N5C,CAAC"}
1
+ {"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-by-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CAqN5C,CAAC"}
@@ -21,7 +21,7 @@ export const documentsByIdRouter = new Hono()
21
21
  if (!result) {
22
22
  return c.json({ success: false, error: 'Document not found' }, 404);
23
23
  }
24
- const collection = localAPI.collections[result.type];
24
+ const collection = localAPI.getCollection(result.type);
25
25
  if (!collection) {
26
26
  return c.json({
27
27
  success: false,
@@ -73,7 +73,7 @@ export const documentsByIdRouter = new Hono()
73
73
  if (!found) {
74
74
  return c.json({ success: false, error: 'Document not found' }, 404);
75
75
  }
76
- const collection = localAPI.collections[found.type];
76
+ const collection = localAPI.getCollection(found.type);
77
77
  if (!collection) {
78
78
  return c.json({
79
79
  success: false,
@@ -120,7 +120,7 @@ export const documentsByIdRouter = new Hono()
120
120
  if (!result) {
121
121
  return c.json({ success: false, error: 'Document not found' }, 404);
122
122
  }
123
- const collection = localAPI.collections[result.type];
123
+ const collection = localAPI.getCollection(result.type);
124
124
  if (!collection) {
125
125
  return c.json({
126
126
  success: false,
@@ -1 +1 @@
1
- {"version":3,"file":"documents-publish.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,QAAQ,CAkK/C,CAAC"}
1
+ {"version":3,"file":"documents-publish.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,QAAQ,CA4J/C,CAAC"}
@@ -23,7 +23,7 @@ export const documentsPublishRouter = new Hono()
23
23
  message: 'Document may not exist'
24
24
  }, 404);
25
25
  }
26
- const collection = localAPI.collections[found.type];
26
+ const collection = localAPI.getCollection(found.type);
27
27
  if (!collection) {
28
28
  return c.json({
29
29
  success: false,
@@ -84,7 +84,7 @@ export const documentsPublishRouter = new Hono()
84
84
  message: `No document found with ID: ${id}`
85
85
  }, 404);
86
86
  }
87
- const collection = localAPI.collections[found.type];
87
+ const collection = localAPI.getCollection(found.type);
88
88
  if (!collection) {
89
89
  return c.json({
90
90
  success: false,
@@ -1 +1 @@
1
- {"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,IAAI,CAAC,QAAQ,CAiF/C,CAAC"}
1
+ {"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,IAAI,CAAC,QAAQ,CA6E/C,CAAC"}
@@ -43,10 +43,9 @@ export const documentsQueryRouter = new Hono().post('/query', zValidator('json',
43
43
  depth: body.depth ?? 0,
44
44
  select: body.select,
45
45
  perspective: body.perspective ?? 'draft',
46
- includeChildOrganizations: body.includeChildOrganizations,
47
- filterOrganizationIds: body.filterOrganizationIds
46
+ includeChildOrganizations: body.includeChildOrganizations
48
47
  };
49
- const result = await localAPI.collections[documentType].find(context, findOptions);
48
+ const result = await localAPI.getCollection(documentType).find(context, findOptions);
50
49
  return c.json({
51
50
  success: true,
52
51
  data: result.docs,
@@ -1 +1 @@
1
- {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,eAAO,MAAM,eAAe,EAAE,IAAI,CAAC,QAAQ,CAyMxC,CAAC"}
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,eAAO,MAAM,eAAe,EAAE,IAAI,CAAC,QAAQ,CA6MzC,CAAC"}
@@ -25,7 +25,6 @@ export const documentsRouter = new Hono()
25
25
  const sortParam = Array.isArray(q.sort) ? q.sort.join(',') : q.sort;
26
26
  const perspective = q.perspective ?? 'draft';
27
27
  const includeChildOrganizations = q.includeChildOrganizations;
28
- const filterOrganizationIds = q.filterOrganizationIds;
29
28
  const page = q.page ?? DEFAULT_PAGE;
30
29
  const pageSize = q.pageSize ?? q.limit ?? DEFAULT_PAGE_SIZE;
31
30
  const offset = (page - 1) * pageSize;
@@ -37,7 +36,7 @@ export const documentsRouter = new Hono()
37
36
  message: 'Document type is required. Use ?type=page or ?docType=page'
38
37
  }, 400);
39
38
  }
40
- const collection = localAPI.collections[docType];
39
+ const collection = localAPI.getCollection(docType);
41
40
  if (!collection) {
42
41
  return c.json({
43
42
  success: false,
@@ -56,8 +55,7 @@ export const documentsRouter = new Hono()
56
55
  depth,
57
56
  sort: sortParam || undefined,
58
57
  perspective,
59
- includeChildOrganizations,
60
- filterOrganizationIds
58
+ includeChildOrganizations
61
59
  });
62
60
  return c.json({
63
61
  success: true,
@@ -128,7 +126,7 @@ export const documentsRouter = new Hono()
128
126
  const documentType = parsed.type;
129
127
  const documentData = (parsed.draftData ?? parsed.data);
130
128
  const shouldPublish = parsed.publish ?? false;
131
- const collection = localAPI.collections[documentType];
129
+ const collection = localAPI.getCollection(documentType);
132
130
  if (!collection) {
133
131
  return c.json({
134
132
  success: false,
@@ -1 +1 @@
1
- {"version":3,"file":"organizations-invitations.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations-invitations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,EAAE,IAAI,CAAC,QAAQ,CA0MxD,CAAC"}
1
+ {"version":3,"file":"organizations-invitations.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations-invitations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,EAAE,IAAI,CAAC,QAAQ,CA4MxD,CAAC"}
@@ -127,7 +127,7 @@ export const organizationsInvitationsRouter = new Hono()
127
127
  }, 403);
128
128
  }
129
129
  const body = c.req.valid('json');
130
- const deleted = await databaseAdapter.deleteInvitation(body.invitationId);
130
+ const deleted = await databaseAdapter.deleteInvitation(body.invitationId, auth.organizationId);
131
131
  if (!deleted) {
132
132
  return c.json({ success: false, error: 'Invitation not found' }, 404);
133
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"organizations-members.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations-members.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,0BAA0B,EAAE,IAAI,CAAC,QAAQ,CA+RpD,CAAC"}
1
+ {"version":3,"file":"organizations-members.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations-members.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,0BAA0B,EAAE,IAAI,CAAC,QAAQ,CA4RpD,CAAC"}
@@ -4,6 +4,7 @@ export * from '../cache/index.js';
4
4
  export * from '../email/index.js';
5
5
  export { AuthError, type AuthErrorCode } from '../auth/auth-errors.js';
6
6
  export { createCMSConfig } from '../config.js';
7
+ export { cmsLogger, setLogger, type Logger } from '../utils/logger.js';
7
8
  export { CMSEngine } from '../engine.js';
8
9
  export { createCMSHook, __notifyAphexConfigChanged, type CMSInstances } from '../hooks.js';
9
10
  export * from '../db/interfaces/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/server/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxF,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI5D,OAAO,EACN,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,KAAK,QAAQ,EACb,MAAM,aAAa,CAAC;AAGrB,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/server/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxF,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG/F,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,oBAAoB,CAAC"}
@@ -9,6 +9,8 @@ export * from '../email/index.js';
9
9
  export { AuthError } from '../auth/auth-errors.js';
10
10
  // Configuration system
11
11
  export { createCMSConfig } from '../config.js';
12
+ // Logger
13
+ export { cmsLogger, setLogger } from '../utils/logger.js';
12
14
  // CMS Engine
13
15
  export { CMSEngine } from '../engine.js';
14
16
  // Hooks integration (SvelteKit server hooks)
@@ -1 +1 @@
1
- {"version":3,"file":"asset-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/asset-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAG5C,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;gBADR,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,eAAe;IAGlC;;OAEG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC;IAoFhF;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAI9E;;;OAGG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAmB5D;;OAEG;IACG,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAItF;;;;;OAKG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BvE;;OAEG;IACG,mBAAmB,CACxB,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GACC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAIxB;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QACpD,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;IAeF;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC;QAChC,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KAClB,CAAC;CAWF"}
1
+ {"version":3,"file":"asset-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/asset-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAG5C,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;gBADR,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,eAAe;IAGlC;;OAEG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC;IAsFhF;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAI9E;;;OAGG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAmB5D;;OAEG;IACG,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAItF;;;;;OAKG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BvE;;OAEG;IACG,mBAAmB,CACxB,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GACC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAIxB;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QACpD,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;IAeF;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC;QAChC,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KAClB,CAAC;CAWF"}
@@ -27,7 +27,9 @@ export class AssetService {
27
27
  };
28
28
  if (assetType === 'image') {
29
29
  try {
30
- const imageMetadata = await sharp(data.buffer).metadata();
30
+ const imageMetadata = await sharp(data.buffer, {
31
+ limitInputPixels: 100_000_000
32
+ }).metadata();
31
33
  width = imageMetadata.width;
32
34
  height = imageMetadata.height;
33
35
  // Merge image metadata with field metadata
@@ -41,7 +43,7 @@ export class AssetService {
41
43
  hasAlpha: imageMetadata.hasAlpha
42
44
  };
43
45
  // Add dominant color
44
- const stats = await sharp(data.buffer).stats();
46
+ const stats = await sharp(data.buffer, { limitInputPixels: 100_000_000 }).stats();
45
47
  metadata.dominantColor = stats.dominant;
46
48
  }
47
49
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"references-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/references-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD;;;;;;;;;GASG;AACH,qBAAa,iBAAiB;IACjB,OAAO,CAAC,eAAe;gBAAf,eAAe,EAAE,eAAe;IAEpD;;;OAGG;IACG,iBAAiB,CACtB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,UAAU,GAAG,IAAI,EACzB,QAAQ,EAAE,UAAU,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;;;OAOG;IACG,eAAe,CACpB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,UAAU,EAAE,EACrB,gBAAgB,EAAE,MAAM,OAAO,CAC9B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAClD,GACC,OAAO,CAAC,IAAI,CAAC;CAwBhB"}
1
+ {"version":3,"file":"references-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/references-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD;;;;;;;;;GASG;AACH,qBAAa,iBAAiB;IACjB,OAAO,CAAC,eAAe;gBAAf,eAAe,EAAE,eAAe;IAEpD;;;OAGG;IACG,iBAAiB,CACtB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,UAAU,GAAG,IAAI,EACzB,QAAQ,EAAE,UAAU,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;;;OAOG;IACG,eAAe,CACpB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,UAAU,EAAE,EACrB,gBAAgB,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,GACjF,OAAO,CAAC,IAAI,CAAC;CAwBhB"}
@@ -6,6 +6,10 @@ export declare class LocalStorageAdapter implements StorageAdapter {
6
6
  readonly name = "local";
7
7
  private config;
8
8
  constructor(config: StorageConfig);
9
+ /**
10
+ * Strip path traversal sequences, keeping only the base filename.
11
+ */
12
+ private sanitizeFilename;
9
13
  /**
10
14
  * Generate unique filename preserving original name
11
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"local-storage-adapter.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/adapters/local-storage-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,MAAM,uBAAuB,CAAC;AAK/B;;GAEG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IACzD,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,MAAM,CAA0B;gBAE5B,MAAM,EAAE,aAAa;IASjC;;OAEG;YACW,sBAAsB;IAcpC;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;OAEG;YACW,gBAAgB;IAU9B;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAoCvD;;;OAGG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9C;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5C;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS5C;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAM5B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAyB/E;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAYnC"}
1
+ {"version":3,"file":"local-storage-adapter.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/adapters/local-storage-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,MAAM,uBAAuB,CAAC;AAK/B;;GAEG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IACzD,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,MAAM,CAA0B;gBAE5B,MAAM,EAAE,aAAa;IASjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;YACW,sBAAsB;IAepC;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;OAEG;YACW,gBAAgB;IAU9B;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAoCvD;;;OAGG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU9C;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe5C;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc5C;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAM5B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAyB/E;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAYnC"}
@@ -1,6 +1,6 @@
1
1
  // Pure local file system storage adapter - no database operations
2
2
  import { writeFile, mkdir, unlink, stat, readdir } from 'fs/promises';
3
- import { join, dirname } from 'path';
3
+ import { join, dirname, resolve, basename } from 'path';
4
4
  import { cmsLogger } from '../../utils/logger.js';
5
5
  const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
6
6
  /**
@@ -17,12 +17,19 @@ export class LocalStorageAdapter {
17
17
  options: config.options || {}
18
18
  };
19
19
  }
20
+ /**
21
+ * Strip path traversal sequences, keeping only the base filename.
22
+ */
23
+ sanitizeFilename(filename) {
24
+ return basename(filename).replace(/^\.+/, '_');
25
+ }
20
26
  /**
21
27
  * Generate unique filename preserving original name
22
28
  */
23
29
  async generateUniqueFilename(originalFilename) {
24
- const { name, ext } = this.parseFilename(originalFilename);
25
- let filename = originalFilename;
30
+ const safe = this.sanitizeFilename(originalFilename);
31
+ const { name, ext } = this.parseFilename(safe);
32
+ let filename = safe;
26
33
  let counter = 1;
27
34
  // Check if file exists on disk
28
35
  while (await this.fileExistsOnDisk(filename)) {
@@ -92,15 +99,25 @@ export class LocalStorageAdapter {
92
99
  * Used by API endpoint to serve files
93
100
  */
94
101
  async getObject(path) {
102
+ const resolved = resolve(path);
103
+ const base = resolve(this.config.basePath);
104
+ if (!resolved.startsWith(base + '/') && resolved !== base) {
105
+ throw new Error('Access denied: path outside storage directory');
106
+ }
95
107
  const { readFile } = await import('fs/promises');
96
- return await readFile(path);
108
+ return await readFile(resolved);
97
109
  }
98
110
  /**
99
111
  * Delete a file from storage
100
112
  */
101
113
  async delete(path) {
102
114
  try {
103
- await unlink(path);
115
+ const resolved = resolve(path);
116
+ const base = resolve(this.config.basePath);
117
+ if (!resolved.startsWith(base + '/') && resolved !== base) {
118
+ throw new Error('Access denied: path outside storage directory');
119
+ }
120
+ await unlink(resolved);
104
121
  return true;
105
122
  }
106
123
  catch (error) {
@@ -113,7 +130,12 @@ export class LocalStorageAdapter {
113
130
  */
114
131
  async exists(path) {
115
132
  try {
116
- await stat(path);
133
+ const resolved = resolve(path);
134
+ const base = resolve(this.config.basePath);
135
+ if (!resolved.startsWith(base + '/') && resolved !== base) {
136
+ return false;
137
+ }
138
+ await stat(resolved);
117
139
  return true;
118
140
  }
119
141
  catch {
@@ -61,6 +61,7 @@ export interface NewRole {
61
61
  * Used by migration, org-creation, and the runtime seeder.
62
62
  */
63
63
  export declare function buildBuiltinRoleRows(organizationId: string): NewRole[];
64
+ export declare function isInstanceRole(auth: Auth): boolean;
64
65
  /**
65
66
  * Check whether an Auth already has a capability.
66
67
  *
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/lib/types/capabilities.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAEnB,eAAe,GACf,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,oBAAoB,GAEpB,YAAY,GACZ,cAAc,GACd,cAAc,GAEd,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,eAAe,GACf,aAAa,GACb,cAAc,CAAC;AAMlB;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,UAAU,EAgBxC,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAKzD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACrC,gBAAgB,EAChB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CA4C5D,CAAC;AAeF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE,CAK/E;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,EAAE,CAQtE;AAWD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAEzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,CAoCvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAInE;AAID;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC3B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0EAA0E;IAC1E,YAAY,EAAE,UAAU,EAAE,CAAC;CAC3B"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/lib/types/capabilities.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAEnB,eAAe,GACf,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,oBAAoB,GAEpB,YAAY,GACZ,cAAc,GACd,cAAc,GAEd,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,eAAe,GACf,aAAa,GACb,cAAc,CAAC;AAMlB;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,UAAU,EAgBxC,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAKzD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACrC,gBAAgB,EAChB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CA4C5D,CAAC;AAeF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE,CAK/E;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,EAAE,CAQtE;AAWD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAEzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,CAoCvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAInE;AAID;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC3B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0EAA0E;IAC1E,YAAY,EAAE,UAAU,EAAE,CAAC;CAC3B"}
@@ -143,6 +143,9 @@ export function buildBuiltinRoleRows(organizationId) {
143
143
  * even if an admin accidentally locks their own role down.
144
144
  */
145
145
  const INSTANCE_ROLE_OVERRIDES = new Set(['super_admin', 'admin']);
146
+ export function isInstanceRole(auth) {
147
+ return auth.type === 'session' && INSTANCE_ROLE_OVERRIDES.has(auth.user.role);
148
+ }
146
149
  /**
147
150
  * Check whether an Auth already has a capability.
148
151
  *
@@ -7,6 +7,7 @@ import type { EmailAdapter } from '../email/index.js';
7
7
  import type { GraphQLConfig } from '../graphql/index.js';
8
8
  import type { AphexEnv } from '../server/api/index.js';
9
9
  import type { SchemaType } from './schemas.js';
10
+ import type { Logger } from '../utils/logger.js';
10
11
  export type { GraphQLConfig };
11
12
  export interface CMSConfig {
12
13
  schemaTypes: SchemaType[];
@@ -32,9 +33,23 @@ export interface CMSConfig {
32
33
  */
33
34
  graphql?: boolean | GraphQLConfig;
34
35
  /**
35
- * Log level for CMS output. Defaults to 'debug' in dev, 'warn' in production.
36
+ * Log level for the built-in console logger. Defaults to 'debug' in dev, 'warn' in production.
37
+ * Ignored when a custom `logger` is provided.
36
38
  */
37
39
  logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';
40
+ /**
41
+ * Custom logger instance (e.g. pino). Must implement debug/info/warn/error.
42
+ * When provided, replaces the built-in console logger entirely.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * import pino from 'pino';
47
+ * export default createCMSConfig({
48
+ * logger: pino({ level: 'info' }),
49
+ * });
50
+ * ```
51
+ */
52
+ logger?: Logger;
38
53
  auth?: {
39
54
  provider: AuthProvider;
40
55
  loginUrl?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/types/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,MAAM,WAAW,SAAS;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QACf,QAAQ,CAAC,EAAE;YACV,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,KAAK,CAAC,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC/B,CAAC;KACF,CAAC;IACF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACxD,IAAI,CAAC,EAAE;QACN,QAAQ,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,CAAC,EAAE;QACV;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;CACpC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/types/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,MAAM,WAAW,SAAS;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QACf,QAAQ,CAAC,EAAE;YACV,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,KAAK,CAAC,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC/B,CAAC;KACF,CAAC;IACF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACxD;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACN,QAAQ,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,CAAC,EAAE;QACV;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;CACpC"}
@@ -1,9 +1,11 @@
1
1
  export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
2
+ export interface Logger {
3
+ debug(...args: any[]): void;
4
+ info(...args: any[]): void;
5
+ warn(...args: any[]): void;
6
+ error(...args: any[]): void;
7
+ }
2
8
  export declare function setLogLevel(level: LogLevel): void;
3
- export declare const cmsLogger: {
4
- debug: (...args: any[]) => void;
5
- info: (...args: any[]) => void;
6
- warn: (...args: any[]) => void;
7
- error: (...args: any[]) => void;
8
- };
9
+ export declare function setLogger(logger: Logger): void;
10
+ export declare const cmsLogger: Logger;
9
11
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAQpE,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,QAE1C;AAoBD,eAAO,MAAM,SAAS;qBAjBJ,GAAG,EAAE;oBAAL,GAAG,EAAE;oBAAL,GAAG,EAAE;qBAAL,GAAG,EAAE;CAsBtB,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpE,MAAM,WAAW,MAAM;IACtB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC5B;AAOD,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,QAE1C;AA6BD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,QAEvC;AAED,eAAO,MAAM,SAAS,EAAE,MAKvB,CAAC"}
@@ -1,5 +1,4 @@
1
1
  const LEVELS = { debug: 0, info: 1, warn: 2, error: 3, none: 4 };
2
- // Default based on environment; overridden by CMSConfig.logLevel via setLogLevel()
3
2
  let currentLevel = typeof process !== 'undefined' && process.env?.NODE_ENV === 'production' ? 'warn' : 'debug';
4
3
  export function setLogLevel(level) {
5
4
  currentLevel = level;
@@ -21,9 +20,19 @@ function createMethod(level, consoleFn) {
21
20
  }
22
21
  };
23
22
  }
24
- export const cmsLogger = {
23
+ const defaultLogger = {
25
24
  debug: createMethod('debug', console.log),
26
25
  info: createMethod('info', console.log),
27
26
  warn: createMethod('warn', console.warn),
28
27
  error: createMethod('error', console.error)
29
28
  };
29
+ let activeLogger = defaultLogger;
30
+ export function setLogger(logger) {
31
+ activeLogger = logger;
32
+ }
33
+ export const cmsLogger = {
34
+ debug: (...args) => activeLogger.debug(...args),
35
+ info: (...args) => activeLogger.info(...args),
36
+ warn: (...args) => activeLogger.warn(...args),
37
+ error: (...args) => activeLogger.error(...args)
38
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"mime-detect.d.ts","sourceRoot":"","sources":["../../src/lib/utils/mime-detect.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuG5D;AAgED,MAAM,WAAW,qBAAqB;IACrC,oHAAoH;IACpH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,qBAA0B,GACjC,oBAAoB,CA8EtB"}
1
+ {"version":3,"file":"mime-detect.d.ts","sourceRoot":"","sources":["../../src/lib/utils/mime-detect.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuG5D;AA2ED,MAAM,WAAW,qBAAqB;IACrC,oHAAoH;IACpH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,qBAA0B,GACjC,oBAAoB,CAkFtB"}
@@ -110,7 +110,11 @@ const BLOCKED_MIME_TYPES = new Set([
110
110
  'application/x-shellscript',
111
111
  'application/wasm',
112
112
  'application/x-msdos-program',
113
- 'application/x-msdownload'
113
+ 'application/x-msdownload',
114
+ 'text/html',
115
+ 'application/xhtml+xml',
116
+ 'text/xml',
117
+ 'application/xml'
114
118
  ]);
115
119
  /**
116
120
  * Blocked file extensions (regardless of MIME type).
@@ -144,18 +148,29 @@ const BLOCKED_EXTENSIONS = new Set([
144
148
  '.reg',
145
149
  '.inf',
146
150
  '.hta',
147
- '.wasm'
151
+ '.wasm',
152
+ '.html',
153
+ '.htm',
154
+ '.xhtml',
155
+ '.shtml',
156
+ '.xml',
157
+ '.xsl',
158
+ '.mhtml'
148
159
  ]);
149
160
  /**
150
161
  * Validate an uploaded file's actual content against allowed types.
151
162
  * Checks magic bytes, not just the client-provided MIME type.
152
163
  */
153
164
  export function validateFile(buffer, filename, clientMimeType, options = {}) {
154
- const ext = filename.toLowerCase().substring(filename.lastIndexOf('.'));
165
+ const lowerName = filename.toLowerCase();
166
+ const ext = lowerName.substring(lowerName.lastIndexOf('.'));
155
167
  const detectedMimeType = detectMimeType(buffer);
156
- // 1. Block dangerous extensions
157
- if (BLOCKED_EXTENSIONS.has(ext)) {
158
- return { valid: false, error: `File type "${ext}" is not allowed`, detectedMimeType };
168
+ // 1. Block dangerous extensions (check all extensions to prevent double-extension bypass)
169
+ const allExts = lowerName.match(/\.[^.]+/g) || [];
170
+ for (const e of allExts) {
171
+ if (BLOCKED_EXTENSIONS.has(e)) {
172
+ return { valid: false, error: `File type "${e}" is not allowed`, detectedMimeType };
173
+ }
159
174
  }
160
175
  // 2. Block dangerous MIME types (detected from actual content)
161
176
  if (detectedMimeType && BLOCKED_MIME_TYPES.has(detectedMimeType)) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/vite/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAElD,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,8DAA8D;IAC9D,GAAG,CAAC,EAAE,eAAe,GAAG,KAAK,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yDAAyD;IACzD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,MAAM,CAiF9D;AAiJD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,MAAM,EAAE,CAoB1D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/vite/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAElD,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,8DAA8D;IAC9D,GAAG,CAAC,EAAE,eAAe,GAAG,KAAK,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yDAAyD;IACzD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,MAAM,CAiF9D;AAgJD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,MAAM,EAAE,CAoB1D"}
@@ -105,7 +105,9 @@ function aphexDayjsAlias() {
105
105
  name: 'aphex:dayjs-alias',
106
106
  config() {
107
107
  const dayjsEsm = require.resolve('dayjs/esm/index.js');
108
- const dayjsEsmPluginDir = dayjsEsm.replace(/\/index\.js$/, '/plugin');
108
+ const dayjsEsmPluginDir = dayjsEsm
109
+ .replace(/\\index\.js$/, '\\plugin')
110
+ .replace(/\/index\.js$/, '/plugin');
109
111
  return {
110
112
  resolve: {
111
113
  alias: [
@@ -219,10 +221,7 @@ function aphexWatchUnfilter() {
219
221
  return {
220
222
  server: {
221
223
  watch: {
222
- ignored: [
223
- '!**/node_modules/@aphexcms/cms-core/**',
224
- '!**/node_modules/@aphexcms/ui/**'
225
- ]
224
+ ignored: ['!**/node_modules/@aphexcms/cms-core/**', '!**/node_modules/@aphexcms/ui/**']
226
225
  }
227
226
  }
228
227
  };