mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
TS Config Modernization Program Part 3 of many (#17904)
* noImplicitOverride: true * noImplicitReturns: true * noPropertyAccessFromIndexSignature: true
This commit is contained in:
@@ -96,7 +96,7 @@ test('Sets accountability to payload contents if valid token is passed', async (
|
||||
share,
|
||||
share_scope: shareScope,
|
||||
},
|
||||
env.SECRET,
|
||||
env['SECRET'],
|
||||
{ issuer: 'directus' }
|
||||
);
|
||||
|
||||
@@ -145,7 +145,7 @@ test('Sets accountability to payload contents if valid token is passed', async (
|
||||
share,
|
||||
share_scope: shareScope,
|
||||
},
|
||||
env.SECRET,
|
||||
env['SECRET'],
|
||||
{ issuer: 'directus' }
|
||||
);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ export const handler = async (req: Request, res: Response, next: NextFunction) =
|
||||
|
||||
if (req.token) {
|
||||
if (isDirectusJWT(req.token)) {
|
||||
const payload = verifyAccessJWT(req.token, env.SECRET);
|
||||
const payload = verifyAccessJWT(req.token, env['SECRET']);
|
||||
|
||||
req.accountability.role = payload.role;
|
||||
req.accountability.admin = payload.admin_access === true || payload.admin_access == 1;
|
||||
|
||||
@@ -11,11 +11,11 @@ const checkCacheMiddleware: RequestHandler = asyncHandler(async (req, res, next)
|
||||
const { cache } = getCache();
|
||||
|
||||
if (req.method.toLowerCase() !== 'get' && req.originalUrl?.startsWith('/graphql') === false) return next();
|
||||
if (env.CACHE_ENABLED !== true) return next();
|
||||
if (env['CACHE_ENABLED'] !== true) return next();
|
||||
if (!cache) return next();
|
||||
|
||||
if (shouldSkipCache(req)) {
|
||||
if (env.CACHE_STATUS_HEADER) res.setHeader(`${env.CACHE_STATUS_HEADER}`, 'MISS');
|
||||
if (env['CACHE_STATUS_HEADER']) res.setHeader(`${env['CACHE_STATUS_HEADER']}`, 'MISS');
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ const checkCacheMiddleware: RequestHandler = asyncHandler(async (req, res, next)
|
||||
cachedData = await getCacheValue(cache, key);
|
||||
} catch (err: any) {
|
||||
logger.warn(err, `[cache] Couldn't read key ${key}. ${err.message}`);
|
||||
if (env.CACHE_STATUS_HEADER) res.setHeader(`${env.CACHE_STATUS_HEADER}`, 'MISS');
|
||||
if (env['CACHE_STATUS_HEADER']) res.setHeader(`${env['CACHE_STATUS_HEADER']}`, 'MISS');
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ const checkCacheMiddleware: RequestHandler = asyncHandler(async (req, res, next)
|
||||
cacheExpiryDate = (await getCacheValue(cache, `${key}__expires_at`))?.exp;
|
||||
} catch (err: any) {
|
||||
logger.warn(err, `[cache] Couldn't read key ${`${key}__expires_at`}. ${err.message}`);
|
||||
if (env.CACHE_STATUS_HEADER) res.setHeader(`${env.CACHE_STATUS_HEADER}`, 'MISS');
|
||||
if (env['CACHE_STATUS_HEADER']) res.setHeader(`${env['CACHE_STATUS_HEADER']}`, 'MISS');
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -46,11 +46,11 @@ const checkCacheMiddleware: RequestHandler = asyncHandler(async (req, res, next)
|
||||
|
||||
res.setHeader('Cache-Control', getCacheControlHeader(req, cacheTTL, true, true));
|
||||
res.setHeader('Vary', 'Origin, Cache-Control');
|
||||
if (env.CACHE_STATUS_HEADER) res.setHeader(`${env.CACHE_STATUS_HEADER}`, 'HIT');
|
||||
if (env['CACHE_STATUS_HEADER']) res.setHeader(`${env['CACHE_STATUS_HEADER']}`, 'HIT');
|
||||
|
||||
return res.json(cachedData);
|
||||
} else {
|
||||
if (env.CACHE_STATUS_HEADER) res.setHeader(`${env.CACHE_STATUS_HEADER}`, 'MISS');
|
||||
if (env['CACHE_STATUS_HEADER']) res.setHeader(`${env['CACHE_STATUS_HEADER']}`, 'MISS');
|
||||
return next();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,13 +8,13 @@ import { ForbiddenException } from '../exceptions';
|
||||
import asyncHandler from '../utils/async-handler';
|
||||
|
||||
const collectionExists: RequestHandler = asyncHandler(async (req, res, next) => {
|
||||
if (!req.params.collection) return next();
|
||||
if (!req.params['collection']) return next();
|
||||
|
||||
if (req.params.collection in req.schema.collections === false) {
|
||||
if (req.params['collection'] in req.schema.collections === false) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
req.collection = req.params.collection;
|
||||
req.collection = req.params['collection'];
|
||||
|
||||
if (req.collection.startsWith('directus_')) {
|
||||
const systemRow = systemCollectionRows.find((collection) => {
|
||||
|
||||
@@ -4,14 +4,14 @@ import env from '../env';
|
||||
|
||||
let corsMiddleware: RequestHandler = (req, res, next) => next();
|
||||
|
||||
if (env.CORS_ENABLED === true) {
|
||||
if (env['CORS_ENABLED'] === true) {
|
||||
corsMiddleware = cors({
|
||||
origin: env.CORS_ORIGIN || true,
|
||||
methods: env.CORS_METHODS || 'GET,POST,PATCH,DELETE',
|
||||
allowedHeaders: env.CORS_ALLOWED_HEADERS,
|
||||
exposedHeaders: env.CORS_EXPOSED_HEADERS,
|
||||
credentials: env.CORS_CREDENTIALS || undefined,
|
||||
maxAge: env.CORS_MAX_AGE || undefined,
|
||||
origin: env['CORS_ORIGIN'] || true,
|
||||
methods: env['CORS_METHODS'] || 'GET,POST,PATCH,DELETE',
|
||||
allowedHeaders: env['CORS_ALLOWED_HEADERS'],
|
||||
exposedHeaders: env['CORS_EXPOSED_HEADERS'],
|
||||
credentials: env['CORS_CREDENTIALS'] || undefined,
|
||||
maxAge: env['CORS_MAX_AGE'] || undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ const errorHandler: ErrorRequestHandler = (err, req, res, _next) => {
|
||||
}
|
||||
|
||||
for (const err of errors) {
|
||||
if (env.NODE_ENV === 'development') {
|
||||
if (env['NODE_ENV'] === 'development') {
|
||||
err.extensions = {
|
||||
...(err.extensions || {}),
|
||||
stack: err.stack,
|
||||
@@ -54,7 +54,7 @@ const errorHandler: ErrorRequestHandler = (err, req, res, _next) => {
|
||||
});
|
||||
|
||||
if (err instanceof MethodNotAllowedException) {
|
||||
res.header('Allow', err.extensions.allow.join(', '));
|
||||
res.header('Allow', err.extensions['allow'].join(', '));
|
||||
}
|
||||
} else {
|
||||
logger.error(err);
|
||||
|
||||
@@ -12,8 +12,8 @@ import type { RequestHandler } from 'express';
|
||||
const extractToken: RequestHandler = (req, res, next) => {
|
||||
let token: string | null = null;
|
||||
|
||||
if (req.query && req.query.access_token) {
|
||||
token = req.query.access_token as string;
|
||||
if (req.query && req.query['access_token']) {
|
||||
token = req.query['access_token'] as string;
|
||||
}
|
||||
|
||||
if (req.headers && req.headers.authorization) {
|
||||
|
||||
@@ -16,11 +16,11 @@ export const parseGraphQL: RequestHandler = asyncHandler(async (req, res, next)
|
||||
let document: DocumentNode;
|
||||
|
||||
if (req.method === 'GET') {
|
||||
query = (req.query.query as string | undefined) || null;
|
||||
query = (req.query['query'] as string | undefined) || null;
|
||||
|
||||
if (req.query.variables) {
|
||||
if (req.query['variables']) {
|
||||
try {
|
||||
variables = parseJSON(req.query.variables as string);
|
||||
variables = parseJSON(req.query['variables'] as string);
|
||||
} catch {
|
||||
throw new InvalidQueryException(`Variables are invalid JSON.`);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export const parseGraphQL: RequestHandler = asyncHandler(async (req, res, next)
|
||||
variables = {};
|
||||
}
|
||||
|
||||
operationName = (req.query.operationName as string | undefined) || null;
|
||||
operationName = (req.query['operationName'] as string | undefined) || null;
|
||||
} else {
|
||||
query = req.body.query || null;
|
||||
variables = req.body.variables || null;
|
||||
@@ -58,10 +58,16 @@ export const parseGraphQL: RequestHandler = asyncHandler(async (req, res, next)
|
||||
|
||||
// Prevent caching responses when mutations are made
|
||||
if (operationAST?.operation === 'mutation') {
|
||||
res.locals.cache = false;
|
||||
res.locals['cache'] = false;
|
||||
}
|
||||
|
||||
res.locals.graphqlParams = { document, query, variables, operationName, contextValue: { req, res } } as GraphQLParams;
|
||||
res.locals['graphqlParams'] = {
|
||||
document,
|
||||
query,
|
||||
variables,
|
||||
operationName,
|
||||
contextValue: { req, res },
|
||||
} as GraphQLParams;
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ const RATE_LIMITER_GLOBAL_KEY = 'global-rate-limit';
|
||||
let checkRateLimit: RequestHandler = (_req, _res, next) => next();
|
||||
export let rateLimiterGlobal: RateLimiterRedis | RateLimiterMemcache | RateLimiterMemory;
|
||||
|
||||
if (env.RATE_LIMITER_GLOBAL_ENABLED === true) {
|
||||
if (env['RATE_LIMITER_GLOBAL_ENABLED'] === true) {
|
||||
validateEnv(['RATE_LIMITER_GLOBAL_STORE', 'RATE_LIMITER_GLOBAL_DURATION', 'RATE_LIMITER_GLOBAL_POINTS']);
|
||||
validateConfiguration();
|
||||
|
||||
@@ -27,7 +27,7 @@ if (env.RATE_LIMITER_GLOBAL_ENABLED === true) {
|
||||
|
||||
res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
|
||||
throw new HitRateLimitException(`Too many requests, retry after ${ms(rateLimiterRes.msBeforeNext)}.`, {
|
||||
limit: +env.RATE_LIMITER_GLOBAL_POINTS,
|
||||
limit: +env['RATE_LIMITER_GLOBAL_POINTS'],
|
||||
reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
|
||||
});
|
||||
}
|
||||
@@ -39,13 +39,13 @@ if (env.RATE_LIMITER_GLOBAL_ENABLED === true) {
|
||||
export default checkRateLimit;
|
||||
|
||||
function validateConfiguration() {
|
||||
if (env.RATE_LIMITER_ENABLED !== true) {
|
||||
if (env['RATE_LIMITER_ENABLED'] !== true) {
|
||||
logger.error(`The IP based rate limiter needs to be enabled when using the global rate limiter.`);
|
||||
process.exit(1);
|
||||
}
|
||||
const globalPointsPerSec =
|
||||
Number(env.RATE_LIMITER_GLOBAL_POINTS) / Math.max(Number(env.RATE_LIMITER_GLOBAL_DURATION), 1);
|
||||
const regularPointsPerSec = Number(env.RATE_LIMITER_POINTS) / Math.max(Number(env.RATE_LIMITER_DURATION), 1);
|
||||
Number(env['RATE_LIMITER_GLOBAL_POINTS']) / Math.max(Number(env['RATE_LIMITER_GLOBAL_DURATION']), 1);
|
||||
const regularPointsPerSec = Number(env['RATE_LIMITER_POINTS']) / Math.max(Number(env['RATE_LIMITER_DURATION']), 1);
|
||||
if (globalPointsPerSec <= regularPointsPerSec) {
|
||||
logger.error(`The global rate limiter needs to allow more requests per second than the IP based rate limiter.`);
|
||||
process.exit(1);
|
||||
|
||||
@@ -11,7 +11,7 @@ import { validateEnv } from '../utils/validate-env';
|
||||
let checkRateLimit: RequestHandler = (_req, _res, next) => next();
|
||||
export let rateLimiter: RateLimiterRedis | RateLimiterMemcache | RateLimiterMemory;
|
||||
|
||||
if (env.RATE_LIMITER_ENABLED === true) {
|
||||
if (env['RATE_LIMITER_ENABLED'] === true) {
|
||||
validateEnv(['RATE_LIMITER_STORE', 'RATE_LIMITER_DURATION', 'RATE_LIMITER_POINTS']);
|
||||
|
||||
rateLimiter = createRateLimiter('RATE_LIMITER');
|
||||
@@ -24,7 +24,7 @@ if (env.RATE_LIMITER_ENABLED === true) {
|
||||
|
||||
res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
|
||||
throw new HitRateLimitException(`Too many requests, retry after ${ms(rateLimiterRes.msBeforeNext)}.`, {
|
||||
limit: +env.RATE_LIMITER_POINTS,
|
||||
limit: +env['RATE_LIMITER_POINTS'],
|
||||
reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,30 +16,30 @@ export const respond: RequestHandler = asyncHandler(async (req, res) => {
|
||||
|
||||
let exceedsMaxSize = false;
|
||||
|
||||
if (env.CACHE_VALUE_MAX_SIZE !== false) {
|
||||
const valueSize = res.locals.payload ? stringByteSize(JSON.stringify(res.locals.payload)) : 0;
|
||||
const maxSize = parseBytesConfiguration(env.CACHE_VALUE_MAX_SIZE);
|
||||
if (env['CACHE_VALUE_MAX_SIZE'] !== false) {
|
||||
const valueSize = res.locals['payload'] ? stringByteSize(JSON.stringify(res.locals['payload'])) : 0;
|
||||
const maxSize = parseBytesConfiguration(env['CACHE_VALUE_MAX_SIZE']);
|
||||
exceedsMaxSize = valueSize > maxSize;
|
||||
}
|
||||
|
||||
if (
|
||||
(req.method.toLowerCase() === 'get' || req.originalUrl?.startsWith('/graphql')) &&
|
||||
env.CACHE_ENABLED === true &&
|
||||
env['CACHE_ENABLED'] === true &&
|
||||
cache &&
|
||||
!req.sanitizedQuery.export &&
|
||||
res.locals.cache !== false &&
|
||||
res.locals['cache'] !== false &&
|
||||
exceedsMaxSize === false
|
||||
) {
|
||||
const key = getCacheKey(req);
|
||||
|
||||
try {
|
||||
await setCacheValue(cache, key, res.locals.payload, getMilliseconds(env.CACHE_TTL));
|
||||
await setCacheValue(cache, `${key}__expires_at`, { exp: Date.now() + getMilliseconds(env.CACHE_TTL, 0) });
|
||||
await setCacheValue(cache, key, res.locals['payload'], getMilliseconds(env['CACHE_TTL']));
|
||||
await setCacheValue(cache, `${key}__expires_at`, { exp: Date.now() + getMilliseconds(env['CACHE_TTL'], 0) });
|
||||
} catch (err: any) {
|
||||
logger.warn(err, `[cache] Couldn't set key ${key}. ${err}`);
|
||||
}
|
||||
|
||||
res.setHeader('Cache-Control', getCacheControlHeader(req, getMilliseconds(env.CACHE_TTL), true, true));
|
||||
res.setHeader('Cache-Control', getCacheControlHeader(req, getMilliseconds(env['CACHE_TTL']), true, true));
|
||||
res.setHeader('Vary', 'Origin, Cache-Control');
|
||||
} else {
|
||||
// Don't cache anything by default
|
||||
@@ -63,32 +63,32 @@ export const respond: RequestHandler = asyncHandler(async (req, res) => {
|
||||
if (req.sanitizedQuery.export === 'json') {
|
||||
res.attachment(`${filename}.json`);
|
||||
res.set('Content-Type', 'application/json');
|
||||
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'json'));
|
||||
return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'json'));
|
||||
}
|
||||
|
||||
if (req.sanitizedQuery.export === 'xml') {
|
||||
res.attachment(`${filename}.xml`);
|
||||
res.set('Content-Type', 'text/xml');
|
||||
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'xml'));
|
||||
return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'xml'));
|
||||
}
|
||||
|
||||
if (req.sanitizedQuery.export === 'csv') {
|
||||
res.attachment(`${filename}.csv`);
|
||||
res.set('Content-Type', 'text/csv');
|
||||
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'csv'));
|
||||
return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'csv'));
|
||||
}
|
||||
|
||||
if (req.sanitizedQuery.export === 'yaml') {
|
||||
res.attachment(`${filename}.yaml`);
|
||||
res.set('Content-Type', 'text/yaml');
|
||||
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'yaml'));
|
||||
return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'yaml'));
|
||||
}
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(res.locals.payload)) {
|
||||
return res.end(res.locals.payload);
|
||||
} else if (res.locals.payload) {
|
||||
return res.json(res.locals.payload);
|
||||
if (Buffer.isBuffer(res.locals['payload'])) {
|
||||
return res.end(res.locals['payload']);
|
||||
} else if (res.locals['payload']) {
|
||||
return res.json(res.locals['payload']);
|
||||
} else {
|
||||
return res.status(204).end();
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const sanitizeQueryMiddleware: RequestHandler = (req, _res, next) => {
|
||||
|
||||
req.sanitizedQuery = sanitizeQuery(
|
||||
{
|
||||
fields: req.query.fields || '*',
|
||||
fields: req.query['fields'] || '*',
|
||||
...req.query,
|
||||
},
|
||||
req.accountability || null
|
||||
|
||||
Reference in New Issue
Block a user