@lilaquadrat/studio 10.0.0-beta.9 → 10.1.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 (244) hide show
  1. package/eslint.config.js +146 -0
  2. package/lib/fastify-plugins.d.ts +6 -0
  3. package/lib/fastify-plugins.js +7 -0
  4. package/lib/fastify-plugins.js.map +1 -0
  5. package/lib/helpers.d.ts +4 -2
  6. package/lib/helpers.js +13 -2
  7. package/lib/helpers.js.map +1 -1
  8. package/lib/main.d.ts +1 -3
  9. package/lib/main.js +7 -3
  10. package/lib/main.js.map +1 -1
  11. package/lib/models.d.ts +4 -4
  12. package/lib/models.js +4 -4
  13. package/lib/models.js.map +1 -1
  14. package/lib/services.d.ts +5 -5
  15. package/lib/services.js +5 -13
  16. package/lib/services.js.map +1 -1
  17. package/lib/src/Immutable.class.d.ts +8 -1
  18. package/lib/src/Immutable.class.js +52 -8
  19. package/lib/src/Immutable.class.js.map +1 -1
  20. package/lib/src/ShareClientFactory.class.d.ts +1 -3
  21. package/lib/src/ShareClientFactory.class.js +1 -9
  22. package/lib/src/ShareClientFactory.class.js.map +1 -1
  23. package/lib/src/classes/models.class.js.map +1 -1
  24. package/lib/src/classes/modelv2.class.d.ts +2 -0
  25. package/lib/src/classes/modelv2.class.js +1 -1
  26. package/lib/src/classes/modelv2.class.js.map +1 -1
  27. package/lib/src/classes/mongo.class.js +4 -14
  28. package/lib/src/classes/mongo.class.js.map +1 -1
  29. package/lib/src/functions/handleError.d.ts +2 -3
  30. package/lib/src/functions/handleError.js +3 -16
  31. package/lib/src/functions/handleError.js.map +1 -1
  32. package/lib/src/functions/optionsHelper.d.ts +4 -4
  33. package/lib/src/functions/optionsHelper.js +5 -4
  34. package/lib/src/functions/optionsHelper.js.map +1 -1
  35. package/lib/src/functions/respondCode.d.ts +2 -1
  36. package/lib/src/functions/respondCode.js +1 -1
  37. package/lib/src/functions/respondCode.js.map +1 -1
  38. package/lib/src/helpers/ControllerHelper.d.ts +73 -0
  39. package/lib/src/helpers/ControllerHelper.js +242 -0
  40. package/lib/src/helpers/ControllerHelper.js.map +1 -0
  41. package/lib/src/helpers/EnvMapper.js +1 -0
  42. package/lib/src/helpers/EnvMapper.js.map +1 -0
  43. package/lib/src/helpers/auth0config.d.ts +6 -0
  44. package/lib/src/helpers/auth0config.js +23 -0
  45. package/lib/src/helpers/auth0config.js.map +1 -0
  46. package/lib/src/helpers/authPlugin.d.ts +29 -0
  47. package/lib/src/helpers/authPlugin.js +77 -0
  48. package/lib/src/helpers/authPlugin.js.map +1 -0
  49. package/lib/src/helpers/cacheHelper.d.ts +69 -0
  50. package/lib/src/helpers/cacheHelper.js +235 -0
  51. package/lib/src/helpers/cacheHelper.js.map +1 -0
  52. package/lib/src/helpers/createSasToken.d.ts +0 -2
  53. package/lib/src/helpers/createSasToken.js +35 -32
  54. package/lib/src/helpers/createSasToken.js.map +1 -1
  55. package/lib/src/helpers/getSecrets.d.ts +1 -1
  56. package/lib/src/helpers/getSecrets.js +10 -12
  57. package/lib/src/helpers/getSecrets.js.map +1 -1
  58. package/lib/src/helpers/limiterPlugin.d.ts +9 -0
  59. package/lib/src/helpers/limiterPlugin.js +72 -0
  60. package/lib/src/helpers/limiterPlugin.js.map +1 -0
  61. package/lib/src/helpers/loggingPlugin.d.ts +30 -0
  62. package/lib/src/helpers/loggingPlugin.js +87 -0
  63. package/lib/src/helpers/loggingPlugin.js.map +1 -0
  64. package/lib/src/helpers/queryAssertionPlugin.d.ts +3 -0
  65. package/lib/src/helpers/queryAssertionPlugin.js +20 -0
  66. package/lib/src/helpers/queryAssertionPlugin.js.map +1 -0
  67. package/lib/src/helpers/safeObjectId.d.ts +1 -1
  68. package/lib/src/helpers/safeObjectId.js +5 -1
  69. package/lib/src/helpers/safeObjectId.js.map +1 -1
  70. package/lib/src/helpers/storageSdkFactory.d.ts +2 -0
  71. package/lib/src/helpers/storageSdkFactory.js +11 -0
  72. package/lib/src/helpers/storageSdkFactory.js.map +1 -0
  73. package/lib/src/helpers/studioAppPlugin.d.ts +3 -0
  74. package/lib/src/helpers/studioAppPlugin.js +16 -0
  75. package/lib/src/helpers/studioAppPlugin.js.map +1 -0
  76. package/lib/src/logger.js +40 -2
  77. package/lib/src/logger.js.map +1 -1
  78. package/lib/src/models/access.model.d.ts +14 -3
  79. package/lib/src/models/access.model.js +7 -9
  80. package/lib/src/models/access.model.js.map +1 -1
  81. package/lib/src/models/customers.model.js +14 -4
  82. package/lib/src/models/customers.model.js.map +1 -1
  83. package/lib/src/models/design.model.d.ts +4 -0
  84. package/lib/src/models/design.model.js +58 -0
  85. package/lib/src/models/design.model.js.map +1 -0
  86. package/lib/src/models/domain.model.js +1 -1
  87. package/lib/src/models/domain.model.js.map +1 -1
  88. package/lib/src/models/editor.model.js +7 -0
  89. package/lib/src/models/editor.model.js.map +1 -1
  90. package/lib/src/models/emailLimit.model.d.ts +4 -0
  91. package/lib/src/models/emailLimit.model.js +31 -0
  92. package/lib/src/models/emailLimit.model.js.map +1 -0
  93. package/lib/src/models/hosting.model.js +1 -3
  94. package/lib/src/models/hosting.model.js.map +1 -1
  95. package/lib/src/models/hostingSettings.model.js +6 -4
  96. package/lib/src/models/hostingSettings.model.js.map +1 -1
  97. package/lib/src/models/invoice.model.d.ts +4 -0
  98. package/lib/src/models/invoice.model.js +235 -0
  99. package/lib/src/models/invoice.model.js.map +1 -0
  100. package/lib/src/models/mailFrom.model.js +51 -10
  101. package/lib/src/models/mailFrom.model.js.map +1 -1
  102. package/lib/src/models/project.model.js +2 -4
  103. package/lib/src/models/project.model.js.map +1 -1
  104. package/lib/src/models/publish-method.model.js +79 -430
  105. package/lib/src/models/publish-method.model.js.map +1 -1
  106. package/lib/src/models/publish.model.js +6 -0
  107. package/lib/src/models/publish.model.js.map +1 -1
  108. package/lib/src/models/storage.model.js +23 -5
  109. package/lib/src/models/storage.model.js.map +1 -1
  110. package/lib/src/models/structure.model.js +40 -0
  111. package/lib/src/models/structure.model.js.map +1 -1
  112. package/lib/src/models/upload.model.js +38 -2
  113. package/lib/src/models/upload.model.js.map +1 -1
  114. package/lib/src/prompts/textGeneration.js +88 -0
  115. package/lib/src/prompts/textGeneration.js.map +1 -1
  116. package/lib/src/prompts/textGenerationMulti.js +78 -44
  117. package/lib/src/prompts/textGenerationMulti.js.map +1 -1
  118. package/lib/src/services/access.service.d.ts +132 -33
  119. package/lib/src/services/access.service.js +270 -92
  120. package/lib/src/services/access.service.js.map +1 -1
  121. package/lib/src/services/ai.service.d.ts +4 -3
  122. package/lib/src/services/ai.service.js +22 -29
  123. package/lib/src/services/ai.service.js.map +1 -1
  124. package/lib/src/services/auth.service.d.ts +11 -0
  125. package/lib/src/services/auth.service.js +70 -0
  126. package/lib/src/services/auth.service.js.map +1 -0
  127. package/lib/src/services/conf.service.d.ts +3 -31
  128. package/lib/src/services/conf.service.js +58 -167
  129. package/lib/src/services/conf.service.js.map +1 -1
  130. package/lib/src/services/customers.service.d.ts +8 -4
  131. package/lib/src/services/customers.service.js +34 -7
  132. package/lib/src/services/customers.service.js.map +1 -1
  133. package/lib/src/services/designs.service.d.ts +7 -0
  134. package/lib/src/services/designs.service.js +10 -0
  135. package/lib/src/services/designs.service.js.map +1 -0
  136. package/lib/src/services/domains.service.d.ts +18 -84
  137. package/lib/src/services/domains.service.js +91 -583
  138. package/lib/src/services/domains.service.js.map +1 -1
  139. package/lib/src/services/editor.service.d.ts +4 -0
  140. package/lib/src/services/editor.service.js +28 -0
  141. package/lib/src/services/editor.service.js.map +1 -1
  142. package/lib/src/services/emailLimit.service.d.ts +21 -0
  143. package/lib/src/services/emailLimit.service.js +51 -0
  144. package/lib/src/services/emailLimit.service.js.map +1 -0
  145. package/lib/src/services/hosting.service.d.ts +12 -24
  146. package/lib/src/services/hosting.service.js +32 -122
  147. package/lib/src/services/hosting.service.js.map +1 -1
  148. package/lib/src/services/hostingAdmin.service.d.ts +1 -1
  149. package/lib/src/services/hostingAdmin.service.js +2 -2
  150. package/lib/src/services/hostingAdmin.service.js.map +1 -1
  151. package/lib/src/services/import.service.d.ts +6 -22
  152. package/lib/src/services/import.service.js +63 -65
  153. package/lib/src/services/import.service.js.map +1 -1
  154. package/lib/src/services/invoices.service.d.ts +30 -0
  155. package/lib/src/services/invoices.service.js +265 -0
  156. package/lib/src/services/invoices.service.js.map +1 -0
  157. package/lib/src/services/jetstream.service.d.ts +5 -3
  158. package/lib/src/services/jetstream.service.js +63 -7
  159. package/lib/src/services/jetstream.service.js.map +1 -1
  160. package/lib/src/services/listParticipants.service.d.ts +3 -5
  161. package/lib/src/services/listParticipants.service.js +76 -16
  162. package/lib/src/services/listParticipants.service.js.map +1 -1
  163. package/lib/src/services/mailFrom.service.d.ts +14 -1
  164. package/lib/src/services/mailFrom.service.js +59 -0
  165. package/lib/src/services/mailFrom.service.js.map +1 -1
  166. package/lib/src/services/me.service.d.ts +23 -12
  167. package/lib/src/services/me.service.js +65 -88
  168. package/lib/src/services/me.service.js.map +1 -1
  169. package/lib/src/services/publish.service.d.ts +6 -8
  170. package/lib/src/services/publish.service.js +34 -32
  171. package/lib/src/services/publish.service.js.map +1 -1
  172. package/lib/src/services/publishData.service.d.ts +10 -7
  173. package/lib/src/services/publishData.service.js +32 -75
  174. package/lib/src/services/publishData.service.js.map +1 -1
  175. package/lib/src/services/spamAnalasys.service.d.ts +4 -4
  176. package/lib/src/services/spamAnalasys.service.js +36 -44
  177. package/lib/src/services/spamAnalasys.service.js.map +1 -1
  178. package/lib/src/services/storage.service.d.ts +68 -39
  179. package/lib/src/services/storage.service.js +382 -209
  180. package/lib/src/services/storage.service.js.map +1 -1
  181. package/lib/src/services/structures.service.d.ts +8 -1
  182. package/lib/src/services/structures.service.js +26 -1
  183. package/lib/src/services/structures.service.js.map +1 -1
  184. package/lib/src/services/upload.service.d.ts +8 -1
  185. package/lib/src/services/upload.service.js +76 -3
  186. package/lib/src/services/upload.service.js.map +1 -1
  187. package/lib/tests/groupStructuresByModel.spec.d.ts +1 -0
  188. package/lib/tests/groupStructuresByModel.spec.js +33 -0
  189. package/lib/tests/groupStructuresByModel.spec.js.map +1 -0
  190. package/lib/tests/listParticipantsServiceJoin.spec.d.ts +1 -0
  191. package/lib/tests/listParticipantsServiceJoin.spec.js +151 -0
  192. package/lib/tests/listParticipantsServiceJoin.spec.js.map +1 -0
  193. package/lib/tests/storageServiceHandleFile.spec.d.ts +1 -0
  194. package/lib/tests/storageServiceHandleFile.spec.js +94 -0
  195. package/lib/tests/storageServiceHandleFile.spec.js.map +1 -0
  196. package/lib/tests/storageServiceToken.spec.d.ts +1 -0
  197. package/lib/tests/storageServiceToken.spec.js +104 -0
  198. package/lib/tests/storageServiceToken.spec.js.map +1 -0
  199. package/lib/tests/uploadServiceCreate.spec.d.ts +1 -0
  200. package/lib/tests/uploadServiceCreate.spec.js +81 -0
  201. package/lib/tests/uploadServiceCreate.spec.js.map +1 -0
  202. package/package.json +30 -26
  203. package/lib/src/AzureBlobStorage.share.d.ts +0 -19
  204. package/lib/src/AzureBlobStorage.share.js +0 -162
  205. package/lib/src/AzureBlobStorage.share.js.map +0 -1
  206. package/lib/src/AzureFileStorage.share.d.ts +0 -22
  207. package/lib/src/AzureFileStorage.share.js +0 -139
  208. package/lib/src/AzureFileStorage.share.js.map +0 -1
  209. package/lib/src/AzureVault.d.ts +0 -14
  210. package/lib/src/AzureVault.js +0 -28
  211. package/lib/src/AzureVault.js.map +0 -1
  212. package/lib/src/dns.challenge.class.d.ts +0 -17
  213. package/lib/src/dns.challenge.class.js +0 -41
  214. package/lib/src/dns.challenge.class.js.map +0 -1
  215. package/lib/src/http.challenge.class.d.ts +0 -33
  216. package/lib/src/http.challenge.class.js +0 -58
  217. package/lib/src/http.challenge.class.js.map +0 -1
  218. package/lib/src/models/certificate-action.model.d.ts +0 -5
  219. package/lib/src/models/certificate-action.model.js +0 -230
  220. package/lib/src/models/certificate-action.model.js.map +0 -1
  221. package/lib/src/models/certificate.model.d.ts +0 -4
  222. package/lib/src/models/certificate.model.js +0 -96
  223. package/lib/src/models/certificate.model.js.map +0 -1
  224. package/lib/src/models/editorBase.model.d.ts +0 -4
  225. package/lib/src/models/editorBase.model.js +0 -39
  226. package/lib/src/models/editorBase.model.js.map +0 -1
  227. package/lib/src/services/certificates.service.js +0 -199
  228. package/lib/src/services/certificates.service.js.map +0 -1
  229. package/lib/src/services/certificatesAction.service.d.ts +0 -0
  230. package/lib/src/services/certificatesAction.service.js +0 -237
  231. package/lib/src/services/certificatesAction.service.js.map +0 -1
  232. package/lib/src/services/editorBase.service.d.ts +0 -46
  233. package/lib/src/services/editorBase.service.js +0 -161
  234. package/lib/src/services/editorBase.service.js.map +0 -1
  235. package/lib/src/services/handleFile.service.d.ts +0 -9
  236. package/lib/src/services/handleFile.service.js +0 -45
  237. package/lib/src/services/handleFile.service.js.map +0 -1
  238. package/lib/src/services/media.service.d.ts +0 -35
  239. package/lib/src/services/media.service.js +0 -418
  240. package/lib/src/services/media.service.js.map +0 -1
  241. package/lib/src/services/share.service.d.ts +0 -6
  242. package/lib/src/services/share.service.js +0 -4
  243. package/lib/src/services/share.service.js.map +0 -1
  244. /package/lib/src/{services/certificates.service.d.ts → helpers/EnvMapper.d.ts} +0 -0
