some bug fix

This commit is contained in:
undefined committed 2020-07-03 22:54:07 +08:00
1 parent 57f711ed4f
commit fb5c29226b
11 files changed
+57 -44

No files matched your search

+1 -1
View File
@@ -2,4 +2,4 @@ FROM mhart/alpine-node:slim-10
WORKDIR /app
COPY .build /app
EXPOSE 8888
CMD ["node", ".build/development.js"]
CMD ["node", ".build/app.js"]
+2 -2
View File
@@ -6,11 +6,11 @@ services:
links:
- mongo
volumes:
- ./config.yaml:/config/config.yaml
- ./data/config:/config
ports:
- 8888:8888
mongo:
image: mongo:latest
restart: always
volumes:
- ./db:/data/db
- ./data/db:/data/db
+10 -10
View File
@@ -33,11 +33,11 @@ class HydroError extends Error {
const UserFacingError = Err('UserFacingError', HydroError, 'UserFacingError', 400);
const SystemError = Err('SystemError', HydroError, 'SystemError', 500);
const BadRequestError = Err('BadRequestError', UserFacingError, 400);
const ForbiddenError = Err('ForbiddenError', UserFacingError, 403);
const NotFoundError = Err('NotFoundError', UserFacingError, 404);
const MethodNotAllowedError = Err('MethodNotAllowedError', UserFacingError, 405);
const RemoteOnlineJudgeError = Err('RemoteOnlineJudgeError', UserFacingError, 500);
const BadRequestError = Err('BadRequestError', UserFacingError, 'BadRequestError', 400);
const ForbiddenError = Err('ForbiddenError', UserFacingError, 'ForbiddenError', 403);
const NotFoundError = Err('NotFoundError', UserFacingError, 'NotFoundError', 404);
const MethodNotAllowedError = Err('MethodNotAllowedError', UserFacingError, 'MethodNotAllowedError', 405);
const RemoteOnlineJudgeError = Err('RemoteOnlineJudgeError', UserFacingError, 'RemoteOnlineJudgeError', 500);
const AlreadyVotedError = Err('AlreadyVotedError', ForbiddenError, "You've already voted.");
const LoginError = Err('LoginError', ForbiddenError, 'Invalid password for user {0}.');
@@ -63,7 +63,7 @@ const ContestNotLiveError = Err('ContestNotLiveError', ForbiddenError, 'This con
const ContestScoreboardHiddenError = Err('ContestScoreboardHiddenError', ForbiddenError, 'Contest scoreboard is not visible.');
const TrainingAlreadyEnrollError = Err('TrainingAlreadyEnrollError', ForbiddenError, "You've already enrolled this training.");
const RoleAlreadyExistError = Err('RoleAlreadyExistError', ForbiddenError, 'This role already exists.');
const CsrfTokenError = Err('CsrfTokenError', ForbiddenError);
const CsrfTokenError = Err('CsrfTokenError', ForbiddenError, 'CsrfTokenError');
const UserNotFoundError = Err('UserNotFoundError', NotFoundError, 'User {0} not found.');
const NoProblemError = Err('NoProblemError', NotFoundError, 'No problem.');
@@ -72,10 +72,10 @@ const ProblemDataNotFoundError = Err('ProblemDataNotFoundError', NotFoundError,
const MessageNotFoundError = Err('MessageNotFoundError', NotFoundError, 'Message {0} not found.');
const DocumentNotFoundError = Err('DocumentNotFoundError', NotFoundError, 'Document {2} not found.');
const ProblemNotFoundError = Err('ProblemNotFountError', DocumentNotFoundError, 'Problem {1} not found.');
const SolutionNotFoundError = Err('SolutionNotFoundError', DocumentNotFoundError);
const TrainingNotFoundError = Err('TrainingNotFoundError', DocumentNotFoundError);
const ContestNotFoundError = Err('ContestNotFoundError', DocumentNotFoundError);
const ProblemNotFoundError = Err('ProblemNotFountError', DocumentNotFoundError, 'Problem {0} not found.');
const SolutionNotFoundError = Err('SolutionNotFoundError', DocumentNotFoundError, 'Solution {0} not found.');
const TrainingNotFoundError = Err('TrainingNotFoundError', DocumentNotFoundError, 'Training {0} not found.');
const ContestNotFoundError = Err('ContestNotFoundError', DocumentNotFoundError, 'Contest {0} not found.');
const DiscussionNotFoundError = Err('DiscussionNotFoundError', DocumentNotFoundError, 'Discussion {0} not found.');
const DiscussionNodeNotFoundError = Err('DiscussionNodeNotFoundError', DocumentNotFoundError, 'Discussion node {1} not found.');
+1 -1
View File
@@ -43,7 +43,7 @@ class UserLoginHandler extends Handler {
await user.setById(udoc._id, { loginat: new Date(), loginip: this.request.ip });
if (udoc.priv === PRIV_NONE) throw new BlacklistedError(uname);
this.session.uid = udoc._id;
this.session.rememberme = rememberme;
this.session.save = rememberme;
this.response.redirect = this.request.referer.endsWith('/login') ? '/' : this.request.referer;
}
}
+2 -2
View File
@@ -28,7 +28,7 @@ async function add(tokenType, expireSeconds, data) {
updateAt: now,
expireAt: new Date(now.getTime() + expireSeconds * 1000),
});
return [str, res.ops];
return [str, res.ops[0]];
}
/**
@@ -109,7 +109,7 @@ global.Hydro.model.token = module.exports = {
get,
update,
del,
deleteByUid(uid) {
delByUid(uid) {
return coll.deleteMany({ uid });
},
getMostRecentSessionByUid(uid) {
+36 -28
View File
@@ -234,7 +234,6 @@ const Handler = HandlerMixin(class {
cdn_prefix: '/',
url_prefix: '/',
};
this._handler = {};
this.session = {};
}
@@ -255,34 +254,37 @@ const Handler = HandlerMixin(class {
this.response.disposition = `attachment; filename="${name}"`;
}
async init({ domainId }) {
this.response.body = {};
this.now = new Date();
this._handler.sid = this.request.cookies.get('sid');
this._handler.save = this.request.cookies.get('save');
if (this._handler.save) this._handler.expireSeconds = await system.get('session.saved_expire_seconds');
else this._handler.expireSeconds = await system.get('session.unsaved_expire_seconds');
this.session = this._handler.sid
? await token.update(
this._handler.sid,
token.TYPE_SESSION,
this._handler.expireSeconds,
{
updateIp: this.request.ip,
updateUa: this.request.headers['user-agent'] || '',
},
) : { uid: 1 };
async getSession() {
const sid = this.request.cookies.get('sid');
this.session = await token.get(sid, token.TYPE_SESSION, false);
if (!this.session) this.session = { uid: 0 };
}
async getBdoc() {
const bdoc = await blacklist.get(this.request.ip);
if (bdoc) throw new BlacklistedError(this.request.ip);
this.user = await user.getById(domainId, this.session.uid);
if (!this.user) throw new UserNotFoundError(this.session.uid);
}
async getCsrfToken() {
this.csrfToken = await token.createOrUpdate(token.TYPE_CSRF_TOKEN, 600, {
path: this.request.path,
uid: this.session.uid,
});
this.UIContext.csrfToken = this.csrfToken;
}
async init({ domainId }) {
this.response.body = {};
this.now = new Date();
this.preferJson = (this.request.headers.accept || '').includes('application/json');
await Promise.all([
this.getSession(),
this.getBdoc(),
]);
[this.user] = await Promise.all([
user.getById(domainId, this.session.uid, true),
this.getCsrfToken(),
]);
}
async checkCsrfToken(csrfToken) {
@@ -339,31 +341,37 @@ const Handler = HandlerMixin(class {
}
async saveCookie() {
const expireSeconds = this.session.save
? await system.get('session.expire_seconds')
: await system.get('session.unsaved_expire_seconds');
if (this.session._id) {
await token.update(
this.session._id,
token.TYPE_SESSION,
this._handler.expireSeconds,
this.session,
expireSeconds,
{
...this.session,
updateIp: this.request.ip,
updateUa: this.request.headers['user-agent'] || '',
},
);
} else {
[this.session._id] = await token.add(
[, this.session] = await token.add(
token.TYPE_SESSION,
this._handler.expireSeconds,
expireSeconds,
{
...this.session,
createIp: this.request.ip,
createUa: this.request.headers['user-agent'] || '',
updateIp: this.request.ip,
updateUa: this.request.headers['user-agent'] || '',
...this.session,
},
);
}
const cookie = { secure: await system.get('session.secure') };
if (this._handler.save) {
if (this.session.save) {
cookie.expires = this.session.expireAt;
cookie.maxAge = this._handler.expireSeconds;
this.ctx.cookies.set('save', 'true', cookie);
cookie.maxAge = expireSeconds;
}
this.ctx.cookies.set('sid', this.session._id, cookie);
}
+1
View File
@@ -33,6 +33,7 @@
{% endif %}
<div class="row"><div class="columns">
<div class="text-center">
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
<input type="submit" value="{{ _('Login') }}" class="inverse expanded rounded primary button">
</div>
</div></div>
+1
View File
@@ -12,6 +12,7 @@
</div></div>
<div class="row"><div class="columns">
<div class="text-center">
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
<input type="submit" value="{{ _('Send Password Reset Email') }}" class="inverse rounded primary button">
</div>
</div></div>
+1
View File
@@ -22,6 +22,7 @@
</label>
</div>
<div class="text-center">
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
<input type="submit" value="{{ _('Reset Password') }}" class="inverse rounded primary button">
</div>
</form>
+1
View File
@@ -12,6 +12,7 @@
</div></div>
<div class="row"><div class="columns">
<div class="text-center">
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
<input type="submit" value="{{ _('Send Verification Email') }}" class="inverse expanded rounded primary button">
</div>
</div></div>
+1
View File
@@ -28,6 +28,7 @@
</label>
</div>
<div class="text-center">
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
<input type="submit" value="{{ _('user_register') }}" class="inverse expanded rounded primary button">
</div>
</form>