diff --git a/packages/hydrojudge/package.json b/packages/hydrojudge/package.json index f228ad49c..228e68cbc 100644 --- a/packages/hydrojudge/package.json +++ b/packages/hydrojudge/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/hydrojudge", - "version": "2.0.4", + "version": "2.0.5", "main": "package.json", "author": "masnn", "os": [ diff --git a/packages/hydrojudge/service.ts b/packages/hydrojudge/src/service.ts similarity index 97% rename from packages/hydrojudge/service.ts rename to packages/hydrojudge/src/service.ts index d999d2163..a727e5b2c 100644 --- a/packages/hydrojudge/service.ts +++ b/packages/hydrojudge/src/service.ts @@ -11,13 +11,13 @@ import { homedir, tmpdir } from 'os'; async function postInit() { // Only start a single daemon if (!cluster.isFirstWorker) return; - const { compilerText } = require('./src/utils'); - const tmpfs = require('./src/tmpfs'); - const { FormatError, CompileError, SystemError } = require('./src/error'); + const { compilerText } = require('./utils'); + const tmpfs = require('./tmpfs'); + const { FormatError, CompileError, SystemError } = require('./error'); const { STATUS_COMPILE_ERROR, STATUS_SYSTEM_ERROR } = global.Hydro.model.builtin.STATUS; - const readYamlCases = require('./src/cases'); - const judge = require('./src/judge'); - const sysinfo = require('./src/sysinfo'); + const readYamlCases = require('./cases'); + const judge = require('./judge'); + const sysinfo = require('./sysinfo'); const { problem, file, task } = global.Hydro.model; const _judge = global.Hydro.handler.judge as any; diff --git a/packages/hydrojudge/tsconfig.json b/packages/hydrojudge/tsconfig.json index ee0b5120f..6c06cb233 100644 --- a/packages/hydrojudge/tsconfig.json +++ b/packages/hydrojudge/tsconfig.json @@ -2,8 +2,8 @@ "compilerOptions": { "target": "es2018", "module": "commonjs", - "outDir": ".", - "rootDir": ".", + "outDir": "dist", + "rootDir": "src", "moduleResolution": "node", "declaration": true, "sourceMap": true, @@ -12,13 +12,7 @@ "resolveJsonModule": true }, "include": [ - "service.ts", "src" ], - "paths": { - "src/*": [ - "dist/*" - ] - }, "exclude": [] } \ No newline at end of file diff --git a/packages/hydrooj/TODO b/packages/hydrooj/TODO index 47ce4524f..a8c8931e2 100644 --- a/packages/hydrooj/TODO +++ b/packages/hydrooj/TODO @@ -4,6 +4,4 @@ SETTINGS_PRIVACY.allowRegisteredUsers model.setting.ui.name pdoc.secretConfig? message.markAsRead -Handle OAuth Map !important -基于document的model难以lint,建议拆分 -写test! !important \ No newline at end of file +基于document的model难以lint,建议拆分 \ No newline at end of file diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index d0565d52a..8198e8bab 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.12.17", + "version": "2.12.18", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index 5be8b8e27..bcb6b2fe2 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -8,6 +8,7 @@ import { Route, Handler, Types, param, } from '../service/server'; import * as user from '../model/user'; +import * as oauth from '../model/oauth'; import * as token from '../model/token'; import * as record from '../model/record'; import * as problem from '../model/problem'; @@ -227,10 +228,9 @@ class OauthCallbackHandler extends Handler { let r; if (global.Hydro.lib[`oauth_${args.type}`]) r = await global.Hydro.lib[`oauth_${args.type}`].callback.call(this, args); else throw new UserFacingError('Oauth type'); - const udoc = await user.getByEmail('system', r.email); - if (udoc) { - this.session.uid = udoc._id; - } else { + const uid = await oauth.get(r._id); + if (uid) this.session.uid = uid; + else { this.checkPriv(PRIV.PRIV_REGISTER_USER); let username = ''; r.uname = r.uname || []; @@ -243,7 +243,7 @@ class OauthCallbackHandler extends Handler { break; } } - const uid = await user.create( + const _id = await user.create( r.email, username, String.random(32), undefined, this.request.ip, ); @@ -252,8 +252,11 @@ class OauthCallbackHandler extends Handler { }; if (r.bio) $set.bio = r.bio; if (r.viewLang) $set.viewLang = r.viewLang; - await user.setById(uid, $set); - this.session.uid = uid; + await Promise.all([ + user.setById(_id, $set), + oauth.set(r.email, _id), + ]); + this.session.uid = _id; } } } diff --git a/packages/hydrooj/src/model/oauth.ts b/packages/hydrooj/src/model/oauth.ts new file mode 100644 index 000000000..f0f0c9b8f --- /dev/null +++ b/packages/hydrooj/src/model/oauth.ts @@ -0,0 +1,36 @@ +import Lru from 'lru-cache'; +import { Collection } from 'mongodb'; +import * as db from '../service/db'; + +interface OauthMap { + _id: string, // source openId + uid: number, // target uid +} + +const coll: Collection = db.collection('oauth'); +const cache = new Lru({ + maxAge: 5000, +}); + +export async function get(_id: string) { + const res = cache.get(_id); + if (res !== undefined) return res; + const doc = await coll.findOne({ _id }); + if (doc) return doc.uid; + return null; +} + +export async function set(_id: string, value: number) { + cache.set(_id, value); + const res = await coll.findOneAndUpdate( + { _id }, + { $set: { value } }, + { upsert: true, returnOriginal: false }, + ); + return res.value.uid; +} + +global.Hydro.model.oauth = { + get, + set, +}; diff --git a/packages/login-with-github/lib.ts b/packages/login-with-github/lib.ts index 5124c5250..816773056 100644 --- a/packages/login-with-github/lib.ts +++ b/packages/login-with-github/lib.ts @@ -46,6 +46,7 @@ async function callback({ state, code }) { .set('User-Agent', 'Hydro-OAuth') .set('Authorization', `token ${t}`); const ret = { + _id: `${userInfo.body.id}@github.local`, email: userInfo.body.email, bio: userInfo.body.bio, uname: [userInfo.body.name, userInfo.body.login], diff --git a/packages/login-with-github/package.json b/packages/login-with-github/package.json index 494341e8e..6aeeb79cc 100644 --- a/packages/login-with-github/package.json +++ b/packages/login-with-github/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/login-with-github", - "version": "0.0.4", + "version": "0.0.5", "main": "package.json", "repository": "git@github.com:hydro-dev/Hydro.git", "author": "undefined ", diff --git a/packages/login-with-google/lib.ts b/packages/login-with-google/lib.ts index c3c3a0ddc..e787bc4d2 100644 --- a/packages/login-with-google/lib.ts +++ b/packages/login-with-google/lib.ts @@ -43,6 +43,8 @@ async function callback({ await token.del(state, token.TYPE_OAUTH); this.response.redirect = s.redirect; return { + // TODO use openid + _id: payload.email, email: payload.email, uname: [payload.given_name, payload.name, payload.family_name], viewLang: payload.locale.replace('-', '_'), diff --git a/packages/login-with-google/package.json b/packages/login-with-google/package.json index 6e82d29da..bf05200e8 100644 --- a/packages/login-with-google/package.json +++ b/packages/login-with-google/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/login-with-google", - "version": "0.0.4", + "version": "0.0.5", "main": "package.json", "repository": "git@github.com:hydro-dev/Hydro.git", "author": "undefined ", diff --git a/packages/login-with-osu/lib.ts b/packages/login-with-osu/lib.ts index ff1bd311a..f7510f89f 100644 --- a/packages/login-with-osu/lib.ts +++ b/packages/login-with-osu/lib.ts @@ -51,6 +51,7 @@ async function callback({ state, code }) { .set('User-Agent', 'Hydro-OAuth') .set('Authorization', `Bearer ${t}`); const ret = { + _id: `${userInfo.body.id}@osu.local`, email: `${userInfo.body.id}@osu.local`, bio: '', uname: [userInfo.body.username], diff --git a/packages/login-with-osu/package.json b/packages/login-with-osu/package.json index 93b874015..1fea35676 100644 --- a/packages/login-with-osu/package.json +++ b/packages/login-with-osu/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/login-with-osu", - "version": "0.0.4", + "version": "0.0.5", "main": "package.json", "repository": "git@github.com:hydro-dev/Hydro.git", "author": "undefined ", diff --git a/packages/login-with-qq/lib.ts b/packages/login-with-qq/lib.ts index 2c2b72e6f..40f64e3be 100644 --- a/packages/login-with-qq/lib.ts +++ b/packages/login-with-qq/lib.ts @@ -20,6 +20,7 @@ async function callback({ state }) { const s = await token.get(state, token.TYPE_OAUTH); if (!s || !s.email) throw new InvalidTokenError(state); const ret = { + _id: s.email, email: s.email, bio: '', uname: [s.username], diff --git a/packages/login-with-qq/package.json b/packages/login-with-qq/package.json index 58ab94a0c..e7a3d8c48 100644 --- a/packages/login-with-qq/package.json +++ b/packages/login-with-qq/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/login-with-qq", - "version": "0.0.1", + "version": "0.0.2", "main": "package.json", "repository": "git@github.com:hydro-dev/Hydro.git", "author": "undefined ",