123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- import { pathExists, writeFile } from 'fs-extra'
- import maxmind, { CountryResponse, Reader } from 'maxmind'
- import { join } from 'path'
- import { CONFIG } from '@server/initializers/config'
- import { logger, loggerTagsFactory } from './logger'
- import { isBinaryResponse, peertubeGot } from './requests'
- const lTags = loggerTagsFactory('geo-ip')
- const mmbdFilename = 'dbip-country-lite-latest.mmdb'
- const mmdbPath = join(CONFIG.STORAGE.BIN_DIR, mmbdFilename)
- export class GeoIP {
- private static instance: GeoIP
- private reader: Reader<CountryResponse>
- private constructor () {
- }
- async safeCountryISOLookup (ip: string): Promise<string> {
- if (CONFIG.GEO_IP.ENABLED === false) return null
- await this.initReaderIfNeeded()
- try {
- const result = this.reader.get(ip)
- if (!result) return null
- return result.country.iso_code
- } catch (err) {
- logger.error('Cannot get country from IP.', { err })
- return null
- }
- }
- async updateDatabase () {
- if (CONFIG.GEO_IP.ENABLED === false) return
- const url = CONFIG.GEO_IP.COUNTRY.DATABASE_URL
- logger.info('Updating GeoIP database from %s.', url, lTags())
- const gotOptions = { context: { bodyKBLimit: 200_000 }, responseType: 'buffer' as 'buffer' }
- try {
- const gotResult = await peertubeGot(url, gotOptions)
- if (!isBinaryResponse(gotResult)) {
- throw new Error('Not a binary response')
- }
- await writeFile(mmdbPath, gotResult.body)
- // Reinit reader
- this.reader = undefined
- logger.info('GeoIP database updated %s.', mmdbPath, lTags())
- } catch (err) {
- logger.error('Cannot update GeoIP database from %s.', url, { err, ...lTags() })
- }
- }
- private async initReaderIfNeeded () {
- if (!this.reader) {
- if (!await pathExists(mmdbPath)) {
- await this.updateDatabase()
- }
- this.reader = await maxmind.open(mmdbPath)
- }
- }
- static get Instance () {
- return this.instance || (this.instance = new this())
- }
- }
|