@lilaquadrat/studio 10.0.0-beta.8 → 10.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.
- package/eslint.config.js +146 -0
- package/lib/fastify-plugins.d.ts +6 -0
- package/lib/fastify-plugins.js +7 -0
- package/lib/fastify-plugins.js.map +1 -0
- package/lib/helpers.d.ts +4 -2
- package/lib/helpers.js +13 -2
- package/lib/helpers.js.map +1 -1
- package/lib/main.d.ts +1 -3
- package/lib/main.js +7 -3
- package/lib/main.js.map +1 -1
- package/lib/models.d.ts +4 -4
- package/lib/models.js +4 -4
- package/lib/models.js.map +1 -1
- package/lib/services.d.ts +5 -5
- package/lib/services.js +5 -13
- package/lib/services.js.map +1 -1
- package/lib/src/Immutable.class.d.ts +8 -1
- package/lib/src/Immutable.class.js +52 -8
- package/lib/src/Immutable.class.js.map +1 -1
- package/lib/src/ShareClientFactory.class.d.ts +1 -3
- package/lib/src/ShareClientFactory.class.js +1 -9
- package/lib/src/ShareClientFactory.class.js.map +1 -1
- package/lib/src/classes/models.class.js.map +1 -1
- package/lib/src/classes/modelv2.class.d.ts +2 -0
- package/lib/src/classes/modelv2.class.js +1 -1
- package/lib/src/classes/modelv2.class.js.map +1 -1
- package/lib/src/classes/mongo.class.js +4 -14
- package/lib/src/classes/mongo.class.js.map +1 -1
- package/lib/src/functions/handleError.d.ts +2 -3
- package/lib/src/functions/handleError.js +3 -16
- package/lib/src/functions/handleError.js.map +1 -1
- package/lib/src/functions/optionsHelper.d.ts +4 -4
- package/lib/src/functions/optionsHelper.js +5 -4
- package/lib/src/functions/optionsHelper.js.map +1 -1
- package/lib/src/functions/respondCode.d.ts +2 -1
- package/lib/src/functions/respondCode.js +1 -1
- package/lib/src/functions/respondCode.js.map +1 -1
- package/lib/src/helpers/ControllerHelper.d.ts +73 -0
- package/lib/src/helpers/ControllerHelper.js +242 -0
- package/lib/src/helpers/ControllerHelper.js.map +1 -0
- package/lib/src/helpers/EnvMapper.js +1 -0
- package/lib/src/helpers/EnvMapper.js.map +1 -0
- package/lib/src/helpers/auth0config.d.ts +6 -0
- package/lib/src/helpers/auth0config.js +23 -0
- package/lib/src/helpers/auth0config.js.map +1 -0
- package/lib/src/helpers/authPlugin.d.ts +29 -0
- package/lib/src/helpers/authPlugin.js +77 -0
- package/lib/src/helpers/authPlugin.js.map +1 -0
- package/lib/src/helpers/cacheHelper.d.ts +69 -0
- package/lib/src/helpers/cacheHelper.js +235 -0
- package/lib/src/helpers/cacheHelper.js.map +1 -0
- package/lib/src/helpers/createSasToken.d.ts +0 -2
- package/lib/src/helpers/createSasToken.js +35 -32
- package/lib/src/helpers/createSasToken.js.map +1 -1
- package/lib/src/helpers/getSecrets.d.ts +1 -1
- package/lib/src/helpers/getSecrets.js +10 -12
- package/lib/src/helpers/getSecrets.js.map +1 -1
- package/lib/src/helpers/limiterPlugin.d.ts +9 -0
- package/lib/src/helpers/limiterPlugin.js +72 -0
- package/lib/src/helpers/limiterPlugin.js.map +1 -0
- package/lib/src/helpers/loggingPlugin.d.ts +30 -0
- package/lib/src/helpers/loggingPlugin.js +87 -0
- package/lib/src/helpers/loggingPlugin.js.map +1 -0
- package/lib/src/helpers/queryAssertionPlugin.d.ts +3 -0
- package/lib/src/helpers/queryAssertionPlugin.js +20 -0
- package/lib/src/helpers/queryAssertionPlugin.js.map +1 -0
- package/lib/src/helpers/safeObjectId.d.ts +1 -1
- package/lib/src/helpers/safeObjectId.js +5 -1
- package/lib/src/helpers/safeObjectId.js.map +1 -1
- package/lib/src/helpers/storageSdkFactory.d.ts +2 -0
- package/lib/src/helpers/storageSdkFactory.js +11 -0
- package/lib/src/helpers/storageSdkFactory.js.map +1 -0
- package/lib/src/helpers/studioAppPlugin.d.ts +3 -0
- package/lib/src/helpers/studioAppPlugin.js +16 -0
- package/lib/src/helpers/studioAppPlugin.js.map +1 -0
- package/lib/src/logger.js +57 -8
- package/lib/src/logger.js.map +1 -1
- package/lib/src/models/access.model.d.ts +14 -3
- package/lib/src/models/access.model.js +7 -9
- package/lib/src/models/access.model.js.map +1 -1
- package/lib/src/models/customers.model.js +14 -4
- package/lib/src/models/customers.model.js.map +1 -1
- package/lib/src/models/design.model.d.ts +4 -0
- package/lib/src/models/design.model.js +58 -0
- package/lib/src/models/design.model.js.map +1 -0
- package/lib/src/models/domain.model.js +1 -1
- package/lib/src/models/domain.model.js.map +1 -1
- package/lib/src/models/editor.model.js +7 -0
- package/lib/src/models/editor.model.js.map +1 -1
- package/lib/src/models/emailLimit.model.d.ts +4 -0
- package/lib/src/models/emailLimit.model.js +31 -0
- package/lib/src/models/emailLimit.model.js.map +1 -0
- package/lib/src/models/hosting.model.js +1 -3
- package/lib/src/models/hosting.model.js.map +1 -1
- package/lib/src/models/hostingSettings.model.js +6 -4
- package/lib/src/models/hostingSettings.model.js.map +1 -1
- package/lib/src/models/invoice.model.d.ts +4 -0
- package/lib/src/models/invoice.model.js +235 -0
- package/lib/src/models/invoice.model.js.map +1 -0
- package/lib/src/models/mailFrom.model.js +51 -10
- package/lib/src/models/mailFrom.model.js.map +1 -1
- package/lib/src/models/project.model.js +2 -4
- package/lib/src/models/project.model.js.map +1 -1
- package/lib/src/models/publish-method.model.js +79 -430
- package/lib/src/models/publish-method.model.js.map +1 -1
- package/lib/src/models/publish.model.js +6 -0
- package/lib/src/models/publish.model.js.map +1 -1
- package/lib/src/models/storage.model.js +23 -5
- package/lib/src/models/storage.model.js.map +1 -1
- package/lib/src/models/structure.model.js +40 -0
- package/lib/src/models/structure.model.js.map +1 -1
- package/lib/src/models/upload.model.js +38 -2
- package/lib/src/models/upload.model.js.map +1 -1
- package/lib/src/prompts/textGeneration.js +88 -0
- package/lib/src/prompts/textGeneration.js.map +1 -1
- package/lib/src/prompts/textGenerationMulti.js +78 -44
- package/lib/src/prompts/textGenerationMulti.js.map +1 -1
- package/lib/src/services/access.service.d.ts +132 -33
- package/lib/src/services/access.service.js +270 -92
- package/lib/src/services/access.service.js.map +1 -1
- package/lib/src/services/ai.service.d.ts +4 -3
- package/lib/src/services/ai.service.js +22 -29
- package/lib/src/services/ai.service.js.map +1 -1
- package/lib/src/services/auth.service.d.ts +11 -0
- package/lib/src/services/auth.service.js +70 -0
- package/lib/src/services/auth.service.js.map +1 -0
- package/lib/src/services/conf.service.d.ts +3 -31
- package/lib/src/services/conf.service.js +58 -167
- package/lib/src/services/conf.service.js.map +1 -1
- package/lib/src/services/customers.service.d.ts +8 -4
- package/lib/src/services/customers.service.js +34 -7
- package/lib/src/services/customers.service.js.map +1 -1
- package/lib/src/services/designs.service.d.ts +7 -0
- package/lib/src/services/designs.service.js +10 -0
- package/lib/src/services/designs.service.js.map +1 -0
- package/lib/src/services/domains.service.d.ts +18 -84
- package/lib/src/services/domains.service.js +91 -583
- package/lib/src/services/domains.service.js.map +1 -1
- package/lib/src/services/editor.service.d.ts +4 -0
- package/lib/src/services/editor.service.js +28 -0
- package/lib/src/services/editor.service.js.map +1 -1
- package/lib/src/services/emailLimit.service.d.ts +21 -0
- package/lib/src/services/emailLimit.service.js +51 -0
- package/lib/src/services/emailLimit.service.js.map +1 -0
- package/lib/src/services/hosting.service.d.ts +12 -24
- package/lib/src/services/hosting.service.js +32 -122
- package/lib/src/services/hosting.service.js.map +1 -1
- package/lib/src/services/hostingAdmin.service.d.ts +1 -1
- package/lib/src/services/hostingAdmin.service.js +2 -2
- package/lib/src/services/hostingAdmin.service.js.map +1 -1
- package/lib/src/services/import.service.d.ts +6 -22
- package/lib/src/services/import.service.js +63 -65
- package/lib/src/services/import.service.js.map +1 -1
- package/lib/src/services/invoices.service.d.ts +30 -0
- package/lib/src/services/invoices.service.js +265 -0
- package/lib/src/services/invoices.service.js.map +1 -0
- package/lib/src/services/jetstream.service.d.ts +5 -3
- package/lib/src/services/jetstream.service.js +63 -7
- package/lib/src/services/jetstream.service.js.map +1 -1
- package/lib/src/services/listParticipants.service.d.ts +3 -5
- package/lib/src/services/listParticipants.service.js +76 -16
- package/lib/src/services/listParticipants.service.js.map +1 -1
- package/lib/src/services/mailFrom.service.d.ts +14 -1
- package/lib/src/services/mailFrom.service.js +59 -0
- package/lib/src/services/mailFrom.service.js.map +1 -1
- package/lib/src/services/me.service.d.ts +23 -12
- package/lib/src/services/me.service.js +65 -88
- package/lib/src/services/me.service.js.map +1 -1
- package/lib/src/services/publish.service.d.ts +6 -8
- package/lib/src/services/publish.service.js +34 -32
- package/lib/src/services/publish.service.js.map +1 -1
- package/lib/src/services/publishData.service.d.ts +10 -7
- package/lib/src/services/publishData.service.js +32 -75
- package/lib/src/services/publishData.service.js.map +1 -1
- package/lib/src/services/spamAnalasys.service.d.ts +4 -4
- package/lib/src/services/spamAnalasys.service.js +36 -44
- package/lib/src/services/spamAnalasys.service.js.map +1 -1
- package/lib/src/services/storage.service.d.ts +68 -39
- package/lib/src/services/storage.service.js +378 -209
- package/lib/src/services/storage.service.js.map +1 -1
- package/lib/src/services/structures.service.d.ts +8 -1
- package/lib/src/services/structures.service.js +26 -1
- package/lib/src/services/structures.service.js.map +1 -1
- package/lib/src/services/upload.service.d.ts +8 -1
- package/lib/src/services/upload.service.js +76 -3
- package/lib/src/services/upload.service.js.map +1 -1
- package/lib/tests/groupStructuresByModel.spec.d.ts +1 -0
- package/lib/tests/groupStructuresByModel.spec.js +33 -0
- package/lib/tests/groupStructuresByModel.spec.js.map +1 -0
- package/lib/tests/listParticipantsServiceJoin.spec.d.ts +1 -0
- package/lib/tests/listParticipantsServiceJoin.spec.js +151 -0
- package/lib/tests/listParticipantsServiceJoin.spec.js.map +1 -0
- package/lib/tests/storageServiceHandleFile.spec.d.ts +1 -0
- package/lib/tests/storageServiceHandleFile.spec.js +94 -0
- package/lib/tests/storageServiceHandleFile.spec.js.map +1 -0
- package/lib/tests/storageServiceToken.spec.d.ts +1 -0
- package/lib/tests/storageServiceToken.spec.js +104 -0
- package/lib/tests/storageServiceToken.spec.js.map +1 -0
- package/lib/tests/uploadServiceCreate.spec.d.ts +1 -0
- package/lib/tests/uploadServiceCreate.spec.js +81 -0
- package/lib/tests/uploadServiceCreate.spec.js.map +1 -0
- package/package.json +30 -26
- package/lib/src/AzureBlobStorage.share.d.ts +0 -19
- package/lib/src/AzureBlobStorage.share.js +0 -162
- package/lib/src/AzureBlobStorage.share.js.map +0 -1
- package/lib/src/AzureFileStorage.share.d.ts +0 -22
- package/lib/src/AzureFileStorage.share.js +0 -139
- package/lib/src/AzureFileStorage.share.js.map +0 -1
- package/lib/src/AzureVault.d.ts +0 -14
- package/lib/src/AzureVault.js +0 -28
- package/lib/src/AzureVault.js.map +0 -1
- package/lib/src/dns.challenge.class.d.ts +0 -17
- package/lib/src/dns.challenge.class.js +0 -41
- package/lib/src/dns.challenge.class.js.map +0 -1
- package/lib/src/http.challenge.class.d.ts +0 -33
- package/lib/src/http.challenge.class.js +0 -58
- package/lib/src/http.challenge.class.js.map +0 -1
- package/lib/src/models/certificate-action.model.d.ts +0 -5
- package/lib/src/models/certificate-action.model.js +0 -230
- package/lib/src/models/certificate-action.model.js.map +0 -1
- package/lib/src/models/certificate.model.d.ts +0 -4
- package/lib/src/models/certificate.model.js +0 -96
- package/lib/src/models/certificate.model.js.map +0 -1
- package/lib/src/models/editorBase.model.d.ts +0 -4
- package/lib/src/models/editorBase.model.js +0 -39
- package/lib/src/models/editorBase.model.js.map +0 -1
- package/lib/src/services/certificates.service.js +0 -199
- package/lib/src/services/certificates.service.js.map +0 -1
- package/lib/src/services/certificatesAction.service.d.ts +0 -0
- package/lib/src/services/certificatesAction.service.js +0 -237
- package/lib/src/services/certificatesAction.service.js.map +0 -1
- package/lib/src/services/editorBase.service.d.ts +0 -46
- package/lib/src/services/editorBase.service.js +0 -161
- package/lib/src/services/editorBase.service.js.map +0 -1
- package/lib/src/services/handleFile.service.d.ts +0 -9
- package/lib/src/services/handleFile.service.js +0 -45
- package/lib/src/services/handleFile.service.js.map +0 -1
- package/lib/src/services/media.service.d.ts +0 -35
- package/lib/src/services/media.service.js +0 -418
- package/lib/src/services/media.service.js.map +0 -1
- package/lib/src/services/share.service.d.ts +0 -6
- package/lib/src/services/share.service.js +0 -4
- package/lib/src/services/share.service.js.map +0 -1
- /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":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChC,OAAO,UAA6B,MAAM,cAAc,CAAC;AACzD,OAAO,OAAO,MAAM,UAAU,CAAC;AAC/B,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,WAAW,MAAM,kBAAkB,CAAC;AA+B3C,MAAM,UAAU,GAAuB,KAAK,EAAE,OAAwB,EAAE,EAAE;IAExE,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;QAE9B,6EAA6E;QAC7E,MAAM,WAAW,GAAG,IAAI,GAAG,EAA8B,CAAC;QAE1D,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,EAAE;YAExC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAE9B,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;oBAC/B,KAAK,EAAE,IAAI;oBACX,eAAe,EAAE,CAAC;oBAClB,WAAW,EAAE,MAAM,EAAE,mBAAmB;oBACxC,SAAS,EAAE,IAAI;oBACf,qBAAqB,EAAE,EAAE;oBACzB,OAAO;iBACR,CAAC,CAAC,CAAC;YAEN,CAAC;YAED,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC;QAEnC,CAAC,CAAC;QAEF,qCAAqC;QACrC,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE;YACjC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC1B,MAAM,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAoB,EAAmB,EAAE;gBAE/E,MAAM,MAAM,GAAG,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;gBACxD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,YAAY,CAAC;gBAC9C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;gBAExC,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAEpC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC;gBAC7B,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;gBACtC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAE3E,OAAO,GAAG,CAAC,YAAY,EAAE,CAAC;YAE5B,CAAC;YACD,MAAM,EAAE;gBACN,UAAU,EAAE,CAAC,OAAO,CAAC;aACtB;SACF,CAAC,CAAC;QAEH,mDAAmD;QACnD,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;YAEtF,IAAI,CAAC;gBAEH,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;gBAE1B,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAE9B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBAEb,OAAO,WAAW,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;YAE5C,CAAC;QAEH,CAAC,CAAC,CAAC;IAEL,CAAC;SAAM,CAAC;QAEN,2BAA2B;QAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;YAEtF,OAAO,CAAC,IAAI,GAAG;gBACb,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,QAAS;gBAC1B,UAAU,EAAE,KAAK;gBACjB,WAAW,EAAE,MAAM;gBACnB,QAAQ,EAAE,SAAS;gBACnB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,EAAE;gBACX,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,GAAG,EAAE,KAAK;gBACV,GAAG,EAAE,KAAK;gBACV,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;gBAClC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI;gBACzC,OAAO,EAAE,EAAE;gBACX,KAAK,EAAE,EAAE;gBACT,cAAc,EAAE,IAAI;aACrB,CAAC;QAEJ,CAAC,CAAC,CAAC;IAEL,CAAC;AAEH,CAAC,CAAC;AAEF,eAAe,EAAE,CAAC,UAAU,EAAE;IAC5B,IAAI,EAAE,aAAa;CACpB,CAAC,CAAC"}
|
|
@@ -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,33 +1,36 @@
|
|
|
1
|
-
import { DefaultAzureCredential } from '@azure/identity';
|
|
2
|
-
import { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions } from '@azure/storage-blob';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
//
|
|
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,
|
|
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,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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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,
|
|
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;
|