]>
Commit | Line | Data |
---|---|---|
b2111066 C |
1 | import { pathExists, writeFile } from 'fs-extra' |
2 | import maxmind, { CountryResponse, Reader } from 'maxmind' | |
3 | import { join } from 'path' | |
4 | import { CONFIG } from '@server/initializers/config' | |
5 | import { logger, loggerTagsFactory } from './logger' | |
6 | import { isBinaryResponse, peertubeGot } from './requests' | |
7 | ||
8 | const lTags = loggerTagsFactory('geo-ip') | |
9 | ||
10 | const mmbdFilename = 'dbip-country-lite-latest.mmdb' | |
11 | const mmdbPath = join(CONFIG.STORAGE.BIN_DIR, mmbdFilename) | |
12 | ||
13 | export class GeoIP { | |
14 | private static instance: GeoIP | |
15 | ||
16 | private reader: Reader<CountryResponse> | |
17 | ||
18 | private constructor () { | |
19 | } | |
20 | ||
21 | async safeCountryISOLookup (ip: string): Promise<string> { | |
22 | if (CONFIG.GEO_IP.ENABLED === false) return null | |
23 | ||
24 | await this.initReaderIfNeeded() | |
25 | ||
26 | try { | |
27 | const result = this.reader.get(ip) | |
28 | if (!result) return null | |
29 | ||
30 | return result.country.iso_code | |
31 | } catch (err) { | |
32 | logger.error('Cannot get country from IP.', { err }) | |
33 | ||
34 | return null | |
35 | } | |
36 | } | |
37 | ||
38 | async updateDatabase () { | |
39 | if (CONFIG.GEO_IP.ENABLED === false) return | |
40 | ||
41 | const url = CONFIG.GEO_IP.COUNTRY.DATABASE_URL | |
42 | ||
43 | logger.info('Updating GeoIP database from %s.', url, lTags()) | |
44 | ||
45 | const gotOptions = { context: { bodyKBLimit: 200_000 }, responseType: 'buffer' as 'buffer' } | |
46 | ||
47 | try { | |
48 | const gotResult = await peertubeGot(url, gotOptions) | |
49 | ||
50 | if (!isBinaryResponse(gotResult)) { | |
51 | throw new Error('Not a binary response') | |
52 | } | |
53 | ||
54 | await writeFile(mmdbPath, gotResult.body) | |
55 | ||
9295c68b | 56 | // Reinit reader |
b2111066 C |
57 | this.reader = undefined |
58 | ||
59 | logger.info('GeoIP database updated %s.', mmdbPath, lTags()) | |
60 | } catch (err) { | |
61 | logger.error('Cannot update GeoIP database from %s.', url, { err, ...lTags() }) | |
62 | } | |
63 | } | |
64 | ||
65 | private async initReaderIfNeeded () { | |
66 | if (!this.reader) { | |
67 | if (!await pathExists(mmdbPath)) { | |
68 | await this.updateDatabase() | |
69 | } | |
70 | ||
71 | this.reader = await maxmind.open(mmdbPath) | |
72 | } | |
73 | } | |
74 | ||
75 | static get Instance () { | |
76 | return this.instance || (this.instance = new this()) | |
77 | } | |
78 | } |