From 06ddc8ec506fea622989335d9e2ae2c286903231 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Wed, 26 Feb 2020 08:03:23 +0900 Subject: Fix: mainStreamのミュート情報が再接続まで反映されない (#6072) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/api/stream/channels/main.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/server') diff --git a/src/server/api/stream/channels/main.ts b/src/server/api/stream/channels/main.ts index 8cd4fcac99..7419ba4203 100644 --- a/src/server/api/stream/channels/main.ts +++ b/src/server/api/stream/channels/main.ts @@ -1,6 +1,6 @@ import autobind from 'autobind-decorator'; import Channel from '../channel'; -import { Mutings, Notes } from '../../../../models'; +import { Notes } from '../../../../models'; export default class extends Channel { public readonly chName = 'main'; @@ -9,15 +9,13 @@ export default class extends Channel { @autobind public async init(params: any) { - const mute = await Mutings.find({ muterId: this.user!.id }); - // Subscribe main stream channel this.subscriber.on(`mainStream:${this.user!.id}`, async data => { let { type, body } = data; switch (type) { case 'notification': { - if (mute.map(m => m.muteeId).includes(body.userId)) return; + if (this.muting.includes(body.userId)) return; if (body.note && body.note.isHidden) { body.note = await Notes.pack(body.note.id, this.user, { detail: true @@ -26,7 +24,7 @@ export default class extends Channel { break; } case 'mention': { - if (mute.map(m => m.muteeId).includes(body.userId)) return; + if (this.muting.includes(body.userId)) return; if (body.isHidden) { body = await Notes.pack(body.id, this.user, { detail: true -- cgit v1.2.3-freya From c18f6fde80c4672df2d2b98d4ecd45bb2958a97d Mon Sep 17 00:00:00 2001 From: rinsuki <428rinsuki+git@gmail.com> Date: Wed, 4 Mar 2020 11:45:33 +0900 Subject: lintをGitHub Actions でするように (#6101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * package.json の lint スクリプトを修正 * lint アクションを追加 * yarn lint --fix * 手動修正 --- .github/workflows/nodejs.yml | 10 ++++++++++ package.json | 2 +- src/@types/jsrsasign.d.ts | 9 +++------ src/client/directives/size.ts | 2 +- src/client/init.ts | 4 ++-- src/client/mios.ts | 2 +- src/misc/check-hit-antenna.ts | 4 ++-- src/models/entities/clip-note.ts | 2 +- src/models/repositories/user.ts | 4 ++-- src/server/api/endpoints/antennas/create.ts | 4 ++-- src/server/api/endpoints/antennas/update.ts | 4 ++-- src/server/api/stream/channels/main.ts | 3 ++- src/services/add-note-to-antenna.ts | 2 +- src/services/note/create.ts | 2 +- tslint.json | 4 +++- 15 files changed, 34 insertions(+), 24 deletions(-) (limited to 'src/server') diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index d8c29abc37..91668786e2 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -41,3 +41,13 @@ jobs: run: yarn build - name: Test run: yarn test + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12.x + - run: yarn install + - run: yarn lint diff --git a/package.json b/package.json index 4fc350cc2f..fa66bdcf64 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "gulp": "gulp build", "clean": "gulp clean", "cleanall": "gulp cleanall", - "lint": "gulp lint", + "lint": "tslint 'src/**/*.ts'", "test": "cross-env TS_NODE_FILES=true gulp test", "format": "gulp format" }, diff --git a/src/@types/jsrsasign.d.ts b/src/@types/jsrsasign.d.ts index 55bebd9bfb..bc9d746f7e 100644 --- a/src/@types/jsrsasign.d.ts +++ b/src/@types/jsrsasign.d.ts @@ -171,6 +171,7 @@ declare module 'jsrsasign' { public static getTLVbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string): ASN1TLV; + // tslint:disable-next-line:bool-param-default public static getVbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string, removeUnusedbits?: boolean): ASN1V; public static hextooidstr(hex: ASN1OIDV): OID; @@ -620,9 +621,7 @@ declare module 'jsrsasign' { public encrypt(text: string): HexString | null; - public encryptOAEP(text: string, hash?: string, hashLen?: number): HexString | null; - - public encryptOAEP(text: string, hash?: (s: string) => string, hashLen?: number): HexString | null; + public encryptOAEP(text: string, hash?: string | ((s: string) => string), hashLen?: number): HexString | null; //// RSA PRIVATE @@ -638,9 +637,7 @@ declare module 'jsrsasign' { public decrypt(ctext: HexString): string; - public decryptOAEP(ctext: HexString, hash?: string, hashLen?: number): string | null; - - public encryptOAEP(ctext: HexString, hash?: (s: string) => string, hashLen?: number): string | null; + public decryptOAEP(ctext: HexString, hash?: string | ((s: string) => string), hashLen?: number): string | null; //// RSA PEM diff --git a/src/client/directives/size.ts b/src/client/directives/size.ts index c4dd7b145d..541f38fd76 100644 --- a/src/client/directives/size.ts +++ b/src/client/directives/size.ts @@ -59,7 +59,7 @@ export default { const ro = new ResizeObserver((entries, observer) => { calc(); }); - + ro.observe(el); el._ro_ = ro; diff --git a/src/client/init.ts b/src/client/init.ts index 2f2f9f5d59..29eabfee4e 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -81,14 +81,14 @@ if (lang == null) { // Detect the user agent const ua = navigator.userAgent.toLowerCase(); -let isMobile = /mobile|iphone|ipad|android/.test(ua); +const isMobile = /mobile|iphone|ipad|android/.test(ua); // Get the element const head = document.getElementsByTagName('head')[0]; // If mobile, insert the viewport meta tag if (isMobile || window.innerWidth <= 1024) { - const viewport = document.getElementsByName("viewport").item(0); + const viewport = document.getElementsByName('viewport').item(0); viewport.setAttribute('content', `${viewport.getAttribute('content')},minimum-scale=1,maximum-scale=1,user-scalable=no`); head.appendChild(viewport); diff --git a/src/client/mios.ts b/src/client/mios.ts index a29dcd8550..c2ba8ac5cd 100644 --- a/src/client/mios.ts +++ b/src/client/mios.ts @@ -124,7 +124,7 @@ export default class MiOS extends EventEmitter { } else { // Get token from localStorage const i = localStorage.getItem('i'); - + fetchme(i, me => { if (me) { this.store.dispatch('login', me); diff --git a/src/misc/check-hit-antenna.ts b/src/misc/check-hit-antenna.ts index 0d72c3f340..fa24794984 100644 --- a/src/misc/check-hit-antenna.ts +++ b/src/misc/check-hit-antenna.ts @@ -48,7 +48,7 @@ export async function checkHitAntenna(antenna: Antenna, note: Note, noteUser: Us ? note.text!.includes(keyword) : note.text!.toLowerCase().includes(keyword.toLowerCase()) )); - + if (!matched) return false; } @@ -61,7 +61,7 @@ export async function checkHitAntenna(antenna: Antenna, note: Note, noteUser: Us ? note.text!.includes(keyword) : note.text!.toLowerCase().includes(keyword.toLowerCase()) )); - + if (matched) return false; } diff --git a/src/models/entities/clip-note.ts b/src/models/entities/clip-note.ts index 19e4750fc6..7d96b2ef7a 100644 --- a/src/models/entities/clip-note.ts +++ b/src/models/entities/clip-note.ts @@ -8,7 +8,7 @@ import { id } from '../id'; export class ClipNote { @PrimaryColumn(id()) public id: string; - + @Index() @Column({ ...id(), diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts index 1d669feb5e..c6bc35030c 100644 --- a/src/models/repositories/user.ts +++ b/src/models/repositories/user.ts @@ -98,7 +98,7 @@ export class UserRepository extends Repository { public async getHasUnreadAntenna(userId: User['id']): Promise { const antennas = await Antennas.find({ userId }); - + const unread = antennas.length > 0 ? await AntennaNotes.findOne({ antennaId: In(antennas.map(x => x.id)), read: false @@ -112,7 +112,7 @@ export class UserRepository extends Repository { muterId: userId }); const mutedUserIds = mute.map(m => m.muteeId); - + const count = await Notifications.count({ where: { notifieeId: userId, diff --git a/src/server/api/endpoints/antennas/create.ts b/src/server/api/endpoints/antennas/create.ts index f11b198f86..bc79385260 100644 --- a/src/server/api/endpoints/antennas/create.ts +++ b/src/server/api/endpoints/antennas/create.ts @@ -82,7 +82,7 @@ export default define(meta, async (ps, user) => { id: ps.userListId, userId: user.id, }); - + if (userList == null) { throw new ApiError(meta.errors.noSuchUserList); } @@ -91,7 +91,7 @@ export default define(meta, async (ps, user) => { userGroupId: ps.userGroupId, userId: user.id, }); - + if (userGroupJoining == null) { throw new ApiError(meta.errors.noSuchUserGroup); } diff --git a/src/server/api/endpoints/antennas/update.ts b/src/server/api/endpoints/antennas/update.ts index ab4ce57937..b329e86ade 100644 --- a/src/server/api/endpoints/antennas/update.ts +++ b/src/server/api/endpoints/antennas/update.ts @@ -101,7 +101,7 @@ export default define(meta, async (ps, user) => { id: ps.userListId, userId: user.id, }); - + if (userList == null) { throw new ApiError(meta.errors.noSuchUserList); } @@ -110,7 +110,7 @@ export default define(meta, async (ps, user) => { userGroupId: ps.userGroupId, userId: user.id, }); - + if (userGroupJoining == null) { throw new ApiError(meta.errors.noSuchUserGroup); } diff --git a/src/server/api/stream/channels/main.ts b/src/server/api/stream/channels/main.ts index 7419ba4203..22e664baca 100644 --- a/src/server/api/stream/channels/main.ts +++ b/src/server/api/stream/channels/main.ts @@ -11,7 +11,8 @@ export default class extends Channel { public async init(params: any) { // Subscribe main stream channel this.subscriber.on(`mainStream:${this.user!.id}`, async data => { - let { type, body } = data; + const { type } = data; + let { body } = data; switch (type) { case 'notification': { diff --git a/src/services/add-note-to-antenna.ts b/src/services/add-note-to-antenna.ts index 0055639c0b..88a6613c60 100644 --- a/src/services/add-note-to-antenna.ts +++ b/src/services/add-note-to-antenna.ts @@ -38,7 +38,7 @@ export async function addNoteToAntenna(antenna: Antenna, note: Note, noteUser: U if (note.renoteId != null) { _note.renote = await Notes.findOne(note.renoteId).then(ensure); } - + if (shouldMuteThisNote(_note, mutings.map(x => x.muteeId))) { return; } diff --git a/src/services/note/create.ts b/src/services/note/create.ts index a10ee5164b..50586e8bc7 100644 --- a/src/services/note/create.ts +++ b/src/services/note/create.ts @@ -223,7 +223,7 @@ export default async (user: User, data: Option, silent = false) => new Promise f.followerId); - + for (const antenna of antennas) { checkHitAntenna(antenna, note, user, followers).then(hit => { if (hit) { diff --git a/tslint.json b/tslint.json index 733c291f3c..4a072b4ffe 100644 --- a/tslint.json +++ b/tslint.json @@ -61,7 +61,9 @@ "no-duplicated-branches": false, "no-identical-conditions": false, "no-useless-cast": false, - "no-hardcoded-credentials": false + "no-hardcoded-credentials": false, + "no-nested-switch": false, + "unified-signatures": false }, "rulesDirectory": [] } -- cgit v1.2.3-freya From 1947835c5152b7cc9a23bb1a5da0caa953e9d660 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Mar 2020 01:04:36 +0900 Subject: Resolve #6137 --- src/prelude/time.ts | 4 +- src/server/api/endpoints/charts/active-users.ts | 7 +- src/server/api/endpoints/charts/drive.ts | 7 +- src/server/api/endpoints/charts/federation.ts | 7 +- src/server/api/endpoints/charts/hashtag.ts | 7 +- src/server/api/endpoints/charts/instance.ts | 7 +- src/server/api/endpoints/charts/network.ts | 7 +- src/server/api/endpoints/charts/notes.ts | 7 +- src/server/api/endpoints/charts/user/drive.ts | 7 +- src/server/api/endpoints/charts/user/following.ts | 7 +- src/server/api/endpoints/charts/user/notes.ts | 7 +- src/server/api/endpoints/charts/user/reactions.ts | 7 +- src/server/api/endpoints/charts/users.ts | 7 +- src/server/api/endpoints/stats.ts | 6 +- src/services/chart/core.ts | 58 +++++++++++------ test/chart.ts | 79 +++++++++++++++-------- 16 files changed, 167 insertions(+), 64 deletions(-) (limited to 'src/server') diff --git a/src/prelude/time.ts b/src/prelude/time.ts index 0c75d96fe2..77a5fc1af2 100644 --- a/src/prelude/time.ts +++ b/src/prelude/time.ts @@ -1,6 +1,6 @@ const dateTimeIntervals = { - 'days': 86400000, - 'hours': 3600000, + 'day': 86400000, + 'hour': 3600000, }; export function DateUTC(time: number[]): Date { diff --git a/src/server/api/endpoints/charts/active-users.ts b/src/server/api/endpoints/charts/active-users.ts index 59bb1db109..327dd4de3e 100644 --- a/src/server/api/endpoints/charts/active-users.ts +++ b/src/server/api/endpoints/charts/active-users.ts @@ -25,11 +25,16 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, + + offset: { + validator: $.optional.num, + default: 0, + }, }, res: convertLog(activeUsersChart.schema), }; export default define(meta, async (ps) => { - return await activeUsersChart.getChart(ps.span as any, ps.limit!); + return await activeUsersChart.getChart(ps.span as any, ps.limit!, ps.offset!); }); diff --git a/src/server/api/endpoints/charts/drive.ts b/src/server/api/endpoints/charts/drive.ts index 5c26fe719a..752cb6f037 100644 --- a/src/server/api/endpoints/charts/drive.ts +++ b/src/server/api/endpoints/charts/drive.ts @@ -25,11 +25,16 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, + + offset: { + validator: $.optional.num, + default: 0, + }, }, res: convertLog(driveChart.schema), }; export default define(meta, async (ps) => { - return await driveChart.getChart(ps.span as any, ps.limit!); + return await driveChart.getChart(ps.span as any, ps.limit!, ps.offset!); }); diff --git a/src/server/api/endpoints/charts/federation.ts b/src/server/api/endpoints/charts/federation.ts index ebd60cc24b..1701f9bde4 100644 --- a/src/server/api/endpoints/charts/federation.ts +++ b/src/server/api/endpoints/charts/federation.ts @@ -25,11 +25,16 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, + + offset: { + validator: $.optional.num, + default: 0, + }, }, res: convertLog(federationChart.schema), }; export default define(meta, async (ps) => { - return await federationChart.getChart(ps.span as any, ps.limit!); + return await federationChart.getChart(ps.span as any, ps.limit!, ps.offset!); }); diff --git a/src/server/api/endpoints/charts/hashtag.ts b/src/server/api/endpoints/charts/hashtag.ts index 8d14430137..bb353e7038 100644 --- a/src/server/api/endpoints/charts/hashtag.ts +++ b/src/server/api/endpoints/charts/hashtag.ts @@ -26,6 +26,11 @@ export const meta = { } }, + offset: { + validator: $.optional.num, + default: 0, + }, + tag: { validator: $.str, desc: { @@ -38,5 +43,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.tag); + return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.tag); }); diff --git a/src/server/api/endpoints/charts/instance.ts b/src/server/api/endpoints/charts/instance.ts index 4c26b7614c..3ccb2ba126 100644 --- a/src/server/api/endpoints/charts/instance.ts +++ b/src/server/api/endpoints/charts/instance.ts @@ -26,6 +26,11 @@ export const meta = { } }, + offset: { + validator: $.optional.num, + default: 0, + }, + host: { validator: $.str, desc: { @@ -39,5 +44,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await instanceChart.getChart(ps.span as any, ps.limit!, ps.host); + return await instanceChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.host); }); diff --git a/src/server/api/endpoints/charts/network.ts b/src/server/api/endpoints/charts/network.ts index 162c0c9ecd..20f5977baa 100644 --- a/src/server/api/endpoints/charts/network.ts +++ b/src/server/api/endpoints/charts/network.ts @@ -25,11 +25,16 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, + + offset: { + validator: $.optional.num, + default: 0, + }, }, res: convertLog(networkChart.schema), }; export default define(meta, async (ps) => { - return await networkChart.getChart(ps.span as any, ps.limit!); + return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset!); }); diff --git a/src/server/api/endpoints/charts/notes.ts b/src/server/api/endpoints/charts/notes.ts index c25f46f543..5111e299e2 100644 --- a/src/server/api/endpoints/charts/notes.ts +++ b/src/server/api/endpoints/charts/notes.ts @@ -25,11 +25,16 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, + + offset: { + validator: $.optional.num, + default: 0, + }, }, res: convertLog(notesChart.schema), }; export default define(meta, async (ps) => { - return await notesChart.getChart(ps.span as any, ps.limit!); + return await notesChart.getChart(ps.span as any, ps.limit!, ps.offset!); }); diff --git a/src/server/api/endpoints/charts/user/drive.ts b/src/server/api/endpoints/charts/user/drive.ts index 6bfa427403..576bc7be6a 100644 --- a/src/server/api/endpoints/charts/user/drive.ts +++ b/src/server/api/endpoints/charts/user/drive.ts @@ -27,6 +27,11 @@ export const meta = { } }, + offset: { + validator: $.optional.num, + default: 0, + }, + userId: { validator: $.type(ID), desc: { @@ -40,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.userId); + return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); }); diff --git a/src/server/api/endpoints/charts/user/following.ts b/src/server/api/endpoints/charts/user/following.ts index 0da995e2ec..dcdf15b410 100644 --- a/src/server/api/endpoints/charts/user/following.ts +++ b/src/server/api/endpoints/charts/user/following.ts @@ -27,6 +27,11 @@ export const meta = { } }, + offset: { + validator: $.optional.num, + default: 0, + }, + userId: { validator: $.type(ID), desc: { @@ -40,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.userId); + return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); }); diff --git a/src/server/api/endpoints/charts/user/notes.ts b/src/server/api/endpoints/charts/user/notes.ts index 754ade1228..65c12d6be2 100644 --- a/src/server/api/endpoints/charts/user/notes.ts +++ b/src/server/api/endpoints/charts/user/notes.ts @@ -27,6 +27,11 @@ export const meta = { } }, + offset: { + validator: $.optional.num, + default: 0, + }, + userId: { validator: $.type(ID), desc: { @@ -40,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.userId); + return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); }); diff --git a/src/server/api/endpoints/charts/user/reactions.ts b/src/server/api/endpoints/charts/user/reactions.ts index f3344c6648..c83a203b9c 100644 --- a/src/server/api/endpoints/charts/user/reactions.ts +++ b/src/server/api/endpoints/charts/user/reactions.ts @@ -27,6 +27,11 @@ export const meta = { } }, + offset: { + validator: $.optional.num, + default: 0, + }, + userId: { validator: $.type(ID), desc: { @@ -40,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.userId); + return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); }); diff --git a/src/server/api/endpoints/charts/users.ts b/src/server/api/endpoints/charts/users.ts index 0d7fb7b951..7f52184f16 100644 --- a/src/server/api/endpoints/charts/users.ts +++ b/src/server/api/endpoints/charts/users.ts @@ -25,11 +25,16 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, + + offset: { + validator: $.optional.num, + default: 0, + }, }, res: convertLog(usersChart.schema), }; export default define(meta, async (ps) => { - return await usersChart.getChart(ps.span as any, ps.limit!); + return await usersChart.getChart(ps.span as any, ps.limit!, ps.offset!); }); diff --git a/src/server/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts index 5bc224450b..a6ee240a89 100644 --- a/src/server/api/endpoints/stats.ts +++ b/src/server/api/endpoints/stats.ts @@ -60,9 +60,9 @@ export default define(meta, async () => { Notes.count({ where: { userHost: null }, cache: 3600000 }), Users.count({ cache: 3600000 }), Users.count({ where: { host: null }, cache: 3600000 }), - federationChart.getChart('hour', 1).then(chart => chart.instance.total[0]), - driveChart.getChart('hour', 1).then(chart => chart.local.totalSize[0]), - driveChart.getChart('hour', 1).then(chart => chart.remote.totalSize[0]), + federationChart.getChart('hour', 1, 0).then(chart => chart.instance.total[0]), + driveChart.getChart('hour', 1, 0).then(chart => chart.local.totalSize[0]), + driveChart.getChart('hour', 1, 0).then(chart => chart.remote.totalSize[0]), ]); return { diff --git a/src/services/chart/core.ts b/src/services/chart/core.ts index d62149c9a9..5a2508b556 100644 --- a/src/services/chart/core.ts +++ b/src/services/chart/core.ts @@ -8,7 +8,7 @@ import * as nestedProperty from 'nested-property'; import autobind from 'autobind-decorator'; import Logger from '../logger'; import { Schema } from '../../misc/schema'; -import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual } from 'typeorm'; +import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual, Between } from 'typeorm'; import { DateUTC, isTimeSame, isTimeBefore, subtractTimespan } from '../../prelude/time'; import { getChartInsertLock } from '../../misc/app-lock'; @@ -133,6 +133,21 @@ export default abstract class Chart> { return Math.floor(x.getTime() / 1000); } + @autobind + private static dateToYMDH(date: Date): [number, number, number, number] { + const y = date.getUTCFullYear(); + const m = date.getUTCMonth(); + const d = date.getUTCDate(); + const h = date.getUTCHours(); + + return [y, m, d, h]; + } + + @autobind + private static getCurrentDate(): [number, number, number, number] { + return Chart.dateToYMDH(new Date()); + } + @autobind public static schemaToEntity(name: string, schema: Schema): EntitySchema { return new EntitySchema({ @@ -211,18 +226,6 @@ export default abstract class Chart> { return log as T; } - @autobind - private getCurrentDate(): [number, number, number, number] { - const now = new Date(); - - const y = now.getUTCFullYear(); - const m = now.getUTCMonth(); - const d = now.getUTCDate(); - const h = now.getUTCHours(); - - return [y, m, d, h]; - } - @autobind private getLatestLog(span: Span, group: string | null = null): Promise { return this.repository.findOne({ @@ -237,7 +240,7 @@ export default abstract class Chart> { @autobind private async getCurrentLog(span: Span, group: string | null = null): Promise { - const [y, m, d, h] = this.getCurrentDate(); + const [y, m, d, h] = Chart.getCurrentDate(); const current = span == 'day' ? DateUTC([y, m, d]) : @@ -378,12 +381,23 @@ export default abstract class Chart> { } @autobind - public async getChart(span: Span, range: number, group: string | null = null): Promise> { - const [y, m, d, h] = this.getCurrentDate(); + public async getChart(span: Span, range: number, offset: number, group: string | null = null): Promise> { + let [y, m, d, h] = Chart.getCurrentDate(); + + let lt: Date = null as never; + + if (offset > 0) { + [y, m, d, h] = Chart.dateToYMDH(subtractTimespan(DateUTC([y, m, d, h]), offset, span)); + + lt = + span === 'day' ? DateUTC([y, m, d]) : + span === 'hour' ? DateUTC([y, m, d, h]) : + null as never; + } const gt = - span === 'day' ? subtractTimespan(DateUTC([y, m, d]), range - 1, 'days') : - span === 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), range - 1, 'hours') : + span === 'day' ? subtractTimespan(DateUTC([y, m, d]), range - 1, 'day') : + span === 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), range - 1, 'hour') : null as never; // ログ取得 @@ -391,7 +405,9 @@ export default abstract class Chart> { where: { group: group, span: span, - date: MoreThanOrEqual(Chart.dateToTimestamp(gt)) + date: offset === 0 + ? MoreThanOrEqual(Chart.dateToTimestamp(gt)) + : Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt)) }, order: { date: -1 @@ -439,8 +455,8 @@ export default abstract class Chart> { // 整形 for (let i = (range - 1); i >= 0; i--) { const current = - span == 'day' ? subtractTimespan(DateUTC([y, m, d]), i, 'days') : - span == 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), i, 'hours') : + span == 'day' ? subtractTimespan(DateUTC([y, m, d]), i, 'day') : + span == 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), i, 'hour') : null as never; const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); diff --git a/test/chart.ts b/test/chart.ts index 13f0392632..27cf2833e2 100644 --- a/test/chart.ts +++ b/test/chart.ts @@ -86,8 +86,8 @@ describe('Chart', () => { it('Can updates', async(async () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -109,8 +109,8 @@ describe('Chart', () => { it('Can updates (dec)', async(async () => { await testChart.decrement(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -130,8 +130,8 @@ describe('Chart', () => { })); it('Empty chart', async(async () => { - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -155,8 +155,8 @@ describe('Chart', () => { await testChart.increment(); await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -182,8 +182,8 @@ describe('Chart', () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -209,8 +209,8 @@ describe('Chart', () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -235,8 +235,8 @@ describe('Chart', () => { clock.tick('05:00:00'); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -262,8 +262,8 @@ describe('Chart', () => { clock.tick('05:00:00'); await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -282,14 +282,41 @@ describe('Chart', () => { }); })); + it('Can specify offset', async(async () => { + await testChart.increment(); + + clock.tick('01:00:00'); + + await testChart.increment(); + + const chartHours = await testChart.getChart('hour', 3, 1); + const chartDays = await testChart.getChart('day', 3, 1); + + assert.deepStrictEqual(chartHours, { + foo: { + dec: [0, 0, 0], + inc: [1, 0, 0], + total: [1, 0, 0] + }, + }); + + assert.deepStrictEqual(chartDays, { + foo: { + dec: [0, 0, 0], + inc: [0, 0, 0], + total: [0, 0, 0] + }, + }); + })); + describe('Grouped', () => { it('Can updates', async(async () => { await testGroupedChart.increment('alice'); - const aliceChartHours = await testGroupedChart.getChart('hour', 3, 'alice'); - const aliceChartDays = await testGroupedChart.getChart('day', 3, 'alice'); - const bobChartHours = await testGroupedChart.getChart('hour', 3, 'bob'); - const bobChartDays = await testGroupedChart.getChart('day', 3, 'bob'); + const aliceChartHours = await testGroupedChart.getChart('hour', 3, 0, 'alice'); + const aliceChartDays = await testGroupedChart.getChart('day', 3, 0, 'alice'); + const bobChartHours = await testGroupedChart.getChart('hour', 3, 0, 'bob'); + const bobChartDays = await testGroupedChart.getChart('day', 3, 0, 'bob'); assert.deepStrictEqual(aliceChartHours, { foo: { @@ -331,8 +358,8 @@ describe('Chart', () => { await testUniqueChart.uniqueIncrement('alice'); await testUniqueChart.uniqueIncrement('bob'); - const chartHours = await testUniqueChart.getChart('hour', 3); - const chartDays = await testUniqueChart.getChart('day', 3); + const chartHours = await testUniqueChart.getChart('hour', 3, 0); + const chartDays = await testUniqueChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: [2, 0, 0], @@ -350,8 +377,8 @@ describe('Chart', () => { await testChart.resync(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { @@ -379,8 +406,8 @@ describe('Chart', () => { await testChart.resync(); - const chartHours = await testChart.getChart('hour', 3); - const chartDays = await testChart.getChart('day', 3); + const chartHours = await testChart.getChart('hour', 3, 0); + const chartDays = await testChart.getChart('day', 3, 0); assert.deepStrictEqual(chartHours, { foo: { -- cgit v1.2.3-freya From 917726fecc2206321bd41264a66a9a39a2103d57 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Mar 2020 11:23:31 +0900 Subject: wip #6140 --- src/prelude/time.ts | 12 ++--- src/server/api/endpoints/charts/active-users.ts | 6 +-- src/server/api/endpoints/charts/drive.ts | 6 +-- src/server/api/endpoints/charts/federation.ts | 6 +-- src/server/api/endpoints/charts/hashtag.ts | 6 +-- src/server/api/endpoints/charts/instance.ts | 6 +-- src/server/api/endpoints/charts/network.ts | 6 +-- src/server/api/endpoints/charts/notes.ts | 6 +-- src/server/api/endpoints/charts/user/drive.ts | 6 +-- src/server/api/endpoints/charts/user/following.ts | 6 +-- src/server/api/endpoints/charts/user/notes.ts | 6 +-- src/server/api/endpoints/charts/user/reactions.ts | 6 +-- src/server/api/endpoints/charts/users.ts | 6 +-- src/server/api/endpoints/stats.ts | 6 +-- src/services/chart/core.ts | 47 +++++++---------- test/chart.ts | 64 +++++++++++------------ 16 files changed, 96 insertions(+), 105 deletions(-) (limited to 'src/server') diff --git a/src/prelude/time.ts b/src/prelude/time.ts index 77a5fc1af2..a65366d74a 100644 --- a/src/prelude/time.ts +++ b/src/prelude/time.ts @@ -1,13 +1,11 @@ const dateTimeIntervals = { 'day': 86400000, 'hour': 3600000, + 'ms': 1, }; -export function DateUTC(time: number[]): Date { - const r = new Date(0); - r.setUTCFullYear(time[0], time[1], time[2]); - if (time[3]) r.setUTCHours(time[3], ...time.slice(4)); - return r; +export function dateUTC(time: number[]): Date { + return new Date(Date.UTC(...time)); } export function isTimeSame(a: Date, b: Date): boolean { @@ -22,10 +20,10 @@ export function isTimeAfter(a: Date, b: Date): boolean { return (a.getTime() - b.getTime()) > 0; } -export function addTimespan(x: Date, value: number, span: keyof typeof dateTimeIntervals): Date { +export function addTime(x: Date, value: number, span: keyof typeof dateTimeIntervals = 'ms'): Date { return new Date(x.getTime() + (value * dateTimeIntervals[span])); } -export function subtractTimespan(x: Date, value: number, span: keyof typeof dateTimeIntervals): Date { +export function subtractTime(x: Date, value: number, span: keyof typeof dateTimeIntervals = 'ms'): Date { return new Date(x.getTime() - (value * dateTimeIntervals[span])); } diff --git a/src/server/api/endpoints/charts/active-users.ts b/src/server/api/endpoints/charts/active-users.ts index 327dd4de3e..df427ff4b7 100644 --- a/src/server/api/endpoints/charts/active-users.ts +++ b/src/server/api/endpoints/charts/active-users.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, }, @@ -36,5 +36,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await activeUsersChart.getChart(ps.span as any, ps.limit!, ps.offset!); + return await activeUsersChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); }); diff --git a/src/server/api/endpoints/charts/drive.ts b/src/server/api/endpoints/charts/drive.ts index 752cb6f037..e1f279fa0a 100644 --- a/src/server/api/endpoints/charts/drive.ts +++ b/src/server/api/endpoints/charts/drive.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, }, @@ -36,5 +36,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await driveChart.getChart(ps.span as any, ps.limit!, ps.offset!); + return await driveChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); }); diff --git a/src/server/api/endpoints/charts/federation.ts b/src/server/api/endpoints/charts/federation.ts index 1701f9bde4..581e42f307 100644 --- a/src/server/api/endpoints/charts/federation.ts +++ b/src/server/api/endpoints/charts/federation.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, }, @@ -36,5 +36,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await federationChart.getChart(ps.span as any, ps.limit!, ps.offset!); + return await federationChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); }); diff --git a/src/server/api/endpoints/charts/hashtag.ts b/src/server/api/endpoints/charts/hashtag.ts index bb353e7038..1aa5c86b35 100644 --- a/src/server/api/endpoints/charts/hashtag.ts +++ b/src/server/api/endpoints/charts/hashtag.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, tag: { @@ -43,5 +43,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.tag); + return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.tag); }); diff --git a/src/server/api/endpoints/charts/instance.ts b/src/server/api/endpoints/charts/instance.ts index 3ccb2ba126..f0f85ed71a 100644 --- a/src/server/api/endpoints/charts/instance.ts +++ b/src/server/api/endpoints/charts/instance.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, host: { @@ -44,5 +44,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await instanceChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.host); + return await instanceChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.host); }); diff --git a/src/server/api/endpoints/charts/network.ts b/src/server/api/endpoints/charts/network.ts index 20f5977baa..d1337681a9 100644 --- a/src/server/api/endpoints/charts/network.ts +++ b/src/server/api/endpoints/charts/network.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, }, @@ -36,5 +36,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset!); + return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); }); diff --git a/src/server/api/endpoints/charts/notes.ts b/src/server/api/endpoints/charts/notes.ts index 5111e299e2..74aa48b36e 100644 --- a/src/server/api/endpoints/charts/notes.ts +++ b/src/server/api/endpoints/charts/notes.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, }, @@ -36,5 +36,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await notesChart.getChart(ps.span as any, ps.limit!, ps.offset!); + return await notesChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); }); diff --git a/src/server/api/endpoints/charts/user/drive.ts b/src/server/api/endpoints/charts/user/drive.ts index 576bc7be6a..5aae5bd757 100644 --- a/src/server/api/endpoints/charts/user/drive.ts +++ b/src/server/api/endpoints/charts/user/drive.ts @@ -28,8 +28,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, userId: { @@ -45,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); + return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId); }); diff --git a/src/server/api/endpoints/charts/user/following.ts b/src/server/api/endpoints/charts/user/following.ts index dcdf15b410..9d772c39c9 100644 --- a/src/server/api/endpoints/charts/user/following.ts +++ b/src/server/api/endpoints/charts/user/following.ts @@ -28,8 +28,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, userId: { @@ -45,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); + return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId); }); diff --git a/src/server/api/endpoints/charts/user/notes.ts b/src/server/api/endpoints/charts/user/notes.ts index 65c12d6be2..8de7c0c3e4 100644 --- a/src/server/api/endpoints/charts/user/notes.ts +++ b/src/server/api/endpoints/charts/user/notes.ts @@ -28,8 +28,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, userId: { @@ -45,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); + return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId); }); diff --git a/src/server/api/endpoints/charts/user/reactions.ts b/src/server/api/endpoints/charts/user/reactions.ts index c83a203b9c..4c37305fc3 100644 --- a/src/server/api/endpoints/charts/user/reactions.ts +++ b/src/server/api/endpoints/charts/user/reactions.ts @@ -28,8 +28,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, userId: { @@ -45,5 +45,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId); + return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId); }); diff --git a/src/server/api/endpoints/charts/users.ts b/src/server/api/endpoints/charts/users.ts index 7f52184f16..18eec384a6 100644 --- a/src/server/api/endpoints/charts/users.ts +++ b/src/server/api/endpoints/charts/users.ts @@ -27,8 +27,8 @@ export const meta = { }, offset: { - validator: $.optional.num, - default: 0, + validator: $.optional.nullable.num, + default: null, }, }, @@ -36,5 +36,5 @@ export const meta = { }; export default define(meta, async (ps) => { - return await usersChart.getChart(ps.span as any, ps.limit!, ps.offset!); + return await usersChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); }); diff --git a/src/server/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts index a6ee240a89..dab05c1675 100644 --- a/src/server/api/endpoints/stats.ts +++ b/src/server/api/endpoints/stats.ts @@ -60,9 +60,9 @@ export default define(meta, async () => { Notes.count({ where: { userHost: null }, cache: 3600000 }), Users.count({ cache: 3600000 }), Users.count({ where: { host: null }, cache: 3600000 }), - federationChart.getChart('hour', 1, 0).then(chart => chart.instance.total[0]), - driveChart.getChart('hour', 1, 0).then(chart => chart.local.totalSize[0]), - driveChart.getChart('hour', 1, 0).then(chart => chart.remote.totalSize[0]), + federationChart.getChart('hour', 1, null).then(chart => chart.instance.total[0]), + driveChart.getChart('hour', 1, null).then(chart => chart.local.totalSize[0]), + driveChart.getChart('hour', 1, null).then(chart => chart.remote.totalSize[0]), ]); return { diff --git a/src/services/chart/core.ts b/src/services/chart/core.ts index ca24082e73..dc09923ae4 100644 --- a/src/services/chart/core.ts +++ b/src/services/chart/core.ts @@ -8,8 +8,8 @@ import * as nestedProperty from 'nested-property'; import autobind from 'autobind-decorator'; import Logger from '../logger'; import { Schema } from '../../misc/schema'; -import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual, Between } from 'typeorm'; -import { DateUTC, isTimeSame, isTimeBefore, subtractTimespan } from '../../prelude/time'; +import { EntitySchema, getRepository, Repository, LessThan, Between } from 'typeorm'; +import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '../../prelude/time'; import { getChartInsertLock } from '../../misc/app-lock'; const logger = new Logger('chart', 'white', process.env.NODE_ENV !== 'test'); @@ -134,18 +134,21 @@ export default abstract class Chart> { } @autobind - private static dateToYMDH(date: Date): [number, number, number, number] { + private static parseDate(date: Date): [number, number, number, number, number, number, number] { const y = date.getUTCFullYear(); const m = date.getUTCMonth(); const d = date.getUTCDate(); const h = date.getUTCHours(); + const _m = date.getUTCMinutes(); + const _s = date.getUTCSeconds(); + const _ms = date.getUTCMilliseconds(); - return [y, m, d, h]; + return [y, m, d, h, _m, _s, _ms]; } @autobind - private static getCurrentDate(): [number, number, number, number] { - return Chart.dateToYMDH(new Date()); + private static getCurrentDate() { + return Chart.parseDate(new Date()); } @autobind @@ -243,8 +246,8 @@ export default abstract class Chart> { const [y, m, d, h] = Chart.getCurrentDate(); const current = - span == 'day' ? DateUTC([y, m, d]) : - span == 'hour' ? DateUTC([y, m, d, h]) : + span == 'day' ? dateUTC([y, m, d, 0]) : + span == 'hour' ? dateUTC([y, m, d, h]) : null as never; // 現在(今日または今のHour)のログ @@ -381,23 +384,15 @@ export default abstract class Chart> { } @autobind - public async getChart(span: Span, amount: number, offset: number, group: string | null = null): Promise> { - let [y, m, d, h] = Chart.getCurrentDate(); + public async getChart(span: Span, amount: number, begin: Date | null, group: string | null = null): Promise> { + const [y, m, d, h, _m, _s, _ms] = begin ? Chart.parseDate(subtractTime(addTime(begin, 1, span), 1)) : Chart.getCurrentDate(); + const [y2, m2, d2, h2] = begin ? Chart.parseDate(addTime(begin, 1, span)) : [] as never; - let lt: Date = null as never; - - if (offset > 0) { - [y, m, d, h] = Chart.dateToYMDH(subtractTimespan(DateUTC([y, m, d, h]), offset, span)); - - lt = - span === 'day' ? DateUTC([y, m, d]) : - span === 'hour' ? DateUTC([y, m, d, h]) : - null as never; - } + const lt = dateUTC([y, m, d, h, _m, _s, _ms]); const gt = - span === 'day' ? subtractTimespan(DateUTC([y, m, d]), amount - 1, 'day') : - span === 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), amount - 1, 'hour') : + span === 'day' ? subtractTime(begin ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]), amount - 1, 'day') : + span === 'hour' ? subtractTime(begin ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]), amount - 1, 'hour') : null as never; // ログ取得 @@ -405,9 +400,7 @@ export default abstract class Chart> { where: { group: group, span: span, - date: offset === 0 - ? MoreThanOrEqual(Chart.dateToTimestamp(gt)) - : Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt)) + date: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt)) }, order: { date: -1 @@ -455,8 +448,8 @@ export default abstract class Chart> { // 整形 for (let i = (amount - 1); i >= 0; i--) { const current = - span == 'day' ? subtractTimespan(DateUTC([y, m, d]), i, 'day') : - span == 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), i, 'hour') : + span === 'day' ? subtractTime(dateUTC([y, m, d, 0]), i, 'day') : + span === 'hour' ? subtractTime(dateUTC([y, m, d, h]), i, 'hour') : null as never; const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); diff --git a/test/chart.ts b/test/chart.ts index 6a04569a90..5548d1869f 100644 --- a/test/chart.ts +++ b/test/chart.ts @@ -86,8 +86,8 @@ describe('Chart', () => { it('Can updates', async(async () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -109,8 +109,8 @@ describe('Chart', () => { it('Can updates (dec)', async(async () => { await testChart.decrement(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -130,8 +130,8 @@ describe('Chart', () => { })); it('Empty chart', async(async () => { - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -155,8 +155,8 @@ describe('Chart', () => { await testChart.increment(); await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -182,8 +182,8 @@ describe('Chart', () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -209,8 +209,8 @@ describe('Chart', () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -235,8 +235,8 @@ describe('Chart', () => { clock.tick('05:00:00'); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -262,8 +262,8 @@ describe('Chart', () => { clock.tick('05:00:00'); await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -289,8 +289,8 @@ describe('Chart', () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3, 1); - const chartDays = await testChart.getChart('day', 3, 1); + const chartHours = await testChart.getChart('hour', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0))); + const chartDays = await testChart.getChart('day', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0))); assert.deepStrictEqual(chartHours, { foo: { @@ -303,8 +303,8 @@ describe('Chart', () => { assert.deepStrictEqual(chartDays, { foo: { dec: [0, 0, 0], - inc: [0, 0, 0], - total: [0, 0, 0] + inc: [2, 0, 0], + total: [2, 0, 0] }, }); })); @@ -318,8 +318,8 @@ describe('Chart', () => { await testChart.increment(); - const chartHours = await testChart.getChart('hour', 3, 1); - const chartDays = await testChart.getChart('day', 3, 1); + const chartHours = await testChart.getChart('hour', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0))); + const chartDays = await testChart.getChart('day', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0))); assert.deepStrictEqual(chartHours, { foo: { @@ -342,10 +342,10 @@ describe('Chart', () => { it('Can updates', async(async () => { await testGroupedChart.increment('alice'); - const aliceChartHours = await testGroupedChart.getChart('hour', 3, 0, 'alice'); - const aliceChartDays = await testGroupedChart.getChart('day', 3, 0, 'alice'); - const bobChartHours = await testGroupedChart.getChart('hour', 3, 0, 'bob'); - const bobChartDays = await testGroupedChart.getChart('day', 3, 0, 'bob'); + const aliceChartHours = await testGroupedChart.getChart('hour', 3, null, 'alice'); + const aliceChartDays = await testGroupedChart.getChart('day', 3, null, 'alice'); + const bobChartHours = await testGroupedChart.getChart('hour', 3, null, 'bob'); + const bobChartDays = await testGroupedChart.getChart('day', 3, null, 'bob'); assert.deepStrictEqual(aliceChartHours, { foo: { @@ -387,8 +387,8 @@ describe('Chart', () => { await testUniqueChart.uniqueIncrement('alice'); await testUniqueChart.uniqueIncrement('bob'); - const chartHours = await testUniqueChart.getChart('hour', 3, 0); - const chartDays = await testUniqueChart.getChart('day', 3, 0); + const chartHours = await testUniqueChart.getChart('hour', 3, null); + const chartDays = await testUniqueChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: [2, 0, 0], @@ -406,8 +406,8 @@ describe('Chart', () => { await testChart.resync(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { @@ -435,8 +435,8 @@ describe('Chart', () => { await testChart.resync(); - const chartHours = await testChart.getChart('hour', 3, 0); - const chartDays = await testChart.getChart('day', 3, 0); + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); assert.deepStrictEqual(chartHours, { foo: { -- cgit v1.2.3-freya From 80eedf744944769c8ba9bbdccc2aa7dad06b2151 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Fri, 20 Mar 2020 13:56:22 +0900 Subject: 連携ログインができないのなどを修正 (#6162) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 連携ログインができないのを修正 * Cookie名変更, セッションに * igiはやっぱり非セッションCookieで * 2回目以降Discordログインできなくなるのを修正 --- src/client/mios.ts | 7 ++++++- src/client/pages/my-settings/integration.vue | 7 +++---- src/client/store.ts | 1 + src/server/api/common/signin.ts | 8 ++------ src/server/api/service/discord.ts | 15 ++++++--------- src/server/api/service/github.ts | 14 +++++--------- src/server/api/service/twitter.ts | 14 +++++--------- 7 files changed, 28 insertions(+), 38 deletions(-) (limited to 'src/server') diff --git a/src/client/mios.ts b/src/client/mios.ts index c2ba8ac5cd..aa2b202abd 100644 --- a/src/client/mios.ts +++ b/src/client/mios.ts @@ -123,7 +123,12 @@ export default class MiOS extends EventEmitter { }); } else { // Get token from localStorage - const i = localStorage.getItem('i'); + let i = localStorage.getItem('i'); + + // 連携ログインの場合用にCookieを参照する + if (i == null || i === 'null') { + i = (document.cookie.match(/igi=(\w+)/) || [null, null])[1]; + } fetchme(i, me => { if (me) { diff --git a/src/client/pages/my-settings/integration.vue b/src/client/pages/my-settings/integration.vue index 742d432018..3dd7783f12 100644 --- a/src/client/pages/my-settings/integration.vue +++ b/src/client/pages/my-settings/integration.vue @@ -70,11 +70,10 @@ export default Vue.extend({ }, mounted() { - if (!document.cookie.match(/i=(\w+)/)) { - document.cookie = `i=${this.$store.state.i.token}; path=/;` + - ` domain=${document.location.hostname}; max-age=31536000;` + + document.cookie = `igi=${this.$store.state.i.token}; path=/;` + + ` max-age=31536000;` + (document.location.protocol.startsWith('https') ? ' secure' : ''); - } + this.$watch('integrations', () => { if (this.integrations.twitter) { if (this.twitterForm) this.twitterForm.close(); diff --git a/src/client/store.ts b/src/client/store.ts index 3064cfdec7..8ded1ba00d 100644 --- a/src/client/store.ts +++ b/src/client/store.ts @@ -101,6 +101,7 @@ export default (os: MiOS) => new Vuex.Store({ ctx.commit('settings/init', {}); ctx.commit('deviceUser/init', {}); localStorage.removeItem('i'); + document.cookie = `igi=; path=/`; }, async switchAccount(ctx, i) { diff --git a/src/server/api/common/signin.ts b/src/server/api/common/signin.ts index aa2786f8fc..50f79f1919 100644 --- a/src/server/api/common/signin.ts +++ b/src/server/api/common/signin.ts @@ -9,16 +9,12 @@ import { publishMainStream } from '../../../services/stream'; export default function(ctx: Koa.Context, user: ILocalUser, redirect = false) { if (redirect) { //#region Cookie - const expires = 1000 * 60 * 60 * 24 * 365; // One Year - ctx.cookies.set('i', user.token, { + ctx.cookies.set('igi', user.token, { path: '/', - domain: config.hostname, // SEE: https://github.com/koajs/koa/issues/974 // When using a SSL proxy it should be configured to add the "X-Forwarded-Proto: https" header secure: config.url.startsWith('https'), - httpOnly: false, - expires: new Date(Date.now() + expires), - maxAge: expires + httpOnly: false }); //#endregion diff --git a/src/server/api/service/discord.ts b/src/server/api/service/discord.ts index f9f3026aa8..c2bb02453b 100644 --- a/src/server/api/service/discord.ts +++ b/src/server/api/service/discord.ts @@ -13,7 +13,7 @@ import { ILocalUser } from '../../../models/entities/user'; import { ensure } from '../../../prelude/ensure'; function getUserToken(ctx: Koa.Context) { - return ((ctx.headers['cookie'] || '').match(/i=(\w+)/) || [null, null])[1]; + return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1]; } function compareOrigin(ctx: Koa.Context) { @@ -113,14 +113,10 @@ router.get('/signin/discord', async ctx => { response_type: 'code' }; - const expires = 1000 * 60 * 60; // 1h - ctx.cookies.set('signin_with_discord_session_id', sessid, { + ctx.cookies.set('signin_with_discord_sid', sessid, { path: '/', - domain: config.host, secure: config.url.startsWith('https'), - httpOnly: true, - expires: new Date(Date.now() + expires), - maxAge: expires + httpOnly: true }); redis.set(sessid, JSON.stringify(params)); @@ -135,7 +131,7 @@ router.get('/dc/cb', async ctx => { const oauth2 = await getOAuth2(); if (!userToken) { - const sessid = ctx.cookies.get('signin_with_discord_session_id'); + const sessid = ctx.cookies.get('signin_with_discord_sid'); if (!sessid) { ctx.throw(400, 'invalid session'); @@ -199,7 +195,7 @@ router.get('/dc/cb', async ctx => { } const profile = await UserProfiles.createQueryBuilder() - .where('"integrations"->"discord"->"id" = :id', { id: id }) + .where(`"integrations"->'discord'->>'id' = :id`, { id: id }) .andWhere('"userHost" IS NULL') .getOne(); @@ -212,6 +208,7 @@ router.get('/dc/cb', async ctx => { integrations: { ...profile.integrations, discord: { + id: id, accessToken: accessToken, refreshToken: refreshToken, expiresDate: expiresDate, diff --git a/src/server/api/service/github.ts b/src/server/api/service/github.ts index ec9cce7ad8..e36c43ee38 100644 --- a/src/server/api/service/github.ts +++ b/src/server/api/service/github.ts @@ -13,7 +13,7 @@ import { ILocalUser } from '../../../models/entities/user'; import { ensure } from '../../../prelude/ensure'; function getUserToken(ctx: Koa.Context) { - return ((ctx.headers['cookie'] || '').match(/i=(\w+)/) || [null, null])[1]; + return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1]; } function compareOrigin(ctx: Koa.Context) { @@ -111,14 +111,10 @@ router.get('/signin/github', async ctx => { state: uuid() }; - const expires = 1000 * 60 * 60; // 1h - ctx.cookies.set('signin_with_github_session_id', sessid, { + ctx.cookies.set('signin_with_github_sid', sessid, { path: '/', - domain: config.host, secure: config.url.startsWith('https'), - httpOnly: true, - expires: new Date(Date.now() + expires), - maxAge: expires + httpOnly: true }); redis.set(sessid, JSON.stringify(params)); @@ -133,7 +129,7 @@ router.get('/gh/cb', async ctx => { const oauth2 = await getOath2(); if (!userToken) { - const sessid = ctx.cookies.get('signin_with_github_session_id'); + const sessid = ctx.cookies.get('signin_with_github_sid'); if (!sessid) { ctx.throw(400, 'invalid session'); @@ -192,7 +188,7 @@ router.get('/gh/cb', async ctx => { } const link = await UserProfiles.createQueryBuilder() - .where('"integrations"->"github"->"id" = :id', { id: id }) + .where(`"integrations"->'github'->>'id' = :id`, { id: id }) .andWhere('"userHost" IS NULL') .getOne(); diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts index 881915b58f..000eb57c1b 100644 --- a/src/server/api/service/twitter.ts +++ b/src/server/api/service/twitter.ts @@ -12,7 +12,7 @@ import { ILocalUser } from '../../../models/entities/user'; import { ensure } from '../../../prelude/ensure'; function getUserToken(ctx: Koa.Context) { - return ((ctx.headers['cookie'] || '').match(/i=(\w+)/) || [null, null])[1]; + return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1]; } function compareOrigin(ctx: Koa.Context) { @@ -102,14 +102,10 @@ router.get('/signin/twitter', async ctx => { redis.set(sessid, JSON.stringify(twCtx)); - const expires = 1000 * 60 * 60; // 1h - ctx.cookies.set('signin_with_twitter_session_id', sessid, { + ctx.cookies.set('signin_with_twitter_sid', sessid, { path: '/', - domain: config.host, secure: config.url.startsWith('https'), - httpOnly: true, - expires: new Date(Date.now() + expires), - maxAge: expires + httpOnly: true }); ctx.redirect(twCtx.url); @@ -121,7 +117,7 @@ router.get('/tw/cb', async ctx => { const twAuth = await getTwAuth(); if (userToken == null) { - const sessid = ctx.cookies.get('signin_with_twitter_session_id'); + const sessid = ctx.cookies.get('signin_with_twitter_sid'); if (sessid == null) { ctx.throw(400, 'invalid session'); @@ -139,7 +135,7 @@ router.get('/tw/cb', async ctx => { const result = await twAuth!.done(JSON.parse(twCtx), ctx.query.oauth_verifier); const link = await UserProfiles.createQueryBuilder() - .where('"integrations"->"twitter"->"userId" = :id', { id: result.userId }) + .where(`"integrations"->'twitter'->>'userId' = :id`, { id: result.userId }) .andWhere('"userHost" IS NULL') .getOne(); -- cgit v1.2.3-freya From 1471e523079294d41821d5f5fb30c25269390d20 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 21 Mar 2020 12:48:25 +0900 Subject: Resolve #6110 --- src/server/api/endpoints/users/search-by-username-and-host.ts | 7 +++++-- src/server/api/endpoints/users/search.ts | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/api/endpoints/users/search-by-username-and-host.ts b/src/server/api/endpoints/users/search-by-username-and-host.ts index 81ff19ff6f..bc68f44094 100644 --- a/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -1,7 +1,6 @@ import $ from 'cafy'; import define from '../../define'; import { Users } from '../../../../models'; -import { User } from '../../../../models/entities/user'; export const meta = { desc: { @@ -73,14 +72,17 @@ export default define(meta, async (ps, me) => { q.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' }) } + q.orderBy('user.updatedAt', 'DESC'); + const users = await q.take(ps.limit!).skip(ps.offset).getMany(); return await Users.packMany(users, me, { detail: ps.detail }); - } else { + } else if (ps.username) { let users = await Users.createQueryBuilder('user') .where('user.host IS NULL') .andWhere('user.isSuspended = FALSE') .andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' }) + .orderBy('user.updatedAt', 'DESC') .take(ps.limit!) .skip(ps.offset) .getMany(); @@ -90,6 +92,7 @@ export default define(meta, async (ps, me) => { .where('user.host IS NOT NULL') .andWhere('user.isSuspended = FALSE') .andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' }) + .orderBy('user.updatedAt', 'DESC') .take(ps.limit! - users.length) .getMany(); diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts index dbeb6eb6af..c01f355d8c 100644 --- a/src/server/api/endpoints/users/search.ts +++ b/src/server/api/endpoints/users/search.ts @@ -74,6 +74,7 @@ export default define(meta, async (ps, me) => { .where('user.host IS NULL') .andWhere('user.isSuspended = FALSE') .andWhere('user.usernameLower like :username', { username: ps.query.replace('@', '').toLowerCase() + '%' }) + .orderBy('user.updatedAt', 'DESC') .take(ps.limit!) .skip(ps.offset) .getMany(); @@ -83,6 +84,7 @@ export default define(meta, async (ps, me) => { .where('user.host IS NOT NULL') .andWhere('user.isSuspended = FALSE') .andWhere('user.usernameLower like :username', { username: ps.query.replace('@', '').toLowerCase() + '%' }) + .orderBy('user.updatedAt', 'DESC') .take(ps.limit! - users.length) .getMany(); -- cgit v1.2.3-freya