@@ -0,0 +1,77 @@
1
+ import { promisify } from 'node:util';
2
+ import fp from 'fastify-plugin';
3
+ import fastifyJwt from '@fastify/jwt';
4
+ import jwksRsa from 'jwks-rsa';
5
+ import respondCode from '../functions/respondCode.js';
6
+ import auth0config from './auth0config.js';
7
+ const authPlugin = async (fastify) => {
8
+ if (process.env.ENV !== 'dev') {
9
+ // Per-domain JWKS client cache to avoid re-creating clients on every request
10
+ const jwksClients = new Map();
11
+ const getJwksClient = (jwksUri) => {
12
+ if (!jwksClients.has(jwksUri)) {
13
+ jwksClients.set(jwksUri, jwksRsa({
14
+ cache: true,
15
+ cacheMaxEntries: 5,
16
+ cacheMaxAge: 600000, // 10 minutes in ms
17
+ rateLimit: true,
18
+ jwksRequestsPerMinute: 10,
19
+ jwksUri,
20
+ }));
21
+ }
22
+ return jwksClients.get(jwksUri);
23
+ };
24
+ // Production: Register JWT with JWKS
25
+ await fastify.register(fastifyJwt, {
26
+ decode: { complete: true },
27
+ secret: async (request, token) => {
28
+ const header = 'header' in token ? token.header : token;
29
+ const app = request.studioApp ?? 'editor-app';
30
+ const settings = await auth0config(app);
31
+ request.customApp = settings.custom;
32
+ const jwksUri = settings.url;
33
+ const client = getJwksClient(jwksUri);
34
+ const key = await promisify(client.getSigningKey.bind(client))(header.kid);
35
+ return key.getPublicKey();
36
+ },
37
+ verify: {
38
+ algorithms: ['RS256']
39
+ }
40
+ });
41
+ // Decorate with authenticate method for production
42
+ fastify.decorate('authenticate', async (request, reply) => {
43
+ try {
44
+ await request.jwtVerify();
45
+ request.auth = request.user;
46
+ }
47
+ catch (err) {
48
+ return respondCode("UNAUTHORIZED", reply);
49
+ }
50
+ });
51
+ }
52
+ else {
53
+ // Dev: Mock authentication
54
+ fastify.decorate('authenticate', async (request, reply) => {
55
+ request.auth = {
56
+ sub: process.env.DEV_USER,
57
+ given_name: 'Dev',
58
+ family_name: 'User',
59
+ nickname: 'devuser',
60
+ name: 'Dev User',
61
+ picture: '',
62
+ updated_at: new Date().toISOString(),
63
+ iss: 'dev',
64
+ aud: 'dev',
65
+ iat: Math.floor(Date.now() / 1000),
66
+ exp: Math.floor(Date.now() / 1000) + 3600,
67
+ at_hash: '',
68
+ nonce: '',
69
+ email_verified: true
70
+ };
71
+ });
72
+ }
73
+ };
74
+ export default fp(authPlugin, {
75
+ name: 'auth-plugin'
76
+ });
77
+ //# sourceMappingURL=authPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authPlugin.js","sourceRoot":"","sources":["../../../src/helpers/authPlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Cache duration constants (in seconds)
3
+ */
4
+ export declare const CacheDuration: {
5
+ /** 1 year - for immutable/versioned assets */
6
+ readonly IMMUTABLE: 31536000;
7
+ /** 1 month - for stable assets */
8
+ readonly LONG: 2592000;
9
+ /** 1 week - for semi-stable assets */
10
+ readonly MEDIUM: 604800;
11
+ /** 1 day - for frequently updated assets */
12
+ readonly SHORT: 86400;
13
+ /** 1 hour - for dynamic content */
14
+ readonly DYNAMIC: 3600;
15
+ /** No cache - for always fresh content */
16
+ readonly NONE: 0;
17
+ };
18
+ /**
19
+ * Cache helper class for managing HTTP cache headers and durations
20
+ *
21
+ * @example
22
+ * // Get cache duration
23
+ * const duration = CacheHelper.getCacheDuration('image/jpeg'); // 2592000
24
+ *
25
+ * @example
26
+ * // Build cache control header
27
+ * const header = CacheHelper.buildCacheControlHeader('image/jpeg');
28
+ * // "public, max-age=2592000, stale-while-revalidate=86400"
29
+ *
30
+ * @example
31
+ * // Get full config
32
+ * const config = CacheHelper.getCacheConfig('font/woff2');
33
+ * // { cache: 31536000, immutable: true }
34
+ */
35
+ export default class CacheHelper {
36
+ /**
37
+ * Get cache configuration for a given mime type
38
+ *
39
+ * @param mimeType - The mime type to get configuration for
40
+ * @returns Cache configuration object
41
+ */
42
+ static getCacheConfig(mimeType: string): {
43
+ cache: number;
44
+ immutable?: boolean;
45
+ staleWhileRevalidate?: number;
46
+ };
47
+ /**
48
+ * Get cache duration in seconds for a given mime type
49
+ *
50
+ * @param mimeType - The mime type to get cache duration for
51
+ * @returns Cache duration in seconds
52
+ *
53
+ * @example
54
+ * const cacheTime = CacheHelper.getCacheDuration('image/jpeg'); // Returns 2592000 (1 month)
55
+ * const cacheTime = CacheHelper.getCacheDuration('text/html'); // Returns 0 (no cache)
56
+ */
57
+ static getCacheDuration(mimeType: string): number;
58
+ /**
59
+ * Build Cache-Control header value for a given mime type
60
+ *
61
+ * @param mimeType - The mime type to build header for
62
+ * @returns Cache-Control header value
63
+ *
64
+ * @example
65
+ * const header = CacheHelper.buildCacheControlHeader('image/jpeg');
66
+ * // Returns: "public, max-age=2592000, stale-while-revalidate=86400"
67
+ */
68
+ static buildCacheControlHeader(mimeType: string): string;
69
+ }
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Cache duration constants (in seconds)
3
+ */
4
+ export const CacheDuration = {
5
+ /** 1 year - for immutable/versioned assets */
6
+ IMMUTABLE: 31536000,
7
+ /** 1 month - for stable assets */
8
+ LONG: 2592000,
9
+ /** 1 week - for semi-stable assets */
10
+ MEDIUM: 604800,
11
+ /** 1 day - for frequently updated assets */
12
+ SHORT: 86400,
13
+ /** 1 hour - for dynamic content */
14
+ DYNAMIC: 3600,
15
+ /** No cache - for always fresh content */
16
+ NONE: 0,
17
+ };
18
+ /**
19
+ * Mime type cache configuration
20
+ * Maps mime types to cache duration and other headers
21
+ */
22
+ const MimeCacheConfig = {
23
+ // HTML - no cache (always fetch fresh)
24
+ 'text/html': {
25
+ cache: CacheDuration.NONE,
26
+ },
27
+ // JSON/API responses - no cache
28
+ 'application/json': {
29
+ cache: CacheDuration.NONE,
30
+ },
31
+ // Images - long cache (1 month)
32
+ 'image/jpeg': {
33
+ cache: CacheDuration.LONG,
34
+ staleWhileRevalidate: CacheDuration.SHORT,
35
+ },
36
+ 'image/jpg': {
37
+ cache: CacheDuration.LONG,
38
+ staleWhileRevalidate: CacheDuration.SHORT,
39
+ },
40
+ 'image/png': {
41
+ cache: CacheDuration.LONG,
42
+ staleWhileRevalidate: CacheDuration.SHORT,
43
+ },
44
+ 'image/gif': {
45
+ cache: CacheDuration.LONG,
46
+ staleWhileRevalidate: CacheDuration.SHORT,
47
+ },
48
+ 'image/webp': {
49
+ cache: CacheDuration.LONG,
50
+ staleWhileRevalidate: CacheDuration.SHORT,
51
+ },
52
+ 'image/avif': {
53
+ cache: CacheDuration.LONG,
54
+ staleWhileRevalidate: CacheDuration.SHORT,
55
+ },
56
+ 'image/svg+xml': {
57
+ cache: CacheDuration.LONG,
58
+ staleWhileRevalidate: CacheDuration.SHORT,
59
+ },
60
+ // Videos - long cache
61
+ 'video/mp4': {
62
+ cache: CacheDuration.LONG,
63
+ },
64
+ 'video/webm': {
65
+ cache: CacheDuration.LONG,
66
+ },
67
+ 'video/ogg': {
68
+ cache: CacheDuration.LONG,
69
+ },
70
+ // Audio - long cache
71
+ 'audio/mpeg': {
72
+ cache: CacheDuration.LONG,
73
+ },
74
+ 'audio/mp3': {
75
+ cache: CacheDuration.LONG,
76
+ },
77
+ 'audio/wav': {
78
+ cache: CacheDuration.LONG,
79
+ },
80
+ 'audio/ogg': {
81
+ cache: CacheDuration.LONG,
82
+ },
83
+ // Fonts - immutable (1 year)
84
+ 'font/woff': {
85
+ cache: CacheDuration.IMMUTABLE,
86
+ immutable: true,
87
+ },
88
+ 'font/woff2': {
89
+ cache: CacheDuration.IMMUTABLE,
90
+ immutable: true,
91
+ },
92
+ 'font/ttf': {
93
+ cache: CacheDuration.IMMUTABLE,
94
+ immutable: true,
95
+ },
96
+ 'font/otf': {
97
+ cache: CacheDuration.IMMUTABLE,
98
+ immutable: true,
99
+ },
100
+ 'application/font-woff': {
101
+ cache: CacheDuration.IMMUTABLE,
102
+ immutable: true,
103
+ },
104
+ 'application/font-woff2': {
105
+ cache: CacheDuration.IMMUTABLE,
106
+ immutable: true,
107
+ },
108
+ // CSS/JS - long cache with stale-while-revalidate
109
+ 'text/css': {
110
+ cache: CacheDuration.LONG,
111
+ staleWhileRevalidate: CacheDuration.SHORT,
112
+ },
113
+ 'application/javascript': {
114
+ cache: CacheDuration.LONG,
115
+ staleWhileRevalidate: CacheDuration.SHORT,
116
+ },
117
+ 'text/javascript': {
118
+ cache: CacheDuration.LONG,
119
+ staleWhileRevalidate: CacheDuration.SHORT,
120
+ },
121
+ // Documents - medium cache
122
+ 'application/pdf': {
123
+ cache: CacheDuration.MEDIUM,
124
+ },
125
+ 'application/msword': {
126
+ cache: CacheDuration.MEDIUM,
127
+ },
128
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': {
129
+ cache: CacheDuration.MEDIUM,
130
+ },
131
+ 'application/vnd.ms-excel': {
132
+ cache: CacheDuration.MEDIUM,
133
+ },
134
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': {
135
+ cache: CacheDuration.MEDIUM,
136
+ },
137
+ // Archives - long cache
138
+ 'application/zip': {
139
+ cache: CacheDuration.LONG,
140
+ },
141
+ 'application/x-rar-compressed': {
142
+ cache: CacheDuration.LONG,
143
+ },
144
+ 'application/x-7z-compressed': {
145
+ cache: CacheDuration.LONG,
146
+ },
147
+ // Text files - short cache
148
+ 'text/plain': {
149
+ cache: CacheDuration.SHORT,
150
+ },
151
+ 'text/csv': {
152
+ cache: CacheDuration.SHORT,
153
+ },
154
+ // XML - no cache (often dynamic)
155
+ 'application/xml': {
156
+ cache: CacheDuration.NONE,
157
+ },
158
+ 'text/xml': {
159
+ cache: CacheDuration.NONE,
160
+ },
161
+ // Default fallback - 1 year cache for everything else
162
+ '*': {
163
+ cache: CacheDuration.IMMUTABLE,
164
+ },
165
+ };
166
+ /**
167
+ * Cache helper class for managing HTTP cache headers and durations
168
+ *
169
+ * @example
170
+ * // Get cache duration
171
+ * const duration = CacheHelper.getCacheDuration('image/jpeg'); // 2592000
172
+ *
173
+ * @example
174
+ * // Build cache control header
175
+ * const header = CacheHelper.buildCacheControlHeader('image/jpeg');
176
+ * // "public, max-age=2592000, stale-while-revalidate=86400"
177
+ *
178
+ * @example
179
+ * // Get full config
180
+ * const config = CacheHelper.getCacheConfig('font/woff2');
181
+ * // { cache: 31536000, immutable: true }
182
+ */
183
+ export default class CacheHelper {
184
+ /**
185
+ * Get cache configuration for a given mime type
186
+ *
187
+ * @param mimeType - The mime type to get configuration for
188
+ * @returns Cache configuration object
189
+ */
190
+ static getCacheConfig(mimeType) {
191
+ return MimeCacheConfig[mimeType] || MimeCacheConfig['*'];
192
+ }
193
+ /**
194
+ * Get cache duration in seconds for a given mime type
195
+ *
196
+ * @param mimeType - The mime type to get cache duration for
197
+ * @returns Cache duration in seconds
198
+ *
199
+ * @example
200
+ * const cacheTime = CacheHelper.getCacheDuration('image/jpeg'); // Returns 2592000 (1 month)
201
+ * const cacheTime = CacheHelper.getCacheDuration('text/html'); // Returns 0 (no cache)
202
+ */
203
+ static getCacheDuration(mimeType) {
204
+ const config = this.getCacheConfig(mimeType);
205
+ return config.cache;
206
+ }
207
+ /**
208
+ * Build Cache-Control header value for a given mime type
209
+ *
210
+ * @param mimeType - The mime type to build header for
211
+ * @returns Cache-Control header value
212
+ *
213
+ * @example
214
+ * const header = CacheHelper.buildCacheControlHeader('image/jpeg');
215
+ * // Returns: "public, max-age=2592000, stale-while-revalidate=86400"
216
+ */
217
+ static buildCacheControlHeader(mimeType) {
218
+ const config = this.getCacheConfig(mimeType);
219
+ const parts = [];
220
+ if (config.cache === 0) {
221
+ parts.push('no-cache', 'no-store', 'must-revalidate');
222
+ }
223
+ else {
224
+ parts.push('public', `max-age=${config.cache}`);
225
+ if (config.immutable) {
226
+ parts.push('immutable');
227
+ }
228
+ if (config.staleWhileRevalidate) {
229
+ parts.push(`stale-while-revalidate=${config.staleWhileRevalidate}`);
230
+ }
231
+ }
232
+ return parts.join(', ');
233
+ }
234
+ }
235
+ //# sourceMappingURL=cacheHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cacheHelper.js","sourceRoot":"","sources":["../../../src/helpers/cacheHelper.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { ShareClientOptions } from '@lilaquadrat/interfaces';
2
- export default function generateSasToken(accountName: string, containerName: string, blobName: string, expiresInHours: number, options: ShareClientOptions): Promise<string>;
@@ -1,33 +1,36 @@
1
- import { DefaultAzureCredential } from '@azure/identity';
2
- import { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions } from '@azure/storage-blob';
3
- export default async function generateSasToken(accountName, containerName, blobName, expiresInHours, options) {
4
- let serviceClient;
5
- if (options.accountName) {
6
- console.log('storage.blob.use.storage_account');
7
- const credentials = new DefaultAzureCredential();
8
- serviceClient = new BlobServiceClient(`https://${options.accountName}.blob.core.windows.net`, credentials);
9
- }
10
- else if (options.connectionString) {
11
- console.log('storage.blob.use.connection_string');
12
- serviceClient = new BlobServiceClient(options.connectionString);
13
- }
14
- if (!serviceClient)
15
- throw new Error('BLOB_CREDENTIALS_MISSING');
16
- // Get user delegation key
17
- const delegationKey = await serviceClient.getUserDelegationKey(new Date(), new Date(Date.now() + expiresInHours * 3600 * 1000));
18
- // Define SAS permissions (Read-only)
19
- const permissions = BlobSASPermissions.parse('r'); // Read-only access
20
- const isFolder = !blobName.includes('.');
21
- // Generate SAS token
22
- const sasToken = generateBlobSASQueryParameters({
23
- containerName,
24
- blobName: isFolder ? undefined : blobName,
25
- permissions,
26
- startsOn: new Date(),
27
- expiresOn: new Date(Date.now() + expiresInHours * 3600 * 1000), // Expire in specified hours
28
- }, delegationKey, accountName).toString();
29
- return sasToken;
30
- }
31
- // Usage example:
32
- // generateSasToken('yourStorageAccountName', 'yourContainerName', undefined, 2).then(console.log);
1
+ // import { DefaultAzureCredential } from '@azure/identity';
2
+ // import { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions } from '@azure/storage-blob';
3
+ // import { ShareClientOptions } from '@lilaquadrat/interfaces';
4
+ // export default async function generateSasToken(accountName: string, containerName: string, blobName: string, expiresInHours: number, options: ShareClientOptions) {
5
+ // let serviceClient: BlobServiceClient | undefined;
6
+ // if (options.accountName) {
7
+ // console.log('storage.blob.use.storage_account');
8
+ // const credentials = new DefaultAzureCredential();
9
+ // serviceClient = new BlobServiceClient(`https://${options.accountName}.blob.core.windows.net`, credentials);
10
+ // } else if (options.connectionString) {
11
+ // console.log('storage.blob.use.connection_string');
12
+ // serviceClient = new BlobServiceClient(options.connectionString);
13
+ // }
14
+ // if (!serviceClient) throw new Error('BLOB_CREDENTIALS_MISSING');
15
+ // // Get user delegation key
16
+ // const delegationKey = await serviceClient.getUserDelegationKey(new Date(), new Date(Date.now() + expiresInHours * 3600 * 1000));
17
+ // // Define SAS permissions (Read-only)
18
+ // const permissions = BlobSASPermissions.parse('r'); // Read-only access
19
+ // const isFolder = !blobName.includes('.');
20
+ // // Generate SAS token
21
+ // const sasToken = generateBlobSASQueryParameters(
22
+ // {
23
+ // containerName,
24
+ // blobName: isFolder ? undefined : blobName,
25
+ // permissions,
26
+ // startsOn: new Date(),
27
+ // expiresOn: new Date(Date.now() + expiresInHours * 3600 * 1000), // Expire in specified hours
28
+ // },
29
+ // delegationKey,
30
+ // accountName,
31
+ // ).toString();
32
+ // return sasToken;
33
+ // }
34
+ // // Usage example:
35
+ // // generateSasToken('yourStorageAccountName', 'yourContainerName', undefined, 2).then(console.log);
33
36
  //# sourceMappingURL=createSasToken.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createSasToken.js","sourceRoot":"","sources":["../../../src/helpers/createSasToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,8BAA8B,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG5G,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,gBAAgB,CAAC,WAAmB,EAAE,aAAqB,EAAE,QAAgB,EAAE,cAAsB,EAAE,OAA2B;IAE9J,IAAI,aAA4C,CAAC;IAEjD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QAExB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAEhD,MAAM,WAAW,GAAG,IAAI,sBAAsB,EAAE,CAAC;QACjD,aAAa,GAAG,IAAI,iBAAiB,CAAC,WAAW,OAAO,CAAC,WAAW,wBAAwB,EAAE,WAAW,CAAC,CAAC;IAE7G,CAAC;SAAM,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAEpC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,aAAa,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAElE,CAAC;IAED,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAEhE,0BAA0B;IAC1B,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,oBAAoB,CAAC,IAAI,IAAI,EAAE,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IAEhI,qCAAqC;IACrC,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB;IAEtE,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACzC,qBAAqB;IACrB,MAAM,QAAQ,GAAG,8BAA8B,CAC7C;QACE,aAAa;QACb,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;QACzC,WAAW;QACX,QAAQ,EAAE,IAAI,IAAI,EAAE;QACpB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC,EAAE,4BAA4B;KAC7F,EACD,aAAa,EACb,WAAW,CACZ,CAAC,QAAQ,EAAE,CAAC;IAEb,OAAO,QAAQ,CAAC;AAElB,CAAC;AAED,iBAAiB;AACjB,mGAAmG"}
