1
0
mirror of https://github.com/hotomoe/hotomoe synced 2024-11-28 23:08:17 +09:00
* wip

* wip

* wip

* wip

* wip

* Update define.ts

* Update update.ts

* Update user.ts

* wip

* wip

* Update request.ts

* URL

* wip

* wip

* wip

* wip

* Update invite.ts

* Update create.ts
This commit is contained in:
syuilo 2021-03-24 11:05:37 +09:00 committed by GitHub
parent 62cc14c93b
commit ce340aba7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 252 additions and 201 deletions

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import config from '@/config'; import config from '@/config';
import { toASCII } from 'punycode'; import { toASCII } from 'punycode';

View File

@ -1,6 +1,7 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as stream from 'stream'; import * as stream from 'stream';
import * as util from 'util'; import * as util from 'util';
import { URL } from 'url';
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import { getAgentByUrl } from './fetch'; import { getAgentByUrl } from './fetch';
import { AbortController } from 'abort-controller'; import { AbortController } from 'abort-controller';

View File

@ -9,7 +9,7 @@ export type PackedApp = SchemaType<typeof packedAppSchema>;
export class AppRepository extends Repository<App> { export class AppRepository extends Repository<App> {
public async pack( public async pack(
src: App['id'] | App, src: App['id'] | App,
me?: any, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean, detail?: boolean,
includeSecret?: boolean, includeSecret?: boolean,

View File

@ -2,12 +2,13 @@ import { EntityRepository, Repository } from 'typeorm';
import { Apps } from '..'; import { Apps } from '..';
import { AuthSession } from '../entities/auth-session'; import { AuthSession } from '../entities/auth-session';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { User } from '../entities/user';
@EntityRepository(AuthSession) @EntityRepository(AuthSession)
export class AuthSessionRepository extends Repository<AuthSession> { export class AuthSessionRepository extends Repository<AuthSession> {
public async pack( public async pack(
src: AuthSession['id'] | AuthSession, src: AuthSession['id'] | AuthSession,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const session = typeof src === 'object' ? src : await this.findOneOrFail(src); const session = typeof src === 'object' ? src : await this.findOneOrFail(src);

View File

@ -3,6 +3,7 @@ import { Users } from '..';
import { Blocking } from '../entities/blocking'; import { Blocking } from '../entities/blocking';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
export type PackedBlocking = SchemaType<typeof packedBlockingSchema>; export type PackedBlocking = SchemaType<typeof packedBlockingSchema>;
@ -10,7 +11,7 @@ export type PackedBlocking = SchemaType<typeof packedBlockingSchema>;
export class BlockingRepository extends Repository<Blocking> { export class BlockingRepository extends Repository<Blocking> {
public async pack( public async pack(
src: Blocking['id'] | Blocking, src: Blocking['id'] | Blocking,
me?: any me?: { id: User['id'] } | null | undefined
): Promise<PackedBlocking> { ): Promise<PackedBlocking> {
const blocking = typeof src === 'object' ? src : await this.findOneOrFail(src); const blocking = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -26,7 +27,7 @@ export class BlockingRepository extends Repository<Blocking> {
public packMany( public packMany(
blockings: any[], blockings: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(blockings.map(x => this.pack(x, me))); return Promise.all(blockings.map(x => this.pack(x, me)));
} }

View File

@ -10,19 +10,19 @@ export type PackedChannel = SchemaType<typeof packedChannelSchema>;
export class ChannelRepository extends Repository<Channel> { export class ChannelRepository extends Repository<Channel> {
public async pack( public async pack(
src: Channel['id'] | Channel, src: Channel['id'] | Channel,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
): Promise<PackedChannel> { ): Promise<PackedChannel> {
const channel = typeof src === 'object' ? src : await this.findOneOrFail(src); const channel = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const banner = channel.bannerId ? await DriveFiles.findOne(channel.bannerId) : null; const banner = channel.bannerId ? await DriveFiles.findOne(channel.bannerId) : null;
const hasUnreadNote = me ? (await NoteUnreads.findOne({ noteChannelId: channel.id, userId: meId })) != null : undefined; const hasUnreadNote = meId ? (await NoteUnreads.findOne({ noteChannelId: channel.id, userId: meId })) != null : undefined;
const following = await ChannelFollowings.findOne({ const following = meId ? await ChannelFollowings.findOne({
followerId: meId, followerId: meId,
followeeId: channel.id, followeeId: channel.id,
}); }) : null;
return { return {
id: channel.id, id: channel.id,

View File

@ -53,7 +53,7 @@ export class DriveFileRepository extends Repository<DriveFile> {
return thumbnail ? (file.thumbnailUrl || (isImage ? (file.webpublicUrl || file.url) : null)) : (file.webpublicUrl || file.url); return thumbnail ? (file.thumbnailUrl || (isImage ? (file.webpublicUrl || file.url) : null)) : (file.webpublicUrl || file.url);
} }
public async calcDriveUsageOf(user: User['id'] | User): Promise<number> { public async calcDriveUsageOf(user: User['id'] | { id: User['id'] }): Promise<number> {
const id = typeof user === 'object' ? user.id : user; const id = typeof user === 'object' ? user.id : user;
const { sum } = await this const { sum } = await this

View File

@ -1,12 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { FollowRequest } from '../entities/follow-request'; import { FollowRequest } from '../entities/follow-request';
import { Users } from '..'; import { Users } from '..';
import { User } from '../entities/user';
@EntityRepository(FollowRequest) @EntityRepository(FollowRequest)
export class FollowRequestRepository extends Repository<FollowRequest> { export class FollowRequestRepository extends Repository<FollowRequest> {
public async pack( public async pack(
src: FollowRequest['id'] | FollowRequest, src: FollowRequest['id'] | FollowRequest,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const request = typeof src === 'object' ? src : await this.findOneOrFail(src); const request = typeof src === 'object' ? src : await this.findOneOrFail(src);

View File

@ -3,6 +3,7 @@ import { Users } from '..';
import { Following } from '../entities/following'; import { Following } from '../entities/following';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
type LocalFollowerFollowing = Following & { type LocalFollowerFollowing = Following & {
followerHost: null; followerHost: null;
@ -50,7 +51,7 @@ export class FollowingRepository extends Repository<Following> {
public async pack( public async pack(
src: Following['id'] | Following, src: Following['id'] | Following,
me?: any, me?: { id: User['id'] } | null | undefined,
opts?: { opts?: {
populateFollowee?: boolean; populateFollowee?: boolean;
populateFollower?: boolean; populateFollower?: boolean;
@ -76,7 +77,7 @@ export class FollowingRepository extends Repository<Following> {
public packMany( public packMany(
followings: any[], followings: any[],
me?: any, me?: { id: User['id'] } | null | undefined,
opts?: { opts?: {
populateFollowee?: boolean; populateFollowee?: boolean;
populateFollower?: boolean; populateFollower?: boolean;

View File

@ -1,3 +1,4 @@
import { User } from '@/models/entities/user';
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Users } from '../../..'; import { Users } from '../../..';
import { ReversiGame } from '../../../entities/games/reversi/game'; import { ReversiGame } from '../../../entities/games/reversi/game';
@ -6,7 +7,7 @@ import { ReversiGame } from '../../../entities/games/reversi/game';
export class ReversiGameRepository extends Repository<ReversiGame> { export class ReversiGameRepository extends Repository<ReversiGame> {
public async pack( public async pack(
src: ReversiGame['id'] | ReversiGame, src: ReversiGame['id'] | ReversiGame,
me?: any, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean detail?: boolean
} }
@ -16,7 +17,6 @@ export class ReversiGameRepository extends Repository<ReversiGame> {
}, options); }, options);
const game = typeof src === 'object' ? src : await this.findOneOrFail(src); const game = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? typeof me === 'string' ? me : me.id : null;
return { return {
id: game.id, id: game.id,
@ -30,10 +30,10 @@ export class ReversiGameRepository extends Repository<ReversiGame> {
user2Accepted: game.user2Accepted, user2Accepted: game.user2Accepted,
user1Id: game.user1Id, user1Id: game.user1Id,
user2Id: game.user2Id, user2Id: game.user2Id,
user1: await Users.pack(game.user1Id, meId), user1: await Users.pack(game.user1Id, me),
user2: await Users.pack(game.user2Id, meId), user2: await Users.pack(game.user2Id, me),
winnerId: game.winnerId, winnerId: game.winnerId,
winner: game.winnerId ? await Users.pack(game.winnerId, meId) : null, winner: game.winnerId ? await Users.pack(game.winnerId, me) : null,
surrendered: game.surrendered, surrendered: game.surrendered,
black: game.black, black: game.black,
bw: game.bw, bw: game.bw,

View File

@ -2,12 +2,13 @@ import { EntityRepository, Repository } from 'typeorm';
import { ReversiMatching } from '../../../entities/games/reversi/matching'; import { ReversiMatching } from '../../../entities/games/reversi/matching';
import { Users } from '../../..'; import { Users } from '../../..';
import { awaitAll } from '../../../../prelude/await-all'; import { awaitAll } from '../../../../prelude/await-all';
import { User } from '@/models/entities/user';
@EntityRepository(ReversiMatching) @EntityRepository(ReversiMatching)
export class ReversiMatchingRepository extends Repository<ReversiMatching> { export class ReversiMatchingRepository extends Repository<ReversiMatching> {
public async pack( public async pack(
src: ReversiMatching['id'] | ReversiMatching, src: ReversiMatching['id'] | ReversiMatching,
me: any me: { id: User['id'] }
) { ) {
const matching = typeof src === 'object' ? src : await this.findOneOrFail(src); const matching = typeof src === 'object' ? src : await this.findOneOrFail(src);

View File

@ -2,6 +2,7 @@ import { EntityRepository, Repository } from 'typeorm';
import { MessagingMessage } from '../entities/messaging-message'; import { MessagingMessage } from '../entities/messaging-message';
import { Users, DriveFiles, UserGroups } from '..'; import { Users, DriveFiles, UserGroups } from '..';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSchema>; export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSchema>;
@ -13,7 +14,7 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
public async pack( public async pack(
src: MessagingMessage['id'] | MessagingMessage, src: MessagingMessage['id'] | MessagingMessage,
me?: any, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
populateRecipient?: boolean, populateRecipient?: boolean,
populateGroup?: boolean, populateGroup?: boolean,

View File

@ -3,6 +3,7 @@ import { Users } from '..';
import { Muting } from '../entities/muting'; import { Muting } from '../entities/muting';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
export type PackedMuting = SchemaType<typeof packedMutingSchema>; export type PackedMuting = SchemaType<typeof packedMutingSchema>;
@ -10,7 +11,7 @@ export type PackedMuting = SchemaType<typeof packedMutingSchema>;
export class MutingRepository extends Repository<Muting> { export class MutingRepository extends Repository<Muting> {
public async pack( public async pack(
src: Muting['id'] | Muting, src: Muting['id'] | Muting,
me?: any me?: { id: User['id'] } | null | undefined
): Promise<PackedMuting> { ): Promise<PackedMuting> {
const muting = typeof src === 'object' ? src : await this.findOneOrFail(src); const muting = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -26,7 +27,7 @@ export class MutingRepository extends Repository<Muting> {
public packMany( public packMany(
mutings: any[], mutings: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(mutings.map(x => this.pack(x, me))); return Promise.all(mutings.map(x => this.pack(x, me)));
} }

View File

@ -1,12 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { NoteFavorite } from '../entities/note-favorite'; import { NoteFavorite } from '../entities/note-favorite';
import { Notes } from '..'; import { Notes } from '..';
import { User } from '../entities/user';
@EntityRepository(NoteFavorite) @EntityRepository(NoteFavorite)
export class NoteFavoriteRepository extends Repository<NoteFavorite> { export class NoteFavoriteRepository extends Repository<NoteFavorite> {
public async pack( public async pack(
src: NoteFavorite['id'] | NoteFavorite, src: NoteFavorite['id'] | NoteFavorite,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const favorite = typeof src === 'object' ? src : await this.findOneOrFail(src); const favorite = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -20,7 +21,7 @@ export class NoteFavoriteRepository extends Repository<NoteFavorite> {
public packMany( public packMany(
favorites: any[], favorites: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(favorites.map(x => this.pack(x, me))); return Promise.all(favorites.map(x => this.pack(x, me)));
} }

View File

@ -3,6 +3,7 @@ import { NoteReaction } from '../entities/note-reaction';
import { Users } from '..'; import { Users } from '..';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { convertLegacyReaction } from '@/misc/reaction-lib'; import { convertLegacyReaction } from '@/misc/reaction-lib';
import { User } from '../entities/user';
export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>; export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>;
@ -10,7 +11,7 @@ export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>;
export class NoteReactionRepository extends Repository<NoteReaction> { export class NoteReactionRepository extends Repository<NoteReaction> {
public async pack( public async pack(
src: NoteReaction['id'] | NoteReaction, src: NoteReaction['id'] | NoteReaction,
me?: any me?: { id: User['id'] } | null | undefined
): Promise<PackedNoteReaction> { ): Promise<PackedNoteReaction> {
const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src); const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src);

View File

@ -79,7 +79,7 @@ export class NoteRepository extends Repository<Note> {
public async pack( public async pack(
src: Note['id'] | Note, src: Note['id'] | Note,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean; detail?: boolean;
skipHide?: boolean; skipHide?: boolean;
@ -93,7 +93,7 @@ export class NoteRepository extends Repository<Note> {
skipHide: false skipHide: false
}, options); }, options);
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const note = typeof src === 'object' ? src : await this.findOneOrFail(src); const note = typeof src === 'object' ? src : await this.findOneOrFail(src);
const host = note.userHost; const host = note.userHost;
@ -174,7 +174,7 @@ export class NoteRepository extends Repository<Note> {
id: note.id, id: note.id,
createdAt: note.createdAt.toISOString(), createdAt: note.createdAt.toISOString(),
userId: note.userId, userId: note.userId,
user: Users.pack(note.user || note.userId, meId, { user: Users.pack(note.user || note.userId, me, {
detail: false, detail: false,
}), }),
text: text, text: text,
@ -204,12 +204,12 @@ export class NoteRepository extends Repository<Note> {
_prId_: (note as any)._prId_ || undefined, _prId_: (note as any)._prId_ || undefined,
...(opts.detail ? { ...(opts.detail ? {
reply: note.replyId ? this.pack(note.reply || note.replyId, meId, { reply: note.replyId ? this.pack(note.reply || note.replyId, me, {
detail: false, detail: false,
_hint_: options?._hint_ _hint_: options?._hint_
}) : undefined, }) : undefined,
renote: note.renoteId ? this.pack(note.renote || note.renoteId, meId, { renote: note.renoteId ? this.pack(note.renote || note.renoteId, me, {
detail: true, detail: true,
_hint_: options?._hint_ _hint_: options?._hint_
}) : undefined, }) : undefined,
@ -236,7 +236,7 @@ export class NoteRepository extends Repository<Note> {
public async packMany( public async packMany(
notes: Note[], notes: Note[],
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean; detail?: boolean;
skipHide?: boolean; skipHide?: boolean;
@ -244,7 +244,7 @@ export class NoteRepository extends Repository<Note> {
) { ) {
if (notes.length === 0) return []; if (notes.length === 0) return [];
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const myReactionsMap = new Map<Note['id'], NoteReaction | null>(); const myReactionsMap = new Map<Note['id'], NoteReaction | null>();
if (meId) { if (meId) {
const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!);

View File

@ -31,38 +31,38 @@ export class NotificationRepository extends Repository<Notification> {
userId: notification.notifierId, userId: notification.notifierId,
user: notification.notifierId ? Users.pack(notification.notifier || notification.notifierId) : null, user: notification.notifierId ? Users.pack(notification.notifier || notification.notifierId) : null,
...(notification.type === 'mention' ? { ...(notification.type === 'mention' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'reply' ? { ...(notification.type === 'reply' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'renote' ? { ...(notification.type === 'renote' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'quote' ? { ...(notification.type === 'quote' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'reaction' ? { ...(notification.type === 'reaction' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
reaction: notification.reaction reaction: notification.reaction
} : {}), } : {}),
...(notification.type === 'pollVote' ? { ...(notification.type === 'pollVote' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),

View File

@ -1,12 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { PageLike } from '../entities/page-like'; import { PageLike } from '../entities/page-like';
import { Pages } from '..'; import { Pages } from '..';
import { User } from '../entities/user';
@EntityRepository(PageLike) @EntityRepository(PageLike)
export class PageLikeRepository extends Repository<PageLike> { export class PageLikeRepository extends Repository<PageLike> {
public async pack( public async pack(
src: PageLike['id'] | PageLike, src: PageLike['id'] | PageLike,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const like = typeof src === 'object' ? src : await this.findOneOrFail(src); const like = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -18,7 +19,7 @@ export class PageLikeRepository extends Repository<PageLike> {
public packMany( public packMany(
likes: any[], likes: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(likes.map(x => this.pack(x, me))); return Promise.all(likes.map(x => this.pack(x, me)));
} }

View File

@ -12,9 +12,9 @@ export type PackedPage = SchemaType<typeof packedPageSchema>;
export class PageRepository extends Repository<Page> { export class PageRepository extends Repository<Page> {
public async pack( public async pack(
src: Page['id'] | Page, src: Page['id'] | Page,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
): Promise<PackedPage> { ): Promise<PackedPage> {
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const page = typeof src === 'object' ? src : await this.findOneOrFail(src); const page = typeof src === 'object' ? src : await this.findOneOrFail(src);
const attachedFiles: Promise<DriveFile | undefined>[] = []; const attachedFiles: Promise<DriveFile | undefined>[] = [];
@ -84,7 +84,7 @@ export class PageRepository extends Repository<Page> {
public packMany( public packMany(
pages: Page[], pages: Page[],
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
) { ) {
return Promise.all(pages.map(x => this.pack(x, me))); return Promise.all(pages.map(x => this.pack(x, me)));
} }

View File

@ -147,7 +147,7 @@ export class UserRepository extends Repository<User> {
public async pack( public async pack(
src: User['id'] | User, src: User['id'] | User,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean, detail?: boolean,
includeSecrets?: boolean, includeSecrets?: boolean,
@ -159,7 +159,7 @@ export class UserRepository extends Repository<User> {
}, options); }, options);
const user = typeof src === 'object' ? src : await this.findOneOrFail(src); const user = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null; const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null;
const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin') const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin')
@ -213,11 +213,11 @@ export class UserRepository extends Repository<User> {
followingCount: user.followingCount, followingCount: user.followingCount,
notesCount: user.notesCount, notesCount: user.notesCount,
pinnedNoteIds: pins.map(pin => pin.noteId), pinnedNoteIds: pins.map(pin => pin.noteId),
pinnedNotes: Notes.packMany(pins.map(pin => pin.note!), meId, { pinnedNotes: Notes.packMany(pins.map(pin => pin.note!), me, {
detail: true detail: true
}), }),
pinnedPageId: profile!.pinnedPageId, pinnedPageId: profile!.pinnedPageId,
pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, meId) : null, pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null,
twoFactorEnabled: profile!.twoFactorEnabled, twoFactorEnabled: profile!.twoFactorEnabled,
usePasswordLessLogin: profile!.usePasswordLessLogin, usePasswordLessLogin: profile!.usePasswordLessLogin,
securityKeys: profile!.twoFactorEnabled securityKeys: profile!.twoFactorEnabled
@ -286,7 +286,7 @@ export class UserRepository extends Repository<User> {
public packMany( public packMany(
users: (User['id'] | User)[], users: (User['id'] | User)[],
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean, detail?: boolean,
includeSecrets?: boolean, includeSecrets?: boolean,
@ -295,11 +295,15 @@ export class UserRepository extends Repository<User> {
return Promise.all(users.map(u => this.pack(u, me, options))); return Promise.all(users.map(u => this.pack(u, me, options)));
} }
public isLocalUser(user: User): user is ILocalUser { public isLocalUser(user: User): user is ILocalUser;
public isLocalUser<T extends { host: User['host'] }>(user: T): user is T & { host: null; };
public isLocalUser(user: User | { host: User['host'] }): boolean {
return user.host == null; return user.host == null;
} }
public isRemoteUser(user: User): user is IRemoteUser { public isRemoteUser(user: User): user is IRemoteUser;
public isRemoteUser<T extends { host: User['host'] }>(user: T): user is T & { host: string; };
public isRemoteUser(user: User | { host: User['host'] }): boolean {
return !this.isLocalUser(user); return !this.isLocalUser(user);
} }

View File

@ -1,7 +1,7 @@
import * as httpSignature from 'http-signature'; import * as httpSignature from 'http-signature';
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../models/entities/user'; import { User } from '../models/entities/user';
import { program } from '../argv'; import { program } from '../argv';
import processDeliver from './processors/deliver'; import processDeliver from './processors/deliver';
@ -65,7 +65,7 @@ objectStorageQueue
.on('error', (job: any, err: Error) => objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) })) .on('error', (job: any, err: Error) => objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) }))
.on('stalled', (job) => objectStorageLogger.warn(`stalled id=${job.id}`)); .on('stalled', (job) => objectStorageLogger.warn(`stalled id=${job.id}`));
export function deliver(user: ILocalUser, content: any, to: any) { export function deliver(user: { id: User['id']; host: null; }, content: any, to: any) {
if (content == null) return null; if (content == null) return null;
const data = { const data = {
@ -102,7 +102,7 @@ export function inbox(activity: any, signature: httpSignature.IParsedSignature)
}); });
} }
export function createDeleteDriveFilesJob(user: ILocalUser) { export function createDeleteDriveFilesJob(user: { id: User['id'] }) {
return dbQueue.add('deleteDriveFiles', { return dbQueue.add('deleteDriveFiles', {
user: user user: user
}, { }, {
@ -111,7 +111,7 @@ export function createDeleteDriveFilesJob(user: ILocalUser) {
}); });
} }
export function createExportNotesJob(user: ILocalUser) { export function createExportNotesJob(user: { id: User['id'] }) {
return dbQueue.add('exportNotes', { return dbQueue.add('exportNotes', {
user: user user: user
}, { }, {
@ -120,7 +120,7 @@ export function createExportNotesJob(user: ILocalUser) {
}); });
} }
export function createExportFollowingJob(user: ILocalUser) { export function createExportFollowingJob(user: { id: User['id'] }) {
return dbQueue.add('exportFollowing', { return dbQueue.add('exportFollowing', {
user: user user: user
}, { }, {
@ -129,7 +129,7 @@ export function createExportFollowingJob(user: ILocalUser) {
}); });
} }
export function createExportMuteJob(user: ILocalUser) { export function createExportMuteJob(user: { id: User['id'] }) {
return dbQueue.add('exportMute', { return dbQueue.add('exportMute', {
user: user user: user
}, { }, {
@ -138,7 +138,7 @@ export function createExportMuteJob(user: ILocalUser) {
}); });
} }
export function createExportBlockingJob(user: ILocalUser) { export function createExportBlockingJob(user: { id: User['id'] }) {
return dbQueue.add('exportBlocking', { return dbQueue.add('exportBlocking', {
user: user user: user
}, { }, {
@ -147,7 +147,7 @@ export function createExportBlockingJob(user: ILocalUser) {
}); });
} }
export function createExportUserListsJob(user: ILocalUser) { export function createExportUserListsJob(user: { id: User['id'] }) {
return dbQueue.add('exportUserLists', { return dbQueue.add('exportUserLists', {
user: user user: user
}, { }, {
@ -156,7 +156,7 @@ export function createExportUserListsJob(user: ILocalUser) {
}); });
} }
export function createImportFollowingJob(user: ILocalUser, fileId: DriveFile['id']) { export function createImportFollowingJob(user: { id: User['id'] }, fileId: DriveFile['id']) {
return dbQueue.add('importFollowing', { return dbQueue.add('importFollowing', {
user: user, user: user,
fileId: fileId fileId: fileId
@ -166,7 +166,7 @@ export function createImportFollowingJob(user: ILocalUser, fileId: DriveFile['id
}); });
} }
export function createImportUserListsJob(user: ILocalUser, fileId: DriveFile['id']) { export function createImportUserListsJob(user: { id: User['id'] }, fileId: DriveFile['id']) {
return dbQueue.add('importUserLists', { return dbQueue.add('importUserLists', {
user: user, user: user,
fileId: fileId fileId: fileId

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import * as Bull from 'bull'; import * as Bull from 'bull';
import request from '../../remote/activitypub/request'; import request from '../../remote/activitypub/request';
import { registerOrFetchInstanceDoc } from '../../services/register-or-fetch-instance-doc'; import { registerOrFetchInstanceDoc } from '../../services/register-or-fetch-instance-doc';

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import * as Bull from 'bull'; import * as Bull from 'bull';
import * as httpSignature from 'http-signature'; import * as httpSignature from 'http-signature';
import perform from '../../remote/activitypub/perform'; import perform from '../../remote/activitypub/perform';

View File

@ -1,5 +1,5 @@
import { Users, Followings } from '../../models'; import { Users, Followings } from '../../models';
import { ILocalUser, IRemoteUser } from '../../models/entities/user'; import { ILocalUser, IRemoteUser, User } from '../../models/entities/user';
import { deliver } from '../../queue'; import { deliver } from '../../queue';
//#region types //#region types
@ -24,7 +24,7 @@ const isDirect = (recipe: any): recipe is IDirectRecipe =>
//#endregion //#endregion
export default class DeliverManager { export default class DeliverManager {
private actor: ILocalUser; private actor: { id: User['id']; host: null; };
private activity: any; private activity: any;
private recipes: IRecipe[] = []; private recipes: IRecipe[] = [];
@ -33,7 +33,7 @@ export default class DeliverManager {
* @param actor Actor * @param actor Actor
* @param activity Activity to deliver * @param activity Activity to deliver
*/ */
constructor(actor: ILocalUser, activity: any) { constructor(actor: { id: User['id']; host: null; }, activity: any) {
this.actor = actor; this.actor = actor;
this.activity = activity; this.activity = activity;
} }

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import * as promiseLimit from 'promise-limit'; import * as promiseLimit from 'promise-limit';
import config from '@/config'; import config from '@/config';

View File

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '../../../models/entities/user';
export default (object: any, user: ILocalUser) => ({ export default (object: any, user: { id: User['id']; host: null }) => ({
type: 'Delete', type: 'Delete',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object object

View File

@ -2,7 +2,7 @@ import config from '@/config';
import { User } from '../../../models/entities/user'; import { User } from '../../../models/entities/user';
import { Users } from '../../../models'; import { Users } from '../../../models';
export default (follower: User, followee: User, requestId?: string) => { export default (follower: { id: User['id']; host: User['host']; uri: User['host'] }, followee: { id: User['id']; host: User['host']; uri: User['host'] }, requestId?: string) => {
const follow = { const follow = {
type: 'Follow', type: 'Follow',
actor: Users.isLocalUser(follower) ? `${config.url}/users/${follower.id}` : follower.uri, actor: Users.isLocalUser(follower) ? `${config.url}/users/${follower.id}` : follower.uri,

View File

@ -2,8 +2,8 @@ import config from '@/config';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { IActivity } from '../type'; import { IActivity } from '../type';
import { LdSignature } from '../misc/ld-signature'; import { LdSignature } from '../misc/ld-signature';
import { ILocalUser } from '../../../models/entities/user';
import { getUserKeypair } from '@/misc/keypair-store'; import { getUserKeypair } from '@/misc/keypair-store';
import { User } from '@/models/entities/user';
export const renderActivity = (x: any): IActivity | null => { export const renderActivity = (x: any): IActivity | null => {
if (x == null) return null; if (x == null) return null;
@ -20,7 +20,7 @@ export const renderActivity = (x: any): IActivity | null => {
}, x); }, x);
}; };
export const attachLdSignature = async (activity: any, user: ILocalUser): Promise<IActivity | null> => { export const attachLdSignature = async (activity: any, user: { id: User['id']; host: null; }): Promise<IActivity | null> => {
if (activity == null) return null; if (activity == null) return null;
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import renderImage from './image'; import renderImage from './image';
import renderKey from './key'; import renderKey from './key';
import config from '@/config'; import config from '@/config';

View File

@ -1,9 +1,9 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
import { Note } from '../../../models/entities/note'; import { Note } from '../../../models/entities/note';
import { Poll } from '../../../models/entities/poll'; import { Poll } from '../../../models/entities/poll';
export default async function renderQuestion(user: ILocalUser, note: Note, poll: Poll) { export default async function renderQuestion(user: { id: User['id'] }, note: Note, poll: Poll) {
const question = { const question = {
type: 'Question', type: 'Question',
id: `${config.url}/questions/${note.id}`, id: `${config.url}/questions/${note.id}`,

View File

@ -1,8 +1,8 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
import { MessagingMessage } from '../../../models/entities/messaging-message'; import { MessagingMessage } from '../../../models/entities/messaging-message';
export const renderReadActivity = (user: ILocalUser, message: MessagingMessage) => ({ export const renderReadActivity = (user: { id: User['id'] }, message: MessagingMessage) => ({
type: 'Read', type: 'Read',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object: message.uri object: message.uri

View File

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
export default (object: any, user: ILocalUser) => ({ export default (object: any, user: { id: User['id'] }) => ({
type: 'Reject', type: 'Reject',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object object

View File

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
export default (user: ILocalUser, target: any, object: any) => ({ export default (user: { id: User['id'] }, target: any, object: any) => ({
type: 'Remove', type: 'Remove',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
target, target,

View File

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser, User } from '../../../models/entities/user'; import { ILocalUser, User } from '../../../models/entities/user';
export default (object: any, user: ILocalUser | User) => ({ export default (object: any, user: { id: User['id'] }) => ({
type: 'Undo', type: 'Undo',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object object

View File

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
export default (object: any, user: ILocalUser) => { export default (object: any, user: { id: User['id'] }) => {
const activity = { const activity = {
id: `${config.url}/users/${user.id}#updates/${new Date().getTime()}`, id: `${config.url}/users/${user.id}#updates/${new Date().getTime()}`,
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,

View File

@ -1,10 +1,10 @@
import config from '@/config'; import config from '@/config';
import { Note } from '../../../models/entities/note'; import { Note } from '../../../models/entities/note';
import { IRemoteUser, ILocalUser } from '../../../models/entities/user'; import { IRemoteUser, User } from '../../../models/entities/user';
import { PollVote } from '../../../models/entities/poll-vote'; import { PollVote } from '../../../models/entities/poll-vote';
import { Poll } from '../../../models/entities/poll'; import { Poll } from '../../../models/entities/poll';
export default async function renderVote(user: ILocalUser, vote: PollVote, note: Note, poll: Poll, pollOwner: IRemoteUser): Promise<any> { export default async function renderVote(user: { id: User['id'] }, vote: PollVote, note: Note, poll: Poll, pollOwner: IRemoteUser): Promise<any> {
return { return {
id: `${config.url}/users/${user.id}#votes/${vote.id}/activity`, id: `${config.url}/users/${user.id}#votes/${vote.id}/activity`,
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,

View File

@ -4,14 +4,14 @@ import { sign } from 'http-signature';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../models/entities/user'; import { User } from '@/models/entities/user';
import { getAgentByUrl } from '@/misc/fetch'; import { getAgentByUrl } from '@/misc/fetch';
import { URL } from 'url'; import { URL } from 'url';
import got from 'got'; import got from 'got';
import * as Got from 'got'; import * as Got from 'got';
import { getUserKeypair } from '@/misc/keypair-store'; import { getUserKeypair } from '@/misc/keypair-store';
export default async (user: ILocalUser, url: string, object: any) => { export default async (user: { id: User['id'] }, url: string, object: any) => {
const timeout = 10 * 1000; const timeout = 10 * 1000;
const { protocol, hostname, port, pathname, search } = new URL(url); const { protocol, hostname, port, pathname, search } = new URL(url);
@ -24,7 +24,7 @@ export default async (user: ILocalUser, url: string, object: any) => {
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);
await new Promise((resolve, reject) => { await new Promise<void>((resolve, reject) => {
const req = https.request({ const req = https.request({
agent: getAgentByUrl(new URL(`https://example.net`)), agent: getAgentByUrl(new URL(`https://example.net`)),
protocol, protocol,
@ -69,7 +69,7 @@ export default async (user: ILocalUser, url: string, object: any) => {
* @param user http-signature user * @param user http-signature user
* @param url URL to fetch * @param url URL to fetch
*/ */
export async function signedGet(url: string, user: ILocalUser) { export async function signedGet(url: string, user: { id: User['id'] }) {
const timeout = 10 * 1000; const timeout = 10 * 1000;
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import webFinger from './webfinger'; import webFinger from './webfinger';
import config from '@/config'; import config from '@/config';
import { createPerson, updatePerson } from './activitypub/models/person'; import { createPerson, updatePerson } from './activitypub/models/person';

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import { getJson } from '@/misc/fetch'; import { getJson } from '@/misc/fetch';
import { query as urlQuery } from '../prelude/url'; import { query as urlQuery } from '../prelude/url';

View File

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { Blockings } from '../../../models'; import { Blockings } from '../../../models';
import { SelectQueryBuilder } from 'typeorm'; import { SelectQueryBuilder } from 'typeorm';
export function generateBlockQueryForUsers(q: SelectQueryBuilder<any>, me: User) { export function generateBlockQueryForUsers(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const blockingQuery = Blockings.createQueryBuilder('blocking') const blockingQuery = Blockings.createQueryBuilder('blocking')
.select('blocking.blockeeId') .select('blocking.blockeeId')
.where('blocking.blockerId = :blockerId', { blockerId: me.id }); .where('blocking.blockerId = :blockerId', { blockerId: me.id });

View File

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { ChannelFollowings } from '../../../models'; import { ChannelFollowings } from '../../../models';
import { Brackets, SelectQueryBuilder } from 'typeorm'; import { Brackets, SelectQueryBuilder } from 'typeorm';
export function generateChannelQuery(q: SelectQueryBuilder<any>, me?: User | null) { export function generateChannelQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) {
if (me == null) { if (me == null) {
q.andWhere('note.channelId IS NULL'); q.andWhere('note.channelId IS NULL');
} else { } else {

View File

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { MutedNotes } from '../../../models'; import { MutedNotes } from '../../../models';
import { SelectQueryBuilder } from 'typeorm'; import { SelectQueryBuilder } from 'typeorm';
export function generateMutedNoteQuery(q: SelectQueryBuilder<any>, me: User) { export function generateMutedNoteQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const mutedQuery = MutedNotes.createQueryBuilder('muted') const mutedQuery = MutedNotes.createQueryBuilder('muted')
.select('muted.noteId') .select('muted.noteId')
.where('muted.userId = :userId', { userId: me.id }); .where('muted.userId = :userId', { userId: me.id });

View File

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { Mutings } from '../../../models'; import { Mutings } from '../../../models';
import { SelectQueryBuilder, Brackets } from 'typeorm'; import { SelectQueryBuilder, Brackets } from 'typeorm';
export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: User, exclude?: User) { export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }, exclude?: User) {
const mutingQuery = Mutings.createQueryBuilder('muting') const mutingQuery = Mutings.createQueryBuilder('muting')
.select('muting.muteeId') .select('muting.muteeId')
.where('muting.muterId = :muterId', { muterId: me.id }); .where('muting.muterId = :muterId', { muterId: me.id });
@ -28,7 +28,7 @@ export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: User, exc
q.setParameters(mutingQuery.getParameters()); q.setParameters(mutingQuery.getParameters());
} }
export function generateMutedUserQueryForUsers(q: SelectQueryBuilder<any>, me: User) { export function generateMutedUserQueryForUsers(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const mutingQuery = Mutings.createQueryBuilder('muting') const mutingQuery = Mutings.createQueryBuilder('muting')
.select('muting.muteeId') .select('muting.muteeId')
.where('muting.muterId = :muterId', { muterId: me.id }); .where('muting.muterId = :muterId', { muterId: me.id });

View File

@ -1,7 +1,7 @@
import { User } from '../../../models/entities/user'; import { User } from '../../../models/entities/user';
import { Brackets, SelectQueryBuilder } from 'typeorm'; import { Brackets, SelectQueryBuilder } from 'typeorm';
export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: User | null) { export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) {
if (me == null) { if (me == null) {
q.andWhere(new Brackets(qb => { qb q.andWhere(new Brackets(qb => { qb
.where(`note.replyId IS NULL`) // 返信ではない .where(`note.replyId IS NULL`) // 返信ではない

View File

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { Followings } from '../../../models'; import { Followings } from '../../../models';
import { Brackets, SelectQueryBuilder } from 'typeorm'; import { Brackets, SelectQueryBuilder } from 'typeorm';
export function generateVisibilityQuery(q: SelectQueryBuilder<any>, me?: User | null) { export function generateVisibilityQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) {
if (me == null) { if (me == null) {
q.andWhere(new Brackets(qb => { qb q.andWhere(new Brackets(qb => { qb
.where(`note.visibility = 'public'`) .where(`note.visibility = 'public'`)

View File

@ -1,7 +1,7 @@
import { publishMainStream, publishGroupMessagingStream } from '../../../services/stream'; import { publishMainStream, publishGroupMessagingStream } from '../../../services/stream';
import { publishMessagingStream } from '../../../services/stream'; import { publishMessagingStream } from '../../../services/stream';
import { publishMessagingIndexStream } from '../../../services/stream'; import { publishMessagingIndexStream } from '../../../services/stream';
import { User, ILocalUser, IRemoteUser } from '../../../models/entities/user'; import { User, IRemoteUser } from '../../../models/entities/user';
import { MessagingMessage } from '../../../models/entities/messaging-message'; import { MessagingMessage } from '../../../models/entities/messaging-message';
import { MessagingMessages, UserGroupJoinings, Users } from '../../../models'; import { MessagingMessages, UserGroupJoinings, Users } from '../../../models';
import { In } from 'typeorm'; import { In } from 'typeorm';
@ -107,7 +107,7 @@ export async function readGroupMessagingMessage(
} }
} }
export async function deliverReadActivity(user: ILocalUser, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) { export async function deliverReadActivity(user: { id: User['id']; host: null; }, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) {
messages = toArray(messages).filter(x => x.uri); messages = toArray(messages).filter(x => x.uri);
const contents = messages.map(x => renderReadActivity(user, x)); const contents = messages.map(x => renderReadActivity(user, x));

View File

@ -5,6 +5,18 @@ import { ApiError } from './error';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { AccessToken } from '../../models/entities/access-token'; import { AccessToken } from '../../models/entities/access-token';
type SimpleUserInfo = {
id: ILocalUser['id'];
host: ILocalUser['host'];
username: ILocalUser['username'];
uri: ILocalUser['uri'];
inbox: ILocalUser['inbox'];
sharedInbox: ILocalUser['sharedInbox'];
isAdmin: ILocalUser['isAdmin'];
isModerator: ILocalUser['isModerator'];
isSilenced: ILocalUser['isSilenced'];
};
// TODO: defaultが設定されている場合はその型も考慮する // TODO: defaultが設定されている場合はその型も考慮する
type Params<T extends IEndpointMeta> = { type Params<T extends IEndpointMeta> = {
[P in keyof T['params']]: NonNullable<T['params']>[P]['transform'] extends Function [P in keyof T['params']]: NonNullable<T['params']>[P]['transform'] extends Function
@ -15,13 +27,12 @@ type Params<T extends IEndpointMeta> = {
export type Response = Record<string, any> | void; export type Response = Record<string, any> | void;
type executor<T extends IEndpointMeta> = type executor<T extends IEndpointMeta> =
(params: Params<T>, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any, cleanup?: Function) => (params: Params<T>, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any, cleanup?: Function) =>
Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>; Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>;
// TODO: API関数に user まるごと渡すのではなくユーザーIDなどの最小限のプロパティだけ渡すようにしたい(キャッシュとか考えないでよくなるため)
export default function <T extends IEndpointMeta>(meta: T, cb: executor<T>) export default function <T extends IEndpointMeta>(meta: T, cb: executor<T>)
: (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any) => Promise<any> { : (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => Promise<any> {
return (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any) => { return (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => {
function cleanup() { function cleanup() {
fs.unlink(file.path, () => {}); fs.unlink(file.path, () => {});
} }

View File

@ -34,7 +34,8 @@ export const meta = {
} }
}; };
export default define(meta, async (ps, me) => { export default define(meta, async (ps, _me) => {
const me = _me ? await Users.findOneOrFail(_me.id) : null;
const noUsers = (await Users.count({ const noUsers = (await Users.count({
host: null, host: null,
})) === 0; })) === 0;

View File

@ -96,9 +96,9 @@ export default define(meta, async (ps) => {
emojis = await q.getMany(); emojis = await q.getMany();
emojis = emojis.filter(emoji => emojis = emojis.filter(emoji =>
emoji.name.includes(ps.query) || emoji.name.includes(ps.query!) ||
emoji.aliases.some(a => a.includes(ps.query)) || emoji.aliases.some(a => a.includes(ps.query!)) ||
emoji.category?.includes(ps.query)); emoji.category?.includes(ps.query!));
emojis.splice(ps.limit! + 1); emojis.splice(ps.limit! + 1);
} else { } else {

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import define from '../../../define'; import define from '../../../define';
import { deliverQueue } from '../../../../../queue'; import { deliverQueue } from '../../../../../queue';

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import define from '../../../define'; import define from '../../../define';
import { inboxQueue } from '../../../../../queue'; import { inboxQueue } from '../../../../../queue';

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import $ from 'cafy'; import $ from 'cafy';
import define from '../../../define'; import define from '../../../define';
import { addRelay } from '../../../../../services/relay'; import { addRelay } from '../../../../../services/relay';

View File

@ -89,7 +89,7 @@ export default define(meta, async (ps, user) => {
let userList; let userList;
let userGroupJoining; let userGroupJoining;
if (ps.src === 'list') { if (ps.src === 'list' && ps.userListId) {
userList = await UserLists.findOne({ userList = await UserLists.findOne({
id: ps.userListId, id: ps.userListId,
userId: user.id, userId: user.id,
@ -98,7 +98,7 @@ export default define(meta, async (ps, user) => {
if (userList == null) { if (userList == null) {
throw new ApiError(meta.errors.noSuchUserList); throw new ApiError(meta.errors.noSuchUserList);
} }
} else if (ps.src === 'group') { } else if (ps.src === 'group' && ps.userGroupId) {
userGroupJoining = await UserGroupJoinings.findOne({ userGroupJoining = await UserGroupJoinings.findOne({
userGroupId: ps.userGroupId, userGroupId: ps.userGroupId,
userId: user.id, userId: user.id,

View File

@ -108,7 +108,7 @@ export default define(meta, async (ps, user) => {
let userList; let userList;
let userGroupJoining; let userGroupJoining;
if (ps.src === 'list') { if (ps.src === 'list' && ps.userListId) {
userList = await UserLists.findOne({ userList = await UserLists.findOne({
id: ps.userListId, id: ps.userListId,
userId: user.id, userId: user.id,
@ -117,7 +117,7 @@ export default define(meta, async (ps, user) => {
if (userList == null) { if (userList == null) {
throw new ApiError(meta.errors.noSuchUserList); throw new ApiError(meta.errors.noSuchUserList);
} }
} else if (ps.src === 'group') { } else if (ps.src === 'group' && ps.userGroupId) {
userGroupJoining = await UserGroupJoinings.findOne({ userGroupJoining = await UserGroupJoinings.findOne({
userGroupId: ps.userGroupId, userGroupId: ps.userGroupId,
userId: user.id, userId: user.id,

View File

@ -46,6 +46,6 @@ export default define(meta, async (ps, user, token) => {
return await Apps.pack(ap, user, { return await Apps.pack(ap, user, {
detail: true, detail: true,
includeSecret: isSecure && (ap.userId === user.id) includeSecret: isSecure && (ap.userId === user!.id)
}); });
}); });

View File

@ -62,7 +62,7 @@ export const meta = {
}; };
export default define(meta, async (ps, user) => { export default define(meta, async (ps, user) => {
const blocker = user; const blocker = await Users.findOneOrFail(user.id);
// 自分自身 // 自分自身
if (user.id === ps.userId) { if (user.id === ps.userId) {
@ -93,7 +93,7 @@ export default define(meta, async (ps, user) => {
noteUserId: blockee.id noteUserId: blockee.id
}); });
return await Users.pack(blockee.id, user, { return await Users.pack(blockee.id, blocker, {
detail: true detail: true
}); });
}); });

View File

@ -126,7 +126,7 @@ export const meta = {
}; };
export default define(meta, async (ps, user) => { export default define(meta, async (ps, user) => {
const blocker = user; const blocker = await Users.findOneOrFail(user.id);
// Check if the blockee is yourself // Check if the blockee is yourself
if (user.id === ps.userId) { if (user.id === ps.userId) {
@ -152,7 +152,7 @@ export default define(meta, async (ps, user) => {
// Delete blocking // Delete blocking
await deleteBlocking(blocker, blockee); await deleteBlocking(blocker, blockee);
return await Users.pack(blockee.id, user, { return await Users.pack(blockee.id, blocker, {
detail: true detail: true
}); });
}); });

View File

@ -97,7 +97,7 @@ export default define(meta, async (ps, user) => {
const timeline = await query.take(ps.limit!).getMany(); const timeline = await query.take(ps.limit!).getMany();
activeUsersChart.update(user); if (user) activeUsersChart.update(user);
return await Notes.packMany(timeline, user); return await Notes.packMany(timeline, user);
}); });

View File

@ -32,14 +32,14 @@ export const meta = {
}; };
export default define(meta, async (ps, user) => { export default define(meta, async (ps, user) => {
const clip = await Clips.save({ const clip = await Clips.insert({
id: genId(), id: genId(),
createdAt: new Date(), createdAt: new Date(),
userId: user.id, userId: user.id,
name: ps.name, name: ps.name,
isPublic: ps.isPublic, isPublic: ps.isPublic,
description: ps.description, description: ps.description,
}); }).then(x => Clips.findOneOrFail(x.identifiers[0]));
return await Clips.pack(clip); return await Clips.pack(clip);
}); });

View File

@ -34,7 +34,7 @@ export default define(meta, async (ps, user) => {
const instance = await fetchMeta(true); const instance = await fetchMeta(true);
// Calculate drive usage // Calculate drive usage
const usage = await DriveFiles.calcDriveUsageOf(user); const usage = await DriveFiles.calcDriveUsageOf(user.id);
return { return {
capacity: 1024 * 1024 * instance.localDriveCapacityMb, capacity: 1024 * 1024 * instance.localDriveCapacityMb,

View File

@ -68,13 +68,13 @@ export default define(meta, async (ps, user) => {
} }
// Create folder // Create folder
const folder = await DriveFolders.save({ const folder = await DriveFolders.insert({
id: genId(), id: genId(),
createdAt: new Date(), createdAt: new Date(),
name: ps.name, name: ps.name,
parentId: parent !== null ? parent.id : null, parentId: parent !== null ? parent.id : null,
userId: user.id userId: user.id
}); }).then(x => DriveFolders.findOneOrFail(x.identifiers[0]));
const folderObj = await DriveFolders.pack(folder); const folderObj = await DriveFolders.pack(folder);

View File

@ -2,7 +2,6 @@ import $ from 'cafy';
import define from '../../define'; import define from '../../define';
import { Instances } from '../../../../models'; import { Instances } from '../../../../models';
import { toPuny } from '@/misc/convert-host'; import { toPuny } from '@/misc/convert-host';
import config from '@/config';
export const meta = { export const meta = {
tags: ['federation'], tags: ['federation'],

View File

@ -140,7 +140,7 @@ export default define(meta, async (ps, user) => {
const query = makePaginationQuery(ReversiGames.createQueryBuilder('game'), ps.sinceId, ps.untilId) const query = makePaginationQuery(ReversiGames.createQueryBuilder('game'), ps.sinceId, ps.untilId)
.andWhere('game.isStarted = TRUE'); .andWhere('game.isStarted = TRUE');
if (ps.my) { if (ps.my && user) {
query.andWhere(new Brackets(qb => { qb query.andWhere(new Brackets(qb => { qb
.where('game.user1Id = :userId', { userId: user.id }) .where('game.user1Id = :userId', { userId: user.id })
.orWhere('game.user2Id = :userId', { userId: user.id }); .orWhere('game.user2Id = :userId', { userId: user.id });

View File

@ -72,7 +72,7 @@ export default define(meta, async (ps, user) => {
isLlotheo: false isLlotheo: false
} as Partial<ReversiGame>); } as Partial<ReversiGame>);
publishReversiStream(exist.parentId, 'matched', await ReversiGames.pack(game, exist.parentId)); publishReversiStream(exist.parentId, 'matched', await ReversiGames.pack(game, { id: exist.parentId }));
const other = await ReversiMatchings.count({ const other = await ReversiMatchings.count({
childId: user.id childId: user.id

View File

@ -61,7 +61,7 @@ export default define(meta, async (ps, user) => {
throw e; throw e;
}); });
return await Users.pack(user, user, { return await Users.pack(user.id, user, {
detail: true detail: true
}); });
}); });

View File

@ -1,4 +1,3 @@
import $ from 'cafy';
import define from '../../../define'; import define from '../../../define';
import { RegistryItems } from '../../../../../models'; import { RegistryItems } from '../../../../../models';

View File

@ -47,7 +47,7 @@ export default define(meta, async (ps, user) => {
throw e; throw e;
}); });
return await Users.pack(user, user, { return await Users.pack(user.id, user, {
detail: true detail: true
}); });
}); });

View File

@ -205,7 +205,8 @@ export const meta = {
} }
}; };
export default define(meta, async (ps, user, token) => { export default define(meta, async (ps, _user, token) => {
const user = await Users.findOneOrFail(_user.id);
const isSecure = token == null; const isSecure = token == null;
const updates = {} as Partial<User>; const updates = {} as Partial<User>;

View File

@ -5,7 +5,7 @@ import define from '../../define';
import * as ms from 'ms'; import * as ms from 'ms';
import { getNote } from '../../common/getters'; import { getNote } from '../../common/getters';
import { ApiError } from '../../error'; import { ApiError } from '../../error';
import { Notes } from '../../../../models'; import { Notes, Users } from '../../../../models';
export const meta = { export const meta = {
desc: { desc: {
@ -55,6 +55,6 @@ export default define(meta, async (ps, user) => {
}); });
for (const note of renotes) { for (const note of renotes) {
deleteNote(user, note); deleteNote(await Users.findOneOrFail(user.id), note);
} }
}); });

View File

@ -43,7 +43,7 @@ export default define(meta, async (ps, user) => {
event: ps.event, event: ps.event,
var: ps.var, var: ps.var,
userId: user.id, userId: user.id,
user: await Users.pack(user, page.userId, { user: await Users.pack(user.id, { id: page.userId }, {
detail: true detail: true
}) })
}); });

View File

@ -31,12 +31,12 @@ export const meta = {
}; };
export default define(meta, async (ps, user) => { export default define(meta, async (ps, user) => {
const userGroup = await UserGroups.save({ const userGroup = await UserGroups.insert({
id: genId(), id: genId(),
createdAt: new Date(), createdAt: new Date(),
userId: user.id, userId: user.id,
name: ps.name, name: ps.name,
} as UserGroup); } as UserGroup).then(x => UserGroups.findOneOrFail(x.identifiers[0]));
// Push the owner // Push the owner
await UserGroupJoinings.insert({ await UserGroupJoinings.insert({

View File

@ -96,12 +96,12 @@ export default define(meta, async (ps, me) => {
throw new ApiError(meta.errors.alreadyInvited); throw new ApiError(meta.errors.alreadyInvited);
} }
const invitation = await UserGroupInvitations.save({ const invitation = await UserGroupInvitations.insert({
id: genId(), id: genId(),
createdAt: new Date(), createdAt: new Date(),
userId: user.id, userId: user.id,
userGroupId: userGroup.id userGroupId: userGroup.id
} as UserGroupInvitation); } as UserGroupInvitation).then(x => UserGroupInvitations.findOneOrFail(x.identifiers[0]));
// 通知を作成 // 通知を作成
createNotification(user.id, 'groupInvited', { createNotification(user.id, 'groupInvited', {

View File

@ -30,12 +30,12 @@ export const meta = {
}; };
export default define(meta, async (ps, user) => { export default define(meta, async (ps, user) => {
const userList = await UserLists.save({ const userList = await UserLists.insert({
id: genId(), id: genId(),
createdAt: new Date(), createdAt: new Date(),
userId: user.id, userId: user.id,
name: ps.name, name: ps.name,
} as UserList); } as UserList).then(x => UserLists.findOneOrFail(x.identifiers[0]));
return await UserLists.pack(userList); return await UserLists.pack(userList);
}); });

View File

@ -6,6 +6,7 @@ import { ApiError } from '../../error';
import { ID } from '@/misc/cafy-id'; import { ID } from '@/misc/cafy-id';
import { Users } from '../../../../models'; import { Users } from '../../../../models';
import { In } from 'typeorm'; import { In } from 'typeorm';
import { User } from '@/models/entities/user';
export const meta = { export const meta = {
desc: { desc: {
@ -81,9 +82,9 @@ export default define(meta, async (ps, me) => {
}); });
// リクエストされた通りに並べ替え // リクエストされた通りに並べ替え
const _users = []; const _users: User[] = [];
for (const id of ps.userIds) { for (const id of ps.userIds) {
_users.push(users.find(x => x.id === id)); _users.push(users.find(x => x.id === id)!);
} }
return await Promise.all(_users.map(u => Users.pack(u, me, { return await Promise.all(_users.map(u => Users.pack(u, me, {

View File

@ -7,7 +7,7 @@ import Logger from '../../services/logger';
const logger = new Logger('limiter'); const logger = new Logger('limiter');
export default (endpoint: IEndpoint, user: User) => new Promise((ok, reject) => { export default (endpoint: IEndpoint, user: User) => new Promise<void>((ok, reject) => {
const limitation = endpoint.meta.limit!; const limitation = endpoint.meta.limit!;
const key = limitation.hasOwnProperty('key') const key = limitation.hasOwnProperty('key')

View File

@ -26,7 +26,7 @@ export default class extends Channel {
childId: body.id childId: body.id
}); });
if (matching == null) return; if (matching == null) return;
publishMainStream(matching.childId, 'reversiInvited', await ReversiMatchings.pack(matching, matching.childId)); publishMainStream(matching.childId, 'reversiInvited', await ReversiMatchings.pack(matching, { id: matching.childId }));
break; break;
} }
} }

View File

@ -42,8 +42,9 @@ export default class extends Channel {
// 関係ない返信は除外 // 関係ない返信は除外
if (note.reply) { if (note.reply) {
const reply = note.reply as PackedNote;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
} }
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する

View File

@ -50,8 +50,9 @@ export default class extends Channel {
// 関係ない返信は除外 // 関係ない返信は除外
if (note.reply) { if (note.reply) {
const reply = note.reply as PackedNote;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
} }
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する

View File

@ -59,8 +59,9 @@ export default class extends Channel {
// 関係ない返信は除外 // 関係ない返信は除外
if (note.reply) { if (note.reply) {
const reply = note.reply as PackedNote;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
} }
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する

View File

@ -44,8 +44,9 @@ export default class extends Channel {
// 関係ない返信は除外 // 関係ない返信は除外
if (note.reply) { if (note.reply) {
const reply = note.reply as PackedNote;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
} }
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する

View File

@ -156,8 +156,8 @@ export default class Connection {
}; };
add(note); add(note);
if (note.reply) add(note.reply); if (note.reply) add(note.reply as PackedNote);
if (note.renote) add(note.renote); if (note.renote) add(note.renote as PackedNote);
} }
@autobind @autobind

View File

@ -89,7 +89,7 @@ router.get('/verify-email/:code', async ctx => {
emailVerifyCode: null emailVerifyCode: null
}); });
publishMainStream(profile.userId, 'meUpdated', await Users.pack(profile.userId, profile.userId, { publishMainStream(profile.userId, 'meUpdated', await Users.pack(profile.userId, { id: profile.userId }, {
detail: true, detail: true,
includeSecrets: true includeSecrets: true
})); }));

View File

@ -6,7 +6,7 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import { publishAntennaStream, publishMainStream } from './stream'; import { publishAntennaStream, publishMainStream } from './stream';
import { User } from '../models/entities/user'; import { User } from '../models/entities/user';
export async function addNoteToAntenna(antenna: Antenna, note: Note, noteUser: User) { export async function addNoteToAntenna(antenna: Antenna, note: Note, noteUser: { id: User['id']; }) {
// 通知しない設定になっているか、自分自身の投稿なら既読にする // 通知しない設定になっているか、自分自身の投稿なら既読にする
const read = !antenna.notify || (antenna.userId === noteUser.id); const read = !antenna.notify || (antenna.userId === noteUser.id);

View File

@ -35,7 +35,7 @@ export default class ActiveUsersChart extends Chart<ActiveUsersLog> {
} }
@autobind @autobind
public async update(user: User) { public async update(user: { id: User['id'], host: User['host'] }) {
const update: Obj = { const update: Obj = {
users: [user.id] users: [user.id]
}; };

View File

@ -35,7 +35,7 @@ export default class HashtagChart extends Chart<HashtagLog> {
} }
@autobind @autobind
public async update(hashtag: string, user: User) { public async update(hashtag: string, user: { id: User['id'], host: User['host'] }) {
const update: Obj = { const update: Obj = {
users: [user.id] users: [user.id]
}; };

View File

@ -100,7 +100,7 @@ export default class PerUserFollowingChart extends Chart<PerUserFollowingLog> {
} }
@autobind @autobind
public async update(follower: User, followee: User, isFollow: boolean) { public async update(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }, isFollow: boolean) {
const update: Obj = {}; const update: Obj = {};
update.total = isFollow ? 1 : -1; update.total = isFollow ? 1 : -1;

View File

@ -46,7 +46,7 @@ export default class PerUserNotesChart extends Chart<PerUserNotesLog> {
} }
@autobind @autobind
public async update(user: User, note: Note, isAdditional: boolean) { public async update(user: { id: User['id'] }, note: Note, isAdditional: boolean) {
const update: Obj = { const update: Obj = {
diffs: {} diffs: {}
}; };

View File

@ -36,7 +36,7 @@ export default class PerUserReactionsChart extends Chart<PerUserReactionsLog> {
} }
@autobind @autobind
public async update(user: User, note: Note) { public async update(user: { id: User['id'], host: User['host'] }, note: Note) {
this.inc({ this.inc({
[Users.isLocalUser(user) ? 'local' : 'remote']: { count: 1 } [Users.isLocalUser(user) ? 'local' : 'remote']: { count: 1 }
}, note.userId); }, note.userId);

View File

@ -59,7 +59,7 @@ export default class UsersChart extends Chart<UsersLog> {
} }
@autobind @autobind
public async update(user: User, isAdditional: boolean) { public async update(user: { id: User['id'], host: User['host'] }, isAdditional: boolean) {
const update: Obj = {}; const update: Obj = {};
update.total = isAdditional ? 1 : -1; update.total = isAdditional ? 1 : -1;

View File

@ -302,7 +302,7 @@ async function deleteOldFile(user: IRemoteUser) {
* @return Created drive file * @return Created drive file
*/ */
export default async function( export default async function(
user: User | null, user: { id: User['id']; host: User['host'] } | null,
path: string, path: string,
name: string | null = null, name: string | null = null,
comment: string | null = null, comment: string | null = null,
@ -347,7 +347,7 @@ export default async function(
throw new Error('no-free-space'); throw new Error('no-free-space');
} else { } else {
// (アバターまたはバナーを含まず)最も古いファイルを削除する // (アバターまたはバナーを含まず)最も古いファイルを削除する
deleteOldFile(user as IRemoteUser); deleteOldFile(await Users.findOneOrFail(user.id) as IRemoteUser);
} }
} }
} }

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import * as S3 from 'aws-sdk/clients/s3'; import * as S3 from 'aws-sdk/clients/s3';
import { Meta } from '../../models/entities/meta'; import { Meta } from '../../models/entities/meta';
import { getAgentByUrl } from '@/misc/fetch'; import { getAgentByUrl } from '@/misc/fetch';

View File

@ -1,3 +1,4 @@
import { URL } from 'url';
import create from './add-file'; import create from './add-file';
import { User } from '../../models/entities/user'; import { User } from '../../models/entities/user';
import { driveLogger } from './logger'; import { driveLogger } from './logger';
@ -11,7 +12,7 @@ const logger = driveLogger.createSubLogger('downloader');
export default async ( export default async (
url: string, url: string,
user: User | null, user: { id: User['id']; host: User['host'] } | null,
folderId: DriveFolder['id'] | null = null, folderId: DriveFolder['id'] | null = null,
uri: string | null = null, uri: string | null = null,
sensitive = false, sensitive = false,

View File

@ -17,7 +17,7 @@ import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error';
const logger = new Logger('following/create'); const logger = new Logger('following/create');
export async function insertFollowingDoc(followee: User, follower: User) { export async function insertFollowingDoc(followee: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox'] }, follower: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox'] }) {
if (follower.id === followee.id) return; if (follower.id === followee.id) return;
let alreadyFollowed = false; let alreadyFollowed = false;
@ -86,7 +86,7 @@ export async function insertFollowingDoc(followee: User, follower: User) {
// Publish follow event // Publish follow event
if (Users.isLocalUser(follower)) { if (Users.isLocalUser(follower)) {
Users.pack(followee, follower, { Users.pack(followee.id, follower, {
detail: true detail: true
}).then(packed => { }).then(packed => {
publishUserEvent(follower.id, 'follow', packed); publishUserEvent(follower.id, 'follow', packed);
@ -96,7 +96,7 @@ export async function insertFollowingDoc(followee: User, follower: User) {
// Publish followed event // Publish followed event
if (Users.isLocalUser(followee)) { if (Users.isLocalUser(followee)) {
Users.pack(follower, followee).then(packed => publishMainStream(followee.id, 'followed', packed)); Users.pack(follower.id, followee).then(packed => publishMainStream(followee.id, 'followed', packed));
// 通知を作成 // 通知を作成
createNotification(followee.id, 'follow', { createNotification(followee.id, 'follow', {
@ -105,7 +105,12 @@ export async function insertFollowingDoc(followee: User, follower: User) {
} }
} }
export default async function(follower: User, followee: User, requestId?: string) { export default async function(_follower: { id: User['id'] }, _followee: { id: User['id'] }, requestId?: string) {
const [follower, followee] = await Promise.all([
Users.findOneOrFail(_follower.id),
Users.findOneOrFail(_followee.id)
]);
// check blocking // check blocking
const [blocking, blocked] = await Promise.all([ const [blocking, blocked] = await Promise.all([
Blockings.findOne({ Blockings.findOne({

View File

@ -11,7 +11,7 @@ import { instanceChart, perUserFollowingChart } from '../chart';
const logger = new Logger('following/delete'); const logger = new Logger('following/delete');
export default async function(follower: User, followee: User, silent = false) { export default async function(follower: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }, followee: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }, silent = false) {
const following = await Followings.findOne({ const following = await Followings.findOne({
followerId: follower.id, followerId: follower.id,
followeeId: followee.id followeeId: followee.id
@ -28,7 +28,7 @@ export default async function(follower: User, followee: User, silent = false) {
// Publish unfollow event // Publish unfollow event
if (!silent && Users.isLocalUser(follower)) { if (!silent && Users.isLocalUser(follower)) {
Users.pack(followee, follower, { Users.pack(followee.id, follower, {
detail: true detail: true
}).then(packed => { }).then(packed => {
publishUserEvent(follower.id, 'unfollow', packed); publishUserEvent(follower.id, 'unfollow', packed);
@ -42,7 +42,7 @@ export default async function(follower: User, followee: User, silent = false) {
} }
} }
export async function decrementFollowing(follower: User, followee: User) { export async function decrementFollowing(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }) {
//#region Decrement following count //#region Decrement following count
Users.decrement({ id: follower.id }, 'followingCount', 1); Users.decrement({ id: follower.id }, 'followingCount', 1);
//#endregion //#endregion

View File

@ -6,7 +6,7 @@ import { FollowRequests, Users } from '../../../models';
* *
* @param user * @param user
*/ */
export default async function(user: User) { export default async function(user: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }) {
const requests = await FollowRequests.find({ const requests = await FollowRequests.find({
followeeId: user.id followeeId: user.id
}); });

View File

@ -8,7 +8,7 @@ import { User, ILocalUser } from '../../../models/entities/user';
import { FollowRequests, Users } from '../../../models'; import { FollowRequests, Users } from '../../../models';
import { IdentifiableError } from '@/misc/identifiable-error'; import { IdentifiableError } from '@/misc/identifiable-error';
export default async function(followee: User, follower: User) { export default async function(followee: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }, follower: User) {
const request = await FollowRequests.findOne({ const request = await FollowRequests.findOne({
followeeId: followee.id, followeeId: followee.id,
followerId: follower.id followerId: follower.id
@ -20,12 +20,12 @@ export default async function(followee: User, follower: User) {
await insertFollowingDoc(followee, follower); await insertFollowingDoc(followee, follower);
if (Users.isRemoteUser(follower)) { if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
const content = renderActivity(renderAccept(renderFollow(follower, followee, request.requestId!), followee as ILocalUser)); const content = renderActivity(renderAccept(renderFollow(follower, followee, request.requestId!), followee));
deliver(followee as ILocalUser, content, follower.inbox); deliver(followee, content, follower.inbox);
} }
Users.pack(followee, followee, { Users.pack(followee.id, followee, {
detail: true detail: true
}).then(packed => publishMainStream(followee.id, 'meUpdated', packed)); }).then(packed => publishMainStream(followee.id, 'meUpdated', packed));
} }

View File

@ -7,10 +7,13 @@ import { IdentifiableError } from '@/misc/identifiable-error';
import { User, ILocalUser } from '../../../models/entities/user'; import { User, ILocalUser } from '../../../models/entities/user';
import { Users, FollowRequests } from '../../../models'; import { Users, FollowRequests } from '../../../models';
export default async function(followee: User, follower: User) { export default async function(followee: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox'] }, follower: { id: User['id']; host: User['host']; uri: User['host'] }) {
if (Users.isRemoteUser(followee)) { if (Users.isRemoteUser(followee)) {
const content = renderActivity(renderUndo(renderFollow(follower, followee), follower)); const content = renderActivity(renderUndo(renderFollow(follower, followee), follower));
deliver(follower as ILocalUser, content, followee.inbox);
if (Users.isLocalUser(follower)) { // 本来このチェックは不要だけどTSに怒られるので
deliver(follower, content, followee.inbox);
}
} }
const request = await FollowRequests.findOne({ const request = await FollowRequests.findOne({
@ -27,7 +30,7 @@ export default async function(followee: User, follower: User) {
followerId: follower.id followerId: follower.id
}); });
Users.pack(followee, followee, { Users.pack(followee.id, followee, {
detail: true detail: true
}).then(packed => publishMainStream(followee.id, 'meUpdated', packed)); }).then(packed => publishMainStream(followee.id, 'meUpdated', packed));
} }

View File

@ -7,7 +7,7 @@ import { Blockings, FollowRequests, Users } from '../../../models';
import { genId } from '@/misc/gen-id'; import { genId } from '@/misc/gen-id';
import { createNotification } from '../../create-notification'; import { createNotification } from '../../create-notification';
export default async function(follower: User, followee: User, requestId?: string) { export default async function(follower: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }, followee: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }, requestId?: string) {
if (follower.id === followee.id) return; if (follower.id === followee.id) return;
// check blocking // check blocking
@ -43,9 +43,9 @@ export default async function(follower: User, followee: User, requestId?: string
// Publish receiveRequest event // Publish receiveRequest event
if (Users.isLocalUser(followee)) { if (Users.isLocalUser(followee)) {
Users.pack(follower, followee).then(packed => publishMainStream(followee.id, 'receiveFollowRequest', packed)); Users.pack(follower.id, followee).then(packed => publishMainStream(followee.id, 'receiveFollowRequest', packed));
Users.pack(followee, followee, { Users.pack(followee.id, followee, {
detail: true detail: true
}).then(packed => publishMainStream(followee.id, 'meUpdated', packed)); }).then(packed => publishMainStream(followee.id, 'meUpdated', packed));

View File

@ -7,15 +7,15 @@ import { User, ILocalUser } from '../../../models/entities/user';
import { Users, FollowRequests, Followings } from '../../../models'; import { Users, FollowRequests, Followings } from '../../../models';
import { decrementFollowing } from '../delete'; import { decrementFollowing } from '../delete';
export default async function(followee: User, follower: User) { export default async function(followee: { id: User['id']; host: User['host']; uri: User['host'] }, follower: User) {
if (Users.isRemoteUser(follower)) { if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
const request = await FollowRequests.findOne({ const request = await FollowRequests.findOne({
followeeId: followee.id, followeeId: followee.id,
followerId: follower.id followerId: follower.id
}); });
const content = renderActivity(renderReject(renderFollow(follower, followee, request!.requestId!), followee as ILocalUser)); const content = renderActivity(renderReject(renderFollow(follower, followee, request!.requestId!), followee));
deliver(followee as ILocalUser, content, follower.inbox); deliver(followee, content, follower.inbox);
} }
const request = await FollowRequests.findOne({ const request = await FollowRequests.findOne({
@ -37,7 +37,7 @@ export default async function(followee: User, follower: User) {
} }
} }
Users.pack(followee, follower, { Users.pack(followee.id, follower, {
detail: true detail: true
}).then(packed => { }).then(packed => {
publishUserEvent(follower.id, 'unfollow', packed); publishUserEvent(follower.id, 'unfollow', packed);

View File

@ -16,7 +16,7 @@ import { deliverToRelays } from '../relay';
* @param user * @param user
* @param noteId * @param noteId
*/ */
export async function addPinned(user: User, noteId: Note['id']) { export async function addPinned(user: { id: User['id']; host: User['host']; }, noteId: Note['id']) {
// Fetch pinee // Fetch pinee
const note = await Notes.findOne({ const note = await Notes.findOne({
id: noteId, id: noteId,
@ -55,7 +55,7 @@ export async function addPinned(user: User, noteId: Note['id']) {
* @param user * @param user
* @param noteId * @param noteId
*/ */
export async function removePinned(user: User, noteId: Note['id']) { export async function removePinned(user: { id: User['id']; host: User['host']; }, noteId: Note['id']) {
// Fetch unpinee // Fetch unpinee
const note = await Notes.findOne({ const note = await Notes.findOne({
id: noteId, id: noteId,

Some files were not shown because too many files have changed in this diff Show More