From 8c20c34d8b4056fa34cfeb85a811fc2869739539 Mon Sep 17 00:00:00 2001 From: masnn Date: Thu, 11 Jun 2020 13:23:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E6=97=B6=E5=8C=BA=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hydro/handler/contest.js | 12 +-- hydro/handler/home.js | 6 +- hydro/handler/homework.js | 44 ++++++---- hydro/model/contest.js | 2 +- hydro/model/setting.js | 13 ++- hydro/model/user.js | 1 + hydro/service/server.js | 8 +- package.json | 3 +- yarn.lock | 178 +++++++++++++++++++++++--------------- 9 files changed, 163 insertions(+), 104 deletions(-) diff --git a/hydro/handler/contest.js b/hydro/handler/contest.js index 2fb911895..8817b70e0 100644 --- a/hydro/handler/contest.js +++ b/hydro/handler/contest.js @@ -1,3 +1,4 @@ +const moment = require('moment-timezone'); const { ContestNotLiveError, ValidationError, ProblemNotFoundError, ContestNotAttendedError, @@ -150,12 +151,13 @@ class ContestEditHandler extends ContestDetailHandler { }) { let beginAt; try { - beginAt = new Date(Date.parse(`${beginAtDate} ${beginAtTime.replace('-', ':')}`)); + beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.uset.timeZone); } catch (e) { throw new ValidationError('beginAtDate', 'beginAtTime'); } - const endAt = new Date(beginAt + duration * 3600 * 1000); - if (beginAt >= endAt) throw new ValidationError('duration'); + const endAt = beginAt.add(duration, 'hours').toDate(); + if (beginAt.isSameOrAfter(endAt)) throw new ValidationError('duration'); + beginAt = beginAt.toDate(); pids = await this.verifyProblems(domainId, pids); await contest.edit(domainId, this.tdoc.docId, title, content, rule, beginAt, endAt, pids); if (this.tdoc.beginAt !== beginAt || this.tdoc.endAt !== endAt @@ -286,11 +288,11 @@ class ContestCreateHandler extends ContestHandler { }) { let beginAt; try { - beginAt = new Date(Date.parse(`${beginAtDate} ${beginAtTime.replace('-', ':')}`)); + beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone); } catch (e) { throw new ValidationError('beginAtDate', 'beginAtTime'); } - const endAt = beginAt.delta({ hour: duration }); + const endAt = beginAt.add(duration, 'hours'); pids = await this.verifyProblems(domainId, pids); const tid = await contest.add( domainId, title, content, diff --git a/hydro/handler/home.js b/hydro/handler/home.js index 6942e7fcc..67d175502 100644 --- a/hydro/handler/home.js +++ b/hydro/handler/home.js @@ -160,7 +160,7 @@ class HomeSettingsHandler extends Handler { async get({ category }) { const path = [ ['Hydro', '/'], - ['home_settings', null], + [`home_${category}`, null], ]; this.response.template = 'home_settings.html'; this.response.body = { @@ -179,11 +179,11 @@ class HomeSettingsHandler extends Handler { async post(args) { const $set = {}; for (const key in args) { - if (setting.SETTINGS_BY_KEY[args]) { + if (setting.SETTINGS_BY_KEY[key]) { $set[key] = args[key]; } } - await user.setById(args.domainId, this.user._id, $set); + await user.setById(this.user._id, $set); this.back(); } } diff --git a/hydro/handler/homework.js b/hydro/handler/homework.js index 1e02acaac..96e6f08c2 100644 --- a/hydro/handler/homework.js +++ b/hydro/handler/homework.js @@ -1,4 +1,5 @@ const yaml = require('js-yaml'); +const moment = require('moment-timezone'); const { ValidationError, HomeworkNotLiveError, ProblemNotFoundError, HomeworkNotAttendedError, @@ -174,8 +175,8 @@ class HomeworkDetailProblemSubmitHandler extends HomeworkDetailProblemHandler { class HomeworkCreateHandler extends HomeworkHandler { async get() { - const beginAt = new Date().delta({ day: 1 }); - const penaltySince = beginAt.delta({ day: 7 }); + const beginAt = moment().add(1, 'day'); + const penaltySince = beginAt.add(7, 'days'); const path = [ ['Hydro', '/'], ['homework_main', '/homework'], @@ -184,9 +185,9 @@ class HomeworkCreateHandler extends HomeworkHandler { this.response.template = 'homework_edit.html'; this.response.body = { path, - dateBeginText: beginAt.format('%Y-%m-%d'), + dateBeginText: beginAt.tz(this.user.timeZone).format('YYYY-M-D'), timeBeginText: '00:00', - datePenaltyText: penaltySince.format('%Y-%m-%d'), + datePenaltyText: penaltySince.tz(this.user.timeZone).format('YYYY-M-D'), timePenaltyText: '23:59', pids: '1000, 1001', extensionDays: 1, @@ -202,21 +203,23 @@ class HomeworkCreateHandler extends HomeworkHandler { let beginAt; let penaltySince; try { - beginAt = new Date(Date.parse(`${beginAtDate} ${beginAtTime.replace('-', ':')}`)); + beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone); } catch (e) { throw new ValidationError('beginAtDate', 'beginAtTime'); } try { - penaltySince = new Date(Date.parse(`${penaltySinceDate} ${penaltySinceTime.replace('-', ':')}`)); + penaltySince = moment.tz(`${penaltySinceDate} ${penaltySinceTime}`, this.user.timeZone); } catch (e) { throw new ValidationError('endAtDate', 'endAtTime'); } - const endAt = penaltySince.delta({ days: extensionDays }); - if (beginAt >= penaltySince) { throw new ValidationError('endAtDate', 'endAtTime'); } - if (penaltySince > endAt) throw new ValidationError('extensionDays'); + const endAt = penaltySince.add(extensionDays, 'days'); + if (beginAt.isSameOrAfter(penaltySince)) throw new ValidationError('endAtDate', 'endAtTime'); + if (penaltySince.isAfter(endAt)) throw new ValidationError('extensionDays'); + penaltySince = penaltySince.toDate(); await this.verifyProblems(domainId, pids); const tid = await contest.add(domainId, title, content, this.user._id, - 'homework', beginAt, endAt, pids, rated, { penaltySince, penaltyRules }, document.TYPE_HOMEWORK); + 'homework', beginAt.toDate(), endAt.toDate(), pids, rated, + { penaltySince, penaltyRules }, document.TYPE_HOMEWORK); this.response.body = { tid }; this.response.redirect = `/homework/${tid}`; } @@ -235,13 +238,15 @@ class HomeworkEditHandler extends HomeworkHandler { [tdoc.title, `/homework/${tid}`, true], ['homework_edit', null], ]; + const beginAt = moment(tdoc.beginAt).tz(this.user.timeZone); + const penaltySince = moment(tdoc.penaltySince).tz(this.user.timeZone); this.response.template = 'homework_edit.html'; this.response.body = { tdoc, - dateBeginText: tdoc.beginAt.format('%Y-%m-%d'), - timeBeginText: tdoc.beginAt.format('%H:%M'), - datePenaltyText: tdoc.penaltySince.format('%Y-%m-%d'), - timePenaltyText: tdoc.penaltySince.format('%H:%M'), + dateBeginText: beginAt.format('YYYY-M-D'), + timeBeginText: beginAt.format('hh:mm'), + datePenaltyText: penaltySince.format('YYYY-M-D'), + timePenaltyText: penaltySince.format('hh:mm'), extensionDays, penaltyRules: yaml.safeDump(tdoc.penaltyRules), pids: tdoc.pids.join(','), @@ -259,18 +264,21 @@ class HomeworkEditHandler extends HomeworkHandler { let beginAt; let penaltySince; try { - beginAt = new Date(Date.parse(`${beginAtDate} ${beginAtTime.replace('-', ':')}`)); + beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone); } catch (e) { throw new ValidationError('beginAtDate', 'beginAtTime'); } try { - penaltySince = new Date(Date.parse(`${penaltySinceDate} ${penaltySinceTime.replace('-', ':')}`)); + penaltySince = moment.tz(`${penaltySinceDate} ${penaltySinceTime}`, this.user.timeZone); } catch (e) { throw new ValidationError('endAtDate', 'endAtTime'); } - const endAt = penaltySince.delta({ days: extensionDays }); - if (beginAt >= penaltySince) throw new ValidationError('end_at_date', 'end_at_time'); + let endAt = penaltySince.add(extensionDays, 'days'); + if (beginAt.isSameOrAfter(penaltySince)) throw new ValidationError('endAtDate', 'endAtTime'); await this.verifyProblems(domainId, pids); + beginAt = beginAt.toDate(); + endAt = endAt.toDate(); + penaltySince = penaltySince.toDate(); await contest.edit(domainId, tid, { title, content, beginAt, endAt, pids, penaltySince, penaltyRules, }, document.TYPE_HOMEWORK); diff --git a/hydro/model/contest.js b/hydro/model/contest.js index a5e8beab8..28a5c98d2 100644 --- a/hydro/model/contest.js +++ b/hydro/model/contest.js @@ -227,7 +227,7 @@ function add(domainId, title, content, owner, rule, * @param {ObjectID} tid * @param {object} $set * @param {number} type - * @returns {Tdoc} tdoc after modification + * @returns {Promise} tdoc after modification */ async function edit(domainId, tid, $set, type = document.TYPE_CONTEST) { if ($set.rule) { diff --git a/hydro/model/setting.js b/hydro/model/setting.js index 04a73f4c3..3c7110c8d 100644 --- a/hydro/model/setting.js +++ b/hydro/model/setting.js @@ -1,7 +1,16 @@ +const moment = require('moment-timezone'); const builtin = require('./builtin'); const options = require('../options'); const i18n = require('../lib/i18n'); +const countries = moment.tz.countries(); +const tzs = new Set(); +for (const country of countries) { + const tz = moment.tz.zonesForCountry(country); + for (const t of tz) tzs.add(t); +} +const timezones = Array.from(tzs).sort().map((tz) => [tz, tz]); + const Setting = ( family, key, range = null, value = null, ui = 'text', name = '', @@ -11,9 +20,9 @@ const Setting = ( }); const PREFERENCE_SETTINGS = [ - Setting('setting_display', 'viewLang', i18n, + Setting('setting_display', 'viewLang', builtin.VIEW_LANGS.map((i) => [i.code, i.name]), options.default_locale, 'select', 'UI Language'), - Setting('setting_display', 'timezone', [], // TODO(masnn) timezone + Setting('setting_display', 'timezone', timezones, 'Asia/Shanghai', 'select', 'Timezone'), Setting('setting_usage', 'codeLang', builtin.LANG_TEXTS, null, 'select', 'Default Code Language'), diff --git a/hydro/model/user.js b/hydro/model/user.js index 099cb5a0a..6b0e462c0 100644 --- a/hydro/model/user.js +++ b/hydro/model/user.js @@ -19,6 +19,7 @@ class USER { this.salt = () => udoc.salt; this.hash = () => udoc.hash; this.priv = udoc.priv; + this.timeZone = udoc.timeZone || 'Asia/Shanghai'; this.viewLang = udoc.viewLang || 'zh_CN'; this.codeLang = udoc.codeLang || 'c'; this.codeTemplate = udoc.codeTemplate || ''; diff --git a/hydro/service/server.js b/hydro/service/server.js index 92109db89..de8da7182 100644 --- a/hydro/service/server.js +++ b/hydro/service/server.js @@ -306,8 +306,12 @@ function Route(route, RouteHandler, permission = null) { domainId: 'system', ...ctx.params, ...ctx.query, ...ctx.request.body, }; if (h.request.host !== await system.get('server.host')) { - args.domainId = (h.request.url.split('//')[1] || '') - .split(`.${await system.get('server.host')}`)[0] || 'system'; + try { + args.domainId = (h.request.url.split('//')[1] || '') + .split(`.${await system.get('server.host')}`)[0] || 'system'; + } catch (e) { + // Ignore + } } if (h.___prepare) await h.___prepare(args); diff --git a/package.json b/package.json index 303a1c1c1..c40a19f44 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "lodash": "^4.17.15", "markdown-it": "^10.0.0", "markdown-it-katex": "^2.0.3", + "moment-timezone": "^0.5.31", "mongodb": "^3.5.7", "nodemailer": "^6.3.1", "nunjucks": "^3.2.1", @@ -48,4 +49,4 @@ ".build/module/**" ] } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 2d04ce96d..78b206293 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41,10 +41,15 @@ "@types/events" "*" "@types/node" "*" +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + "@types/node@*": - version "13.11.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" - integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g== + version "14.0.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.13.tgz#ee1128e881b874c371374c1f72201893616417c9" + integrity sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA== "@webassemblyjs/ast@1.9.0": version "1.9.0" @@ -354,7 +359,7 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-includes@^3.0.3: +array-includes@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== @@ -368,7 +373,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.1: +array.prototype.flat@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== @@ -1244,11 +1249,6 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -error-inject@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" - integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= - error-stack-parser@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" @@ -1301,7 +1301,7 @@ eslint-config-airbnb-base@^14.1.0: object.assign "^4.1.0" object.entries "^1.1.1" -eslint-import-resolver-node@^0.3.2: +eslint-import-resolver-node@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg== @@ -1309,7 +1309,7 @@ eslint-import-resolver-node@^0.3.2: debug "^2.6.9" resolve "^1.13.1" -eslint-module-utils@^2.4.1: +eslint-module-utils@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== @@ -1318,22 +1318,23 @@ eslint-module-utils@^2.4.1: pkg-dir "^2.0.0" eslint-plugin-import@^2.20.2: - version "2.20.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d" - integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg== + version "2.21.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c" + integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA== dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" + array-includes "^3.1.1" + array.prototype.flat "^1.2.3" contains-path "^0.1.0" debug "^2.6.9" doctrine "1.5.0" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.4.1" + eslint-import-resolver-node "^0.3.3" + eslint-module-utils "^2.6.0" has "^1.0.3" minimatch "^3.0.4" - object.values "^1.1.0" + object.values "^1.1.1" read-pkg-up "^2.0.0" - resolve "^1.12.0" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" eslint-scope@^4.0.3: version "4.0.3" @@ -1756,16 +1757,11 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" -graceful-fs@^4.1.11, graceful-fs@^4.1.15: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -2012,9 +2008,9 @@ is-buffer@^1.1.5: integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== is-data-descriptor@^0.1.4: version "0.1.4" @@ -2124,11 +2120,11 @@ is-promise@^2.1.0: integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== dependencies: - has "^1.0.3" + has-symbols "^1.0.1" is-string@^1.0.5: version "1.0.5" @@ -2185,9 +2181,9 @@ js-tokens@^4.0.0: integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -2253,9 +2249,9 @@ kind-of@^6.0.0, kind-of@^6.0.2: integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== koa-body@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/koa-body/-/koa-body-4.1.1.tgz#50686d290891fc6f1acb986cf7cfcd605f855ef0" - integrity sha512-rLb/KVD8qplEcK8Qsu6F4Xw+uHkmx3MWogDVmMX07DpjXizhw3pOEp1ja1MqqAcl0ei75AsrbGVDlySmsUrreA== + version "4.1.3" + resolved "https://registry.yarnpkg.com/koa-body/-/koa-body-4.1.3.tgz#1381c91bd2def7044ba790045bf3cfb2cdbb4c51" + integrity sha512-lSu0zmGqtF8vxzgPqNb7CpsIE05llY4pflkOVct9jN1yGTM7ajLz3wBSh8TrSzMGzguBjgEWizoxHLdMbmzz8A== dependencies: "@types/formidable" "^1.0.31" co-body "^5.1.1" @@ -2312,9 +2308,9 @@ koa-static-cache@^5.1.3: mz "^2.7.0" koa@^2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/koa/-/koa-2.11.0.tgz#fe5a51c46f566d27632dd5dc8fd5d7dd44f935a4" - integrity sha512-EpR9dElBTDlaDgyhDMiLkXrPwp6ZqgAIBvhhmxQ9XN4TFgW+gEz6tkcsNI6BnUbUftrKDjVFj4lW2/J2aNBMMA== + version "2.12.0" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.12.0.tgz#c92bfb42defd86f365c31bf63fe918db11fc5c74" + integrity sha512-WlUBj6PXoVhjI5ljMmlyK+eqkbVFW5XQu8twz6bd4WM2E67IwKgPMu5wIFXGxAsZT7sW5xAB54KhY8WAEkLPug== dependencies: accepts "^1.3.5" cache-content-type "^1.0.0" @@ -2326,7 +2322,6 @@ koa@^2.11.0: depd "^1.1.2" destroy "^1.0.4" encodeurl "^1.0.2" - error-inject "^1.0.0" escape-html "^1.0.3" fresh "~0.5.2" http-assert "^1.3.0" @@ -2533,7 +2528,19 @@ mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== -mime-types@^2.1.18, mime-types@^2.1.8, mime-types@~2.1.24: +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.18, mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime-types@^2.1.8: version "2.1.26" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== @@ -2598,10 +2605,22 @@ mkdirp@^0.5.1, mkdirp@^0.5.3: dependencies: minimist "^1.2.5" +moment-timezone@^0.5.31: + version "0.5.31" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.31.tgz#9c40d8c5026f0c7ab46eda3d63e49c155148de05" + integrity sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA== + dependencies: + moment ">= 2.9.0" + +"moment@>= 2.9.0": + version "2.26.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a" + integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw== + mongodb@^3.5.7: - version "3.5.7" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.5.7.tgz#6dcfff3bdbf67a53263dcca1647c265eea1d065d" - integrity sha512-lMtleRT+vIgY/JhhTn1nyGwnSMmJkJELp+4ZbrjctrnBxuLbj6rmLuJFz8W2xUzUqWmqoyVxJLYuC58ZKpcTYQ== + version "3.5.8" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.5.8.tgz#34550856449b745d145873734bf922c12d6b9caa" + integrity sha512-jz7mR58z66JKL8Px4ZY+FXbgB7d0a0hEGCT7kw8iye46/gsqPrOEpZOswwJ2BQlfzsrCLKdsF9UcaUfGVN2HrQ== dependencies: bl "^2.2.0" bson "^1.1.4" @@ -2730,9 +2749,9 @@ node-libs-browser@^2.2.1: vm-browserify "^1.0.1" nodemailer@^6.3.1: - version "6.4.6" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.6.tgz#d37f504f6560b36616f646a606894fe18819107f" - integrity sha512-/kJ+FYVEm2HuUlw87hjSqTss+GU35D4giOpdSfGp7DO+5h6RlJj7R94YaYHOkoxu1CSaM0d3WRBtCzwXrY6MKA== + version "6.4.8" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.8.tgz#aca52886e4e56f71f6b8a65f5ca6b767ca751fc7" + integrity sha512-UbJD0+g5e2H20bWv7Rpj3B+N3TMMJ0MLoLwaGVJ0k3Vo8upq0UltwHJ5BJfrpST1vFa91JQ8cf7cICK5DSIo1Q== normalize-package-data@^2.3.2: version "2.5.0" @@ -2825,7 +2844,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0: +object.values@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== @@ -3155,9 +3174,9 @@ punycode@^2.1.0: integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@^6.4.0: - version "6.9.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" - integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + version "6.9.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" + integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== querystring-es3@^0.2.0: version "0.2.1" @@ -3300,10 +3319,10 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== +resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" @@ -3368,11 +3387,16 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== +safe-buffer@^5.1.1, safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -3561,22 +3585,22 @@ sparse-bitfield@^3.0.3: memory-pager "^1.0.2" spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" @@ -3787,9 +3811,9 @@ supports-color@^7.1.0: has-flag "^4.0.0" systeminformation@^4.26.5: - version "4.26.5" - resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-4.26.5.tgz#d2dc77d4cc54b38345d552fcfd00344f49a964a4" - integrity sha512-hTVhCYNIsoDtL8brW6wg/UTHmyRfMRItd/+6f6JZtXjmx06FHKBGCyBe7WN6J+FiDIiDfTK7mvMq7hljM6r5OA== + version "4.26.9" + resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-4.26.9.tgz#ecc725a162c0c7d8d48226f97637a5f590042ffd" + integrity sha512-69MTIX9j//wnteJzQWuGL6FiMxlfS3wTWyhROI6pNUaQALYqJb3W9VtLVcEcKFOjO1vrGRgilJVFzJeRRi//Pg== table@^5.2.3: version "5.4.6" @@ -3923,6 +3947,16 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +tsconfig-paths@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" + integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + tslib@^1.9.0: version "1.11.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"