diff --git a/eslint.config.mjs b/eslint.config.mjs index db261f4a9..ccb465a51 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -28,6 +28,7 @@ export default tseslint.config( 'camelcase': 'off', 'no-param-reassign': 'off', 'new-cap': 'off', + '@typescript-eslint/no-unsafe-function-type':'off' } } ); diff --git a/lib/auth/backends/in_memory/Backend.ts b/lib/auth/backends/in_memory/Backend.ts index 8baaea36e..b5ee0a896 100644 --- a/lib/auth/backends/in_memory/Backend.ts +++ b/lib/auth/backends/in_memory/Backend.ts @@ -10,16 +10,16 @@ import { AuthInfoType, AuthV4Results } from '../../AuthInfo'; function _formatResponse(userInfo: AuthInfoType): { message: { body: AuthV4Results } } { return { message: { - body: { - userInfo, - accountQuota: { - account: userInfo.canonicalID, - quota: 0n, + body: { + userInfo, + accountQuota: { + account: userInfo.canonicalID, + quota: 0n, + }, }, - }, }, - }; }; +}; /** * Class that provides a memory backend for verifying signatures and getting diff --git a/lib/auth/v2/queryAuthCheck.ts b/lib/auth/v2/queryAuthCheck.ts index df8d5a966..e52413129 100644 --- a/lib/auth/v2/queryAuthCheck.ts +++ b/lib/auth/v2/queryAuthCheck.ts @@ -4,7 +4,7 @@ import * as constants from '../../constants'; import algoCheck from './algoCheck'; import constructStringToSign from './constructStringToSign'; -export let PRE_SIGN_URL_EXPIRY = process.env.PRE_SIGN_URL_EXPIRY ? +export const PRE_SIGN_URL_EXPIRY = process.env.PRE_SIGN_URL_EXPIRY ? Number.parseInt(process.env.PRE_SIGN_URL_EXPIRY, 10) : constants.defaultPreSignedURLExpiry * 1000; diff --git a/lib/storage/metadata/mongoclient/MongoClientInterface.ts b/lib/storage/metadata/mongoclient/MongoClientInterface.ts index fbd27f4be..0e7354c47 100644 --- a/lib/storage/metadata/mongoclient/MongoClientInterface.ts +++ b/lib/storage/metadata/mongoclient/MongoClientInterface.ts @@ -20,7 +20,9 @@ import BucketInfo, { BucketMetadata, Capabilities } from '../../../models/Bucket import ObjectMD, { ObjectMDData } from '../../../models/ObjectMD'; import * as jsutil from '../../../jsutil'; -import { MongoClient, Long, Db, MongoClientOptions, ReadPreferenceMode, WithId, Collection, AnyBulkWriteOperation, UpdateFilter, MongoServerError } from 'mongodb'; +import { MongoClient, Long, Db, MongoClientOptions, + ReadPreferenceMode, WithId, Collection, AnyBulkWriteOperation, + UpdateFilter, MongoServerError } from 'mongodb'; import Uuid from 'uuid'; import diskusage from 'diskusage'; @@ -37,7 +39,7 @@ import { Version } from '../../../versioning/Version'; import { formatMasterKey, formatVersionKey } from './utils'; import { VeeamCapacityInfo, VeeamSOSApiSchema } from '../../../models/Veeam'; -import { BucketVersioningFormat, VersioningConstants } from '../../../versioning/constants'; +import { BucketVersioningFormat } from '../../../versioning/constants'; const VID_NONE = ''; @@ -68,7 +70,7 @@ const BUCKET_VERSIONS = require('../../../versioning/constants') .VersioningConstants.BucketVersioningKeyFormat; const DEFAULT_BUCKET_KEY_FORMAT = [BUCKET_VERSIONS.v0, BUCKET_VERSIONS.v1] - .includes(process.env.DEFAULT_BUCKET_KEY_FORMAT!) ? + .includes(process.env.DEFAULT_BUCKET_KEY_FORMAT!) ? process.env.DEFAULT_BUCKET_KEY_FORMAT : BUCKET_VERSIONS.v1; const DB_PREFIXES = require('../../../versioning/constants') @@ -255,7 +257,7 @@ class MongoClientInterface { private readonly defaultBucketKeyFormat: BucketVersioningFormat; private cacheHit: number; private cacheMiss: number; - private cacheHitMissLoggerInterval: NodeJS.Timer; + private cacheHitMissLoggerInterval: NodeJS.Timer | null; private adminDb: Db | null; private isConnected = false; @@ -289,7 +291,7 @@ class MongoClientInterface { this.cacheHit = 0; this.cacheMiss = 0; - this.cacheHitMissLoggerInterval = undefined; + this.cacheHitMissLoggerInterval = null; } setup(cb: Function) { @@ -324,7 +326,7 @@ class MongoClientInterface { this.adminDb = client.db('admin'); // log cache hit/miss every 5min this.cacheHitMissLoggerInterval = setInterval(() => { - let hitRatio = (this.cacheHit / (this.cacheHit + this.cacheMiss)) || 0; + const hitRatio = (this.cacheHit / (this.cacheHit + this.cacheMiss)) || 0; this.logger.debug('MongoClientInterface: Bucket vFormat cache hit/miss (5min)', { hits: this.cacheHit, misses: this.cacheMiss, hitRatio: hitRatio.toFixed(3) }); this.cacheHit = 0; @@ -359,7 +361,7 @@ class MongoClientInterface { if (err) { this.logger.fatal('error writing usersBucket ' + 'attributes to metastore', - { error: err }); + { error: err }); throw (errors.InternalError); } return cb(); @@ -369,7 +371,7 @@ class MongoClientInterface { close(cb) { if (this.client) { if (this.cacheHitMissLoggerInterval) { - clearInterval(this.cacheHitMissLoggerInterval); + clearInterval(this.cacheHitMissLoggerInterval as NodeJS.Timeout); } return this.client.close(true) .then(() => cb()) @@ -576,7 +578,7 @@ class MongoClientInterface { const newBucketMD = JSON.parse(bucketMDStr); // Quota must be stored as a Long to account for values larger than // Number.MAX_SAFE_INTEGER. - // eslint-disable-next-line new-cap + newBucketMD.quotaMax = new Long(newBucketMD.quotaMax || 0); const m = this.getCollection(METASTORE); m.updateOne({ @@ -683,7 +685,7 @@ class MongoClientInterface { _id: bucketName, } , { includeResultMetadata: true, - }, {}) + }) .then(result => { if (result.ok !== 1) { log.error('deleteBucketStep2: failed deleting bucket'); @@ -744,7 +746,8 @@ class MongoClientInterface { * @param {Boolean} upsert if upserting is needed * @return {Object} mongo operation */ - updateDeleteMaster(isDeleteMarker: boolean, vFormat: string, filter: any, update: any, upsert: boolean): AnyBulkWriteOperation { + updateDeleteMaster(isDeleteMarker: boolean, vFormat: string, + filter: any, update: any, upsert: boolean): AnyBulkWriteOperation { // delete master when we are in v1 and the version is a delete // marker if (isDeleteMarker && vFormat === BUCKET_VERSIONS.v1) { @@ -800,7 +803,7 @@ class MongoClientInterface { isRetry?: boolean, ) { const versionId = generateVersionId(this.replicationGroupId); - // eslint-disable-next-line + objVal.versionId = versionId; const versionKey = formatVersionKey(objName, versionId, params.vFormat); const masterKey = formatMasterKey(objName, params.vFormat); @@ -844,7 +847,7 @@ class MongoClientInterface { ordered: true, }) .then(() => cb(null, `{"versionId": "${versionId}"}`)) - .catch((err) => { + .catch(err => { /* * Related to https://jira.mongodb.org/browse/SERVER-14322 * It happens when we are pushing two versions "at the same time" @@ -913,7 +916,7 @@ class MongoClientInterface { cb: ArsenalCallback, ) { const versionId = generateVersionId(this.replicationGroupId); - // eslint-disable-next-line + objVal.versionId = versionId; const masterKey = formatMasterKey(objName, params.vFormat); c.updateOne({ _id: masterKey }, @@ -921,7 +924,7 @@ class MongoClientInterface { { upsert: true }, ) .then(() => cb(null, `{"versionId": "${objVal.versionId}"}`)) - .catch((err) => { + .catch(err => { log.error('putObjectVerCase2: error putting object version', { error: err.message }); return cb(errors.InternalError); }); @@ -956,7 +959,7 @@ class MongoClientInterface { log: werelogs.Logger, cb: ArsenalCallback, ) { - // eslint-disable-next-line + objVal.versionId = params.versionId; const versionKey = formatVersionKey(objName, params.versionId, params.vFormat); const masterKey = formatMasterKey(objName, params.vFormat); @@ -1120,7 +1123,7 @@ class MongoClientInterface { ops.push(masterOp); return c.bulkWrite(ops, { ordered: true, - }).then(() => cb(null, `{"versionId": "${objVal.versionId}"}`)).catch((err) => { + }).then(() => cb(null, `{"versionId": "${objVal.versionId}"}`)).catch(err => { // we accept that the update fails if // condition is not met, meaning that a more // recent master was already in place @@ -1231,13 +1234,13 @@ class MongoClientInterface { }, { upsert: false, }).then(doc => { - if (!doc.value) { + if (!doc?.value) { log.error('internalPutObject: unable to find target object to update', { bucket: bucketName, object: key }); return next(errors.NoSuchKey); } const obj = doc.value; - const objMetadata = new ObjectMD(obj.value); + const objMetadata = new ObjectMD(obj); objMetadata.setOriginOp(params.originOp); objMetadata.setDeleted(true); return next(null, objMetadata.getValue()); @@ -1268,7 +1271,7 @@ class MongoClientInterface { }, }, ], { ordered: true }).then(() => next(null)).catch(next), - ], (err) => { + ], err => { if (err) { log.error('internalPutObject: error updating object', { bucket: bucketName, object: key, error: err.message }); @@ -1589,7 +1592,7 @@ class MongoClientInterface { ) { const masterKey = formatMasterKey(objName, vFormat); MongoUtils.serialize(objVal); - // eslint-disable-next-line + objVal.originOp = 's3:ObjectRemoved:Delete'; c.findOneAndReplace({ '_id': masterKey, @@ -1687,7 +1690,7 @@ class MongoClientInterface { // a master or re-delete it in between so place an // atomic condition on the PHD flag and the mst // version: - // eslint-disable-next-line + const filter = { 'value.isPHD': true, 'value.versionId': mst.versionId, @@ -2226,11 +2229,11 @@ class MongoClientInterface { newParams.gt = undefined; if (newParams.secondaryStreamParams) { - // eslint-disable-next-line no-param-reassign + newParams.mainStreamParams.gte = range[0]; newParams.secondaryStreamParams.gte = range[1]; } else { - // eslint-disable-next-line no-param-reassign + newParams.mainStreamParams.gte = range; } // then continue listing the next key range @@ -2382,7 +2385,7 @@ class MongoClientInterface { const i = this.getCollection(INFOSTORE); if (!i) { log.error('readUUID: error getting infostore collection'); - return + return; } i.findOne({ _id: __UUID, @@ -2404,7 +2407,7 @@ class MongoClientInterface { log.error('writeUUIDIfNotExists: error getting infostore collection'); return cb(errors.InternalError); } - i.insertOne({ + return i.insertOne({ _id: __UUID, value: uuid, }, {}).then(() => cb(null)) // FIXME: shoud we check for result.ok === 1 ? @@ -2445,11 +2448,11 @@ class MongoClientInterface { // way for guessing free space. diskusage.check(this.path !== undefined ? this.path : '/', (err, result) => { - if (err) { - return cb(errors.InternalError); - } - return cb(null, result); - }); + if (err) { + return cb(errors.InternalError); + } + return cb(null, result); + }); } readCountItems(log: werelogs.Logger, cb: ArsenalCallback) { @@ -2458,7 +2461,7 @@ class MongoClientInterface { log.error('readCountItems: error getting infostore collection'); return cb(errors.InternalError); } - i.findOne({ + return i.findOne({ _id: __COUNT_ITEMS, }, {}).then(doc => { if (!doc) { @@ -2492,12 +2495,12 @@ class MongoClientInterface { return cb(errors.InternalError); } - i.updateOne({ + return i.updateOne({ _id: __COUNT_ITEMS, }, { $set: { _id: __COUNT_ITEMS, - value: value, + value, }, }, { upsert: true, @@ -2591,15 +2594,15 @@ class MongoClientInterface { bucketInfos, }); })).catch(err => { - log.error('could not get list of collections', { - method: 'getBucketInfos', - error: err, - }); - if (err && err instanceof ArsenalError) { - return cb(err); - } - return cb(errors.InternalError); + log.error('could not get list of collections', { + method: 'getBucketInfos', + error: err, }); + if (err && err instanceof ArsenalError) { + return cb(err); + } + return cb(errors.InternalError); + }); } countItems(log: werelogs.Logger, cb: ArsenalCallback) { @@ -2636,22 +2639,22 @@ class MongoClientInterface { return cb(err); } if (!results || typeof results === 'string') { - log.error('unable to get any count items document') + log.error('unable to get any count items document'); return cb(errors.InternalError); } // overwrite bucket info since we have latest info - /* eslint-disable */ + results.bucketList = retBucketInfos; results.buckets = bucketCount; results.bucketWithQuotaCount = bucketWithQuotaCount; - /* eslint-enable */ + return cb(null, results); }); }); } consolidateData(store, dataManaged) { - /* eslint-disable */ + if (dataManaged && dataManaged.locations && dataManaged.total) { const locations = dataManaged.locations; store.dataManaged.total.curr += dataManaged.total.curr; @@ -2668,7 +2671,7 @@ class MongoClientInterface { } }); } - /* eslint-enable */ + } scanItemCount(log, cb) { @@ -2965,7 +2968,7 @@ class MongoClientInterface { this._isReplicationEntryStalled(res, cmpDate)) { stalledCount++; } - } else if (!!res.value.versionId) { + } else if (res.value.versionId) { // master version targetCount = 'masterCount'; targetData = 'masterData'; @@ -2983,20 +2986,20 @@ class MongoClientInterface { } }); }).then(() => { - const bucketStatus = bucketInfo.getVersioningConfiguration(); - const isVer = (bucketStatus && + const bucketStatus = bucketInfo.getVersioningConfiguration(); + const isVer = (bucketStatus && (bucketStatus.Status === 'Enabled' || bucketStatus.Status === 'Suspended')); - const retResult = this._handleResults(collRes, isVer); - retResult.stalled = stalledCount; - return callback(null, retResult); - }).catch(err => { - log.error('Error when processing mongo entries', { - method: 'getObjectMDStats', - error: err, - }); - return callback(err); + const retResult = this._handleResults(collRes, isVer); + retResult.stalled = stalledCount; + return callback(null, retResult); + }).catch(err => { + log.error('Error when processing mongo entries', { + method: 'getObjectMDStats', + error: err, }); + return callback(err); + }); } getIngestionBuckets(log: werelogs.Logger, cb: ArsenalCallback) { @@ -3027,7 +3030,8 @@ class MongoClientInterface { * @warning this method only work on master keys, and will thus break * when the object is versionned */ - deleteObjectWithCond(bucketName: string, objName: string, params: ObjectMDOperationParams, log: werelogs.Logger, cb: ArsenalCallback) { + deleteObjectWithCond(bucketName: string, objName: string, params: ObjectMDOperationParams, + log: werelogs.Logger, cb: ArsenalCallback) { const c = this.getCollection(bucketName); const method = 'deleteObjectWithCond'; this.getBucketVFormat(bucketName, log, (err, vFormat?) => { @@ -3158,7 +3162,8 @@ class MongoClientInterface { * @param {Function} cb callback * @return {undefined} */ - deleteBucketIndexes(bucketName: string, indexSpecs: { name: string }[], log: werelogs.Logger, cb: ArsenalCallback) { + deleteBucketIndexes(bucketName: string, indexSpecs: { name: string }[], + log: werelogs.Logger, cb: ArsenalCallback) { const c = this.getCollection(bucketName); async.each(indexSpecs, (spec, next) => c.dropIndex(spec.name).then(() => next()).catch(err => next(err)), diff --git a/lib/storage/metadata/mongoclient/utils.ts b/lib/storage/metadata/mongoclient/utils.ts index 67cb0a808..b62f3e798 100644 --- a/lib/storage/metadata/mongoclient/utils.ts +++ b/lib/storage/metadata/mongoclient/utils.ts @@ -52,7 +52,7 @@ function unescape(obj: Record): Record { function serialize(objMD: ObjectMetadata): void { // Tags require special handling since dot and dollar are accepted if (objMD.tags) { - // eslint-disable-next-line + objMD.tags = escape(objMD.tags); } } @@ -76,7 +76,7 @@ function _assignCondition(prefix: string, object: Record, cond: Con if (!validateConditionsObject(cond) || prefix === '') { throw errors.InternalError; } - // eslint-disable-next-line no-param-reassign + object[prefix] = cond; } @@ -226,7 +226,7 @@ function indexFormatObjectToMongoArray(indexObj: Index[]): MongoIndex[] { const key = new Map(); idx.keys.forEach(k => key.set(k.key, k.order)); - const { keys: _, ...toCopy } = idx; + const { ...toCopy } = idx; return { ...toCopy, name: idx.name, key }; }); } diff --git a/lib/versioning/VersionID.ts b/lib/versioning/VersionID.ts index d21f3fcdb..39dcf20d1 100644 --- a/lib/versioning/VersionID.ts +++ b/lib/versioning/VersionID.ts @@ -21,7 +21,7 @@ const TEMPLATE_TS = new Array(LENGTH_TS + 1).join('0'); const TEMPLATE_SEQ = new Array(LENGTH_SEQ + 1).join('0'); const TEMPLATE_RG = new Array(LENGTH_RG + 1).join(' '); -export let S3_VERSION_ID_ENCODING_TYPE = process.env.S3_VERSION_ID_ENCODING_TYPE; +export const S3_VERSION_ID_ENCODING_TYPE = process.env.S3_VERSION_ID_ENCODING_TYPE; /** * Left-pad a string representation of a value with a given template. diff --git a/lib/versioning/constants.ts b/lib/versioning/constants.ts index 64ddb4dde..2b294ad7c 100644 --- a/lib/versioning/constants.ts +++ b/lib/versioning/constants.ts @@ -1,5 +1,4 @@ export enum BucketVersioningFormat { - CURRENT = 'v1', V0 = 'v0', V0MIG = 'v0mig', V0V1 = 'v0v1', @@ -17,12 +16,12 @@ export const VersioningConstants = { Replay: '\x7fR', }, BucketVersioningKeyFormat: { - current: BucketVersioningFormat.CURRENT, + current: BucketVersioningFormat.V1, v0: BucketVersioningFormat.V0, v0mig: BucketVersioningFormat.V0MIG, v0v1: BucketVersioningFormat.V0V1, v1mig: BucketVersioningFormat.V1MIG, v1: BucketVersioningFormat.V1, }, - ExternalNullVersionId: 'null', + ExternalNullVersionId: 'null', };