mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
geoip: use context.service
This commit is contained in:
1 parent
63c9c00d1d
commit
d94e3e650a
6 files changed
+65
-64
No files matched your search
@@ -0,0 +1,34 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import { Reader } from 'maxmind';
|
||||||
|
import { Context, findFileSync, Service } from 'hydrooj';
|
||||||
|
|
||||||
|
const buffer = fs.readFileSync(findFileSync('@hydrooj/geoip/GeoLite2-City.mmdb'));
|
||||||
|
const reader = new Reader(buffer);
|
||||||
|
|
||||||
|
export interface Result {
|
||||||
|
location?: string,
|
||||||
|
continent?: string,
|
||||||
|
country?: string,
|
||||||
|
city?: string,
|
||||||
|
display: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apply() {
|
||||||
|
Context.service('geoip', class GeoIPService extends Service {
|
||||||
|
provider = '<a href="http://www.maxmind.com" target="_blank">MaxMind</a>';
|
||||||
|
lookup(ip: string, locale: string): Result {
|
||||||
|
const res: any = reader.get(ip);
|
||||||
|
if (!res) return { display: 'Unknown address'.translate(locale) };
|
||||||
|
const ret: Result = { display: '' };
|
||||||
|
if (res.location) ret.location = res.location;
|
||||||
|
if (res.continent) ret.continent = res.continent.names[locale] || res.continent.names.en;
|
||||||
|
if (res.country || res.registered_country) {
|
||||||
|
ret.country = (res.country || res.registered_country).names[locale]
|
||||||
|
|| (res.country || res.registered_country).names.en;
|
||||||
|
}
|
||||||
|
if (res.city) ret.city = res.city.names[locale] || res.city.names.en;
|
||||||
|
ret.display = `${ret.continent} ${ret.country}${ret.city ? ` ${ret.city}` : ''}`;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import 'hydrooj';
|
|
||||||
|
|
||||||
import fs from 'fs';
|
|
||||||
import { Reader } from 'maxmind';
|
|
||||||
import { findFileSync } from '@hydrooj/utils/lib/utils';
|
|
||||||
|
|
||||||
const buffer = fs.readFileSync(findFileSync('@hydrooj/geoip/GeoLite2-City.mmdb'));
|
|
||||||
const reader = new Reader(buffer);
|
|
||||||
|
|
||||||
export interface Result {
|
|
||||||
location?: string,
|
|
||||||
continent?: string,
|
|
||||||
country?: string,
|
|
||||||
city?: string,
|
|
||||||
display: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function lookup(ip: string, locale: string): Result {
|
|
||||||
const res: any = reader.get(ip);
|
|
||||||
if (!res) return { display: 'Unknown address'.translate(locale) };
|
|
||||||
const ret: Result = { display: '' };
|
|
||||||
if (res.location) ret.location = res.location;
|
|
||||||
if (res.continent) ret.continent = res.continent.names[locale] || res.continent.names.en;
|
|
||||||
if (res.country || res.registered_country) {
|
|
||||||
ret.country = (res.country || res.registered_country).names[locale]
|
|
||||||
|| (res.country || res.registered_country).names.en;
|
|
||||||
}
|
|
||||||
if (res.city) ret.city = res.city.names[locale] || res.city.names.en;
|
|
||||||
ret.display = `${ret.continent} ${ret.country}${ret.city ? ` ${ret.city}` : ''}`;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const provider = '<a href="http://www.maxmind.com" target="_blank">MaxMind</a>';
|
|
||||||
|
|
||||||
global.Hydro.lib.geoip = { provider, lookup };
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/geoip",
|
"name": "@hydrooj/geoip",
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"main": "package.json",
|
"main": "index.ts",
|
||||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
@@ -11,8 +11,5 @@
|
|||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublish": "./download.sh"
|
"prepublish": "./download.sh"
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"hydrooj": "*"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as cordis from 'cordis';
|
import * as cordis from 'cordis';
|
||||||
import Schema from 'schemastery';
|
import Schema from 'schemastery';
|
||||||
import { ModuleInterfaces } from './interface';
|
import { GeoIP, ModuleInterfaces } from './interface';
|
||||||
import { inject } from './lib/ui';
|
import { inject } from './lib/ui';
|
||||||
import { Loader } from './loader';
|
import { Loader } from './loader';
|
||||||
import { EventMap } from './service/bus';
|
import { EventMap } from './service/bus';
|
||||||
@@ -33,6 +33,7 @@ export interface Context {
|
|||||||
inject: typeof inject;
|
inject: typeof inject;
|
||||||
api: ApiMixin;
|
api: ApiMixin;
|
||||||
broadcast: Context['emit'];
|
broadcast: Context['emit'];
|
||||||
|
geoip?: GeoIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Context extends cordis.Context {
|
export class Context extends cordis.Context {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { ObjectID } from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
import { camelCase } from '@hydrooj/utils/lib/utils';
|
import { camelCase } from '@hydrooj/utils/lib/utils';
|
||||||
|
import { Context } from '../context';
|
||||||
import {
|
import {
|
||||||
BlacklistedError, DomainAlreadyExistsError, InvalidTokenError,
|
BlacklistedError, DomainAlreadyExistsError, InvalidTokenError,
|
||||||
NotFoundError, PermissionError, UserAlreadyExistError,
|
NotFoundError, PermissionError, UserAlreadyExistError,
|
||||||
@@ -9,6 +10,7 @@ import {
|
|||||||
import { DomainDoc, MessageDoc, Setting } from '../interface';
|
import { DomainDoc, MessageDoc, Setting } from '../interface';
|
||||||
import avatar from '../lib/avatar';
|
import avatar from '../lib/avatar';
|
||||||
import * as mail from '../lib/mail';
|
import * as mail from '../lib/mail';
|
||||||
|
import * as useragent from '../lib/useragent';
|
||||||
import { isDomainId, isEmail, isPassword } from '../lib/validator';
|
import { isDomainId, isEmail, isPassword } from '../lib/validator';
|
||||||
import BlackListModel from '../model/blacklist';
|
import BlackListModel from '../model/blacklist';
|
||||||
import { PERM, PRIV } from '../model/builtin';
|
import { PERM, PRIV } from '../model/builtin';
|
||||||
@@ -28,8 +30,6 @@ import {
|
|||||||
} from '../service/server';
|
} from '../service/server';
|
||||||
import { md5 } from '../utils';
|
import { md5 } from '../utils';
|
||||||
|
|
||||||
const { geoip, useragent } = global.Hydro.lib;
|
|
||||||
|
|
||||||
export class HomeHandler extends Handler {
|
export class HomeHandler extends Handler {
|
||||||
uids = new Set<number>();
|
uids = new Set<number>();
|
||||||
|
|
||||||
@@ -147,6 +147,7 @@ export class HomeHandler extends Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let geoip: Context['geoip'] = null;
|
||||||
class HomeSecurityHandler extends Handler {
|
class HomeSecurityHandler extends Handler {
|
||||||
async get() {
|
async get() {
|
||||||
// TODO(iceboy): pagination? or limit session count for uid?
|
// TODO(iceboy): pagination? or limit session count for uid?
|
||||||
@@ -154,17 +155,18 @@ class HomeSecurityHandler extends Handler {
|
|||||||
for (const session of sessions) {
|
for (const session of sessions) {
|
||||||
session.isCurrent = session._id === this.session._id;
|
session.isCurrent = session._id === this.session._id;
|
||||||
session._id = md5(session._id);
|
session._id = md5(session._id);
|
||||||
if (useragent) session.updateUa = useragent.parse(session.updateUa || session.createUa || '');
|
session.updateUa = useragent.parse(session.updateUa || session.createUa || '');
|
||||||
if (geoip) {
|
session.updateGeoip = geoip?.lookup?.(
|
||||||
session.updateGeoip = geoip.lookup(
|
session.updateIp || session.createIp,
|
||||||
session.updateIp || session.createIp,
|
this.translate('geoip_locale'),
|
||||||
this.translate('geoip_locale'),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.response.template = 'home_security.html';
|
this.response.template = 'home_security.html';
|
||||||
this.response.body = { sessions, geoipProvider: geoip?.provider };
|
this.response.body = {
|
||||||
if (useragent) this.response.body.icon = useragent.icon;
|
sessions,
|
||||||
|
geoipProvider: geoip?.provider,
|
||||||
|
icon: useragent.icon,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@param('current', Types.String)
|
@param('current', Types.String)
|
||||||
@@ -432,7 +434,10 @@ class HomeMessagesConnectionHandler extends ConnectionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function apply(ctx) {
|
export async function apply(ctx: Context) {
|
||||||
|
ctx.using(['geoip'], (g) => {
|
||||||
|
geoip = g.geoip;
|
||||||
|
});
|
||||||
ctx.Route('homepage', '/', HomeHandler);
|
ctx.Route('homepage', '/', HomeHandler);
|
||||||
ctx.Route('home_security', '/home/security', HomeSecurityHandler, PRIV.PRIV_USER_PROFILE);
|
ctx.Route('home_security', '/home/security', HomeSecurityHandler, PRIV.PRIV_USER_PROFILE);
|
||||||
ctx.Route('user_changemail_with_code', '/home/changeMail/:code', UserChangemailWithCodeHandler, PRIV.PRIV_USER_PROFILE);
|
ctx.Route('user_changemail_with_code', '/home/changeMail/:code', UserChangemailWithCodeHandler, PRIV.PRIV_USER_PROFILE);
|
||||||
|
|||||||
@@ -671,18 +671,17 @@ export interface ProblemSearchOptions {
|
|||||||
export type ProblemSearch = (domainId: string, q: string, options?: ProblemSearchOptions) => Promise<ProblemSearchResponse>;
|
export type ProblemSearch = (domainId: string, q: string, options?: ProblemSearchOptions) => Promise<ProblemSearchResponse>;
|
||||||
|
|
||||||
export interface Lib extends Record<string, any> {
|
export interface Lib extends Record<string, any> {
|
||||||
difficulty: typeof import('./lib/difficulty'),
|
difficulty: typeof import('./lib/difficulty');
|
||||||
buildContent: typeof import('./lib/content').buildContent,
|
buildContent: typeof import('./lib/content').buildContent;
|
||||||
i18n: typeof import('./lib/i18n'),
|
i18n: typeof import('./lib/i18n');
|
||||||
mail: typeof import('./lib/mail'),
|
mail: typeof import('./lib/mail');
|
||||||
paginate: typeof import('./lib/paginate'),
|
paginate: typeof import('./lib/paginate');
|
||||||
rank: typeof import('./lib/rank'),
|
rank: typeof import('./lib/rank');
|
||||||
rating: typeof import('./lib/rating'),
|
rating: typeof import('./lib/rating');
|
||||||
testdataConfig: typeof import('./lib/testdataConfig'),
|
testdataConfig: typeof import('./lib/testdataConfig');
|
||||||
useragent: typeof import('./lib/useragent'),
|
useragent: typeof import('./lib/useragent');
|
||||||
validator: typeof import('./lib/validator'),
|
validator: typeof import('./lib/validator');
|
||||||
template?: any,
|
template?: any;
|
||||||
geoip?: GeoIP,
|
|
||||||
problemSearch: ProblemSearch;
|
problemSearch: ProblemSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user