1
+ {"version":3,"file":"createSasToken.js","sourceRoot":"","sources":["../../../src/helpers/createSasToken.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,+GAA+G;AAC/G,gEAAgE;AAEhE,sKAAsK;AAEtK,sDAAsD;AAEtD,+BAA+B;AAE/B,uDAAuD;AAEvD,wDAAwD;AACxD,kHAAkH;AAElH,2CAA2C;AAE3C,yDAAyD;AACzD,uEAAuE;AAEvE,MAAM;AAEN,qEAAqE;AAErE,+BAA+B;AAC/B,qIAAqI;AAErI,0CAA0C;AAC1C,2EAA2E;AAE3E,8CAA8C;AAC9C,0BAA0B;AAC1B,qDAAqD;AACrD,QAAQ;AACR,uBAAuB;AACvB,mDAAmD;AACnD,qBAAqB;AACrB,8BAA8B;AAC9B,qGAAqG;AACrG,SAAS;AACT,qBAAqB;AACrB,mBAAmB;AACnB,kBAAkB;AAElB,qBAAqB;AAErB,IAAI;AAEJ,oBAAoB;AACpB,sGAAsG"}
@@ -1,4 +1,4 @@
1
1
  declare const _default: (name: string, vaultUrl: string, options?: {
2
2
  base64: true;
3
- }) => Promise<string>;
3
+ }) => Promise<void>;
4
4
  export default _default;
