Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,38 @@ import { from, to } from './shared';
import { TargetField } from './common_fields/target_field';
import { PropertiesField } from './common_fields/properties_field';
import type { GeoipDatabase } from '../../../../../../../common/types';
import { getDatabaseText, getDatabaseValue } from '../../../../../sections/manage_processors/utils';
import {
getDatabaseOptionLabel,
getDatabaseText,
getDatabaseValue,
normalizeMmdbFilename,
MMDB_EXTENSION,
} from '../../../../../sections/manage_processors/utils';
import { getTypeLabel } from '../../../../../sections/manage_processors/constants';

const extension = '.mmdb';

const fieldsConfig: FieldsConfig = {
/* Optional field config */
database_file: {
type: FIELD_TYPES.COMBO_BOX,
deserializer: (v: unknown) =>
to.arrayOfStrings(v).map((str) => {
const databaseName = str?.split(extension)[0];
// Use the translated text for this database, if it exists
return getDatabaseText(databaseName) ?? databaseName;
const databaseName = str.split(MMDB_EXTENSION)[0];
const knownDatabaseText = getDatabaseText(databaseName);
// Known managed DB → return display text (e.g. "ASN" for standard_asn)
// Local DB → return full filename (e.g. "ASN.mmdb") to match the combo box label
return knownDatabaseText ?? str;
}),
serializer: (v: any[]) => {
if (v.length) {
const databaseName = v[0];
// Local databases have the extension already in the label
if (typeof databaseName === 'string' && databaseName.endsWith(MMDB_EXTENSION)) {
return normalizeMmdbFilename(databaseName);
}
const databaseValue = getDatabaseValue(databaseName);
return databaseValue ? `${databaseValue}${extension}` : `${databaseName}${extension}`;
return databaseValue
? `${databaseValue}${MMDB_EXTENSION}`
: `${databaseName}${MMDB_EXTENSION}`;
}
return undefined;
},
Expand Down Expand Up @@ -92,8 +104,8 @@ export const IpLocation: FunctionComponent = () => {
const dataAsOptions = (data || []).map((item) => ({
id: item.id,
type: item.type,
// Use the translated text for this database, if it exists
label: getDatabaseText(item.name) ?? item.name,
// Use the name of the database file for local databases and the translated text for others, if it exists
label: getDatabaseOptionLabel(item),
}));
const optionsByGroup = groupBy(dataAsOptions, 'type');
const groupedOptions = map(optionsByGroup, (items, groupName) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
* 2.0.
*/

import { getDatabaseValue, getDatabaseText } from './utils';
import {
getDatabaseOptionLabel,
getDatabaseText,
getDatabaseValue,
normalizeMmdbFilename,
} from './utils';

describe('getDatabaseValue', () => {
it('should return the value for a given database text for maxmind', () => {
Expand Down Expand Up @@ -58,3 +63,38 @@ describe('getDatabaseText', () => {
expect(result).toBe('IP Geolocation');
});
});

describe('normalizeMmdbFilename', () => {
it('should add .mmdb when missing', () => {
expect(normalizeMmdbFilename('GeoLite2-City')).toBe('GeoLite2-City.mmdb');
});

it('should keep a single .mmdb suffix', () => {
expect(normalizeMmdbFilename('GeoLite2-City.mmdb')).toBe('GeoLite2-City.mmdb');
});

it('should collapse repeated .mmdb suffixes', () => {
expect(normalizeMmdbFilename('GeoLite2-City.mmdb.mmdb')).toBe('GeoLite2-City.mmdb');
});
});

describe('getDatabaseOptionLabel', () => {
it('should return the database filename for local databases', () => {
expect(getDatabaseOptionLabel({ type: 'local', name: 'GeoLite2-City' })).toBe(
'GeoLite2-City.mmdb'
);
expect(getDatabaseOptionLabel({ type: 'local', name: 'GeoLite2-City.mmdb' })).toBe(
'GeoLite2-City.mmdb'
);
});

it('should return translated text for known managed databases', () => {
expect(getDatabaseOptionLabel({ type: 'maxmind', name: 'standard_asn' })).toBe('ASN');
});

it('should fallback to name when no translation exists', () => {
expect(getDatabaseOptionLabel({ type: 'maxmind', name: 'something_else' })).toBe(
'something_else'
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import type { DatabaseType, DatabaseNameOption } from '../../../../common/types';
import { GEOIP_NAME_OPTIONS, IPINFO_NAME_OPTIONS } from './constants';

export const MMDB_EXTENSION = '.mmdb';
const mmdbSuffixRegExp = /(\.mmdb)+$/;

const getDatabaseNameOptions = (type?: DatabaseType): DatabaseNameOption[] => {
switch (type) {
case 'maxmind':
Expand Down Expand Up @@ -42,3 +45,29 @@ export const getDatabaseText = (databaseValue: string, type?: DatabaseType): str
const options = getDatabaseNameOptions(type);
return options.find((opt) => opt.value === databaseValue)?.text;
};

/**
* Returns the normalized filename of the database.
* @param name The name of the database
* @returns The normalized filename of the database
*/
export const normalizeMmdbFilename = (name: string) => {
if (name.endsWith(MMDB_EXTENSION)) {
return name.replace(mmdbSuffixRegExp, MMDB_EXTENSION);
}

return `${name}${MMDB_EXTENSION}`;
};

/**
* Returns the label of the database, if it exists.
* @param item The database item
* @returns The label of the database
*/
export const getDatabaseOptionLabel = (item: { type: DatabaseType; name: string }) => {
if (item.type === 'local') {
return normalizeMmdbFilename(item.name);
}

return getDatabaseText(item.name) ?? item.name;
};
Loading