@@ -1,15 +1,13 @@
1
- import { DefaultAzureCredential } from '@azure/identity';
2
- import AzureVault from '../AzureVault.js';
1
+ // import { DefaultAzureCredential } from '@azure/identity';
2
+ // import AzureVault from '../AzureVault.js';
3
3
  export default async (name, vaultUrl, options) => {
4
- const credentials = new DefaultAzureCredential();
5
- const secret = await AzureVault.secrets.get(name, vaultUrl, credentials);
6
- if (!secret.value)
7
- return '';
8
- if (options?.base64) {
9
- return Buffer.from(secret.value, 'base64').toString('ascii');
10
- }
11
- else {
12
- return secret.value;
13
- }
4
+ // const credentials = new DefaultAzureCredential();
5
+ // const secret = await AzureVault.secrets.get(name, vaultUrl, credentials);
6
+ // if (!secret.value) return '';
7
+ // if (options?.base64) {
8
+ // return Buffer.from(secret.value, 'base64').toString('ascii');
9
+ // } else {
10
+ // return secret.value;
11
+ // }
14
12
  };
15
13
  //# sourceMappingURL=getSecrets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getSecrets.js","sourceRoot":"","sources":["../../../src/helpers/getSecrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAE1C,eAAe,KAAK,EAAE,IAAY,EAAE,QAAgB,EAAE,OAA0B,EAAE,EAAE;IAElF,MAAM,WAAW,GAAG,IAAI,sBAAsB,EAAE,CAAC;IAEjD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACzE,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAE7B,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QAEpB,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE/D,CAAC;SAAM,CAAC;QAEN,OAAO,MAAM,CAAC,KAAK,CAAC;IAEtB,CAAC;AAEH,CAAC,CAAC"}
1
+ {"version":3,"file":"getSecrets.js","sourceRoot":"","sources":["../../../src/helpers/getSecrets.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,6CAA6C;AAE7C,eAAe,KAAK,EAAE,IAAY,EAAE,QAAgB,EAAE,OAA0B,EAAE,EAAE;IAElF,oDAAoD;IAEpD,4EAA4E;IAC5E,gCAAgC;IAEhC,yBAAyB;IAEzB,kEAAkE;IAElE,WAAW;IAEX,yBAAyB;IAEzB,IAAI;AAEN,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { FastifyPluginAsync } from 'fastify';
2
+ import { type LimiterTier, type LimiterPluginOptions } from '@lilaquadrat/interfaces';
3
+ declare module 'fastify' {
4
+ interface FastifyContextConfig {
5
+ rateLimit?: LimiterTier | false;
6
+ }
7
+ }
8
+ declare const _default: FastifyPluginAsync<LimiterPluginOptions>;
9
+ export default _default;
@@ -0,0 +1,72 @@
1
+ import fp from 'fastify-plugin';
2
+ import AccessService from '../services/access.service.js';
3
+ const limiterPlugin = async (fastify, opts) => {
4
+ const ignore = new Set(opts.ignoreRoutes ?? ['/health', '/']);
5
+ const skipOnError = opts.skipOnError ?? true;
6
+ const overrides = (opts.overrides ?? [])
7
+ .slice()
8
+ .sort((a, b) => b.prefix.length - a.prefix.length);
9
+ const resolveTier = (request) => {
10
+ const routeCfg = request.routeOptions?.config?.rateLimit;
11
+ if (routeCfg === false)
12
+ return { tier: {}, kind: 'user' };
13
+ if (routeCfg)
14
+ return { tier: routeCfg, kind: request.url.startsWith('/public/') ? 'public' : 'user' };
15
+ const url = request.url;
16
+ for (const o of overrides) {
17
+ if (url.startsWith(o.prefix)) {
18
+ const kind = o.prefix.startsWith('/public/') ? 'public' : o.prefix.startsWith('/members/') ? 'members' : 'user';
19
+ return { tier: o.tier, kind };
20
+ }
21
+ }
22
+ if (url.startsWith('/public/'))
23
+ return { tier: opts.tiers.public, kind: 'public' };
24
+ if (url.startsWith('/members/'))
25
+ return { tier: opts.tiers.members, kind: 'members' };
26
+ return { tier: opts.tiers.user, kind: 'user' };
27
+ };
28
+ const resolveKey = (request, kind) => {
29
+ if (kind === 'public')
30
+ return `${opts.namespace}:ip:${request.ip}`;
31
+ const sub = request.auth?.sub;
32
+ if (sub)
33
+ return `${opts.namespace}:user:${sub}`;
34
+ return `${opts.namespace}:ip:${request.ip}`;
35
+ };
36
+ fastify.addHook('preHandler', async (request, reply) => {
37
+ if (ignore.has(request.url))
38
+ return;
39
+ const { tier, kind } = resolveTier(request);
40
+ if (!tier.minute && !tier.hour)
41
+ return;
42
+ const key = resolveKey(request, kind);
43
+ try {
44
+ const breach = await AccessService.hit(key, tier);
45
+ if (!breach)
46
+ return;
47
+ // Headers we can set reliably:
48
+ // Retry-After — RFC 9110, seconds until window reset
49
+ // RateLimit-Limit — IETF draft, configured limit (always exact)
50
+ // RateLimit-Reset — IETF draft, seconds until window reset
51
+ // RateLimit-Policy — IETF draft, describes the policy window
52
+ // We intentionally OMIT RateLimit-Remaining because the LRU cache
53
+ // makes the live count unreliable for reporting (correct for limit
54
+ // enforcement, lagging for display).
55
+ const policyWindow = breach.interval === 'minute' ? 60 : 3600;
56
+ reply
57
+ .header('Retry-After', breach.retryAfter)
58
+ .header('RateLimit-Limit', breach.limit)
59
+ .header('RateLimit-Reset', breach.retryAfter)
60
+ .header('RateLimit-Policy', `${breach.limit};w=${policyWindow}`)
61
+ .code(429)
62
+ .send({ error: 'rate_limited', interval: breach.interval });
63
+ }
64
+ catch (err) {
65
+ if (!skipOnError)
66
+ throw err;
67
+ request.requestLog?.warn?.('limiter.failed', { err });
68
+ }
69
+ });
70
+ };
71
+ export default fp(limiterPlugin, { name: 'studio-limiter-plugin' });
72
+ //# sourceMappingURL=limiterPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limiterPlugin.js","sourceRoot":"","sources":["../../../src/helpers/limiterPlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { FastifyPluginAsync, FastifyRequest } from 'fastify';
2
+ import type { Logger } from 'winston';
3
+ declare module 'fastify' {
4
+ interface FastifyRequest {
5
+ requestId: string;
6
+ requestLog: Logger;
7
+ requestStartTime: bigint;
8
+ }
9
+ }
10
+ export interface LoggingPluginOptions {
11
+ /** Routes to skip access logging entirely. Default: ['/health', '/']. */
12
+ ignoreRoutes?: string[];
13
+ /**
14
+ * Context available at request boundary (headers, url). Runs in onRequest,
15
+ * before auth has populated request.auth / studioApp.
16
+ */
17
+ earlyContextExtractor?: (request: FastifyRequest) => Record<string, unknown>;
18
+ /**
19
+ * Context available after auth + plugin hooks (request.auth, request.studioApp,
20
+ * request.customApp). Runs in preHandler — replaces child logger with enriched
21
+ * version. Used for tenant/user fields.
22
+ */
23
+ contextExtractor?: (request: FastifyRequest) => Record<string, unknown>;
24
+ /** Header used for request id propagation. Default: 'x-request-id'. */
25
+ requestIdHeader?: string;
26
+ /** Install setErrorHandler. Default: true. Disable if app installs its own. */
27
+ installErrorHandler?: boolean;
28
+ }
29
+ declare const _default: FastifyPluginAsync<LoggingPluginOptions>;
30
+ export default _default;