Compare commits

...

11 Commits

Author SHA1 Message Date
60a11f8da5 11.0.0-beta.10 2019-04-13 18:58:48 +09:00
1181fcdceb Fix bug 2019-04-13 18:58:29 +09:00
8cb9852058 リプライ先をエラー時に無視すると本来は投票なのに投票じゃないと扱われおかしくなるのでエラーにするように 2019-04-13 18:45:07 +09:00
53d46d1cbe Fix error 2019-04-13 18:23:32 +09:00
275e1c8de9 Refactor 2019-04-13 18:17:27 +09:00
d46eca4c87 Refactor 2019-04-13 18:14:32 +09:00
2927fb1597 11.0.0-beta.9 2019-04-13 17:27:17 +09:00
8c72e011d2 Fix bug 2019-04-13 17:26:38 +09:00
69662e24c3 Fix bug 2019-04-13 17:24:56 +09:00
96099ffe98 11.0.0-beta.8 2019-04-13 16:55:13 +09:00
ae16b45c11 Fix bug 2019-04-13 16:54:21 +09:00
15 changed files with 48 additions and 33 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "11.0.0-beta.7", "version": "11.0.0-beta.10",
"codename": "daybreak", "codename": "daybreak",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -19,3 +19,8 @@ export function extractDbHost(uri: string) {
export function toPuny(host: string) { export function toPuny(host: string) {
return toASCII(host.toLowerCase()); return toASCII(host.toLowerCase());
} }
export function toPunyNullable(host: string | null | undefined): string | null {
if (host == null) return null;
return toASCII(host.toLowerCase());
}

View File

@ -20,7 +20,7 @@ export async function getFallbackReaction(): Promise<string> {
return meta.useStarForReactionFallback ? 'star' : 'like'; return meta.useStarForReactionFallback ? 'star' : 'like';
} }
export async function toDbReaction(reaction: string, enableEmoji = true): Promise<string> { export async function toDbReaction(reaction?: string | null, enableEmoji = true): Promise<string> {
if (reaction == null) return await getFallbackReaction(); if (reaction == null) return await getFallbackReaction();
// 既存の文字列リアクションはそのまま // 既存の文字列リアクションはそのまま

View File

@ -1,6 +1,7 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { UserList } from '../entities/user-list'; import { UserList } from '../entities/user-list';
import { ensure } from '../../prelude/ensure'; import { ensure } from '../../prelude/ensure';
import { UserListJoinings } from '..';
@EntityRepository(UserList) @EntityRepository(UserList)
export class UserListRepository extends Repository<UserList> { export class UserListRepository extends Repository<UserList> {
@ -9,9 +10,14 @@ export class UserListRepository extends Repository<UserList> {
) { ) {
const userList = typeof src === 'object' ? src : await this.findOne(src).then(ensure); const userList = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
const users = await UserListJoinings.find({
userListId: userList.id
});
return { return {
id: userList.id, id: userList.id,
name: userList.name name: userList.name,
userIds: users.map(x => x.userId)
}; };
} }
} }

View File

@ -12,7 +12,7 @@ import { Instances, Users, UserPublickeys } from '../../models';
import { instanceChart } from '../../services/chart'; import { instanceChart } from '../../services/chart';
import { UserPublickey } from '../../models/entities/user-publickey'; import { UserPublickey } from '../../models/entities/user-publickey';
import fetchMeta from '../../misc/fetch-meta'; import fetchMeta from '../../misc/fetch-meta';
import { toPuny } from '../../misc/convert-host'; import { toPuny, toPunyNullable } from '../../misc/convert-host';
import { validActor } from '../../remote/activitypub/type'; import { validActor } from '../../remote/activitypub/type';
import { ensure } from '../../prelude/ensure'; import { ensure } from '../../prelude/ensure';
@ -36,7 +36,7 @@ export default async (job: Bull.Job): Promise<void> => {
if (keyIdLower.startsWith('acct:')) { if (keyIdLower.startsWith('acct:')) {
const acct = parseAcct(keyIdLower.slice('acct:'.length)); const acct = parseAcct(keyIdLower.slice('acct:'.length));
const host = acct.host ? toPuny(acct.host) : null; const host = toPunyNullable(acct.host);
const username = toPuny(acct.username); const username = toPuny(acct.username);
if (host === null) { if (host === null) {

View File

@ -120,13 +120,15 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
: []; : [];
// リプライ // リプライ
const reply: Note | undefined | null = note.inReplyTo const reply: Note | null = note.inReplyTo
? await resolveNote(note.inReplyTo, resolver).catch(e => { ? await resolveNote(note.inReplyTo, resolver).then(x => {
// 4xxの場合はリプライしてないことにする if (x == null) {
if (e.statusCode >= 400 && e.statusCode < 500) { logger.warn(`Specified inReplyTo, but nout found`);
logger.warn(`Ignored inReplyTo ${note.inReplyTo} - ${e.statusCode} `); throw 'inReplyTo not found';
return null; } else {
return x;
} }
}).catch(e => {
logger.warn(`Error in inReplyTo ${note.inReplyTo} - ${e.statusCode || e}`); logger.warn(`Error in inReplyTo ${note.inReplyTo} - ${e.statusCode || e}`);
throw e; throw e;
}) })
@ -150,11 +152,11 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
const cw = note.summary === '' ? null : note.summary; const cw = note.summary === '' ? null : note.summary;
// テキストのパース // テキストのパース
const text = note._misskey_content || fromHtml(note.content); const text = note._misskey_content || (note.content ? fromHtml(note.content) : null);
// vote // vote
if (reply && reply.hasPoll) { if (reply && reply.hasPoll) {
const poll = await Polls.findOne({ noteId: reply.id }).then(ensure); const poll = await Polls.findOne(reply.id).then(ensure);
const tryCreateVote = async (name: string, index: number): Promise<null> => { const tryCreateVote = async (name: string, index: number): Promise<null> => {
if (poll.expiresAt && Date.now() > new Date(poll.expiresAt).getTime()) { if (poll.expiresAt && Date.now() > new Date(poll.expiresAt).getTime()) {

View File

@ -12,7 +12,7 @@ export interface IObject {
attachment?: any[]; attachment?: any[];
inReplyTo?: any; inReplyTo?: any;
replies?: ICollection; replies?: ICollection;
content: string; content?: string;
name?: string; name?: string;
startTime?: Date; startTime?: Date;
endTime?: Date; endTime?: Date;
@ -44,16 +44,16 @@ export interface IOrderedCollection extends IObject {
export interface INote extends IObject { export interface INote extends IObject {
type: 'Note' | 'Question'; type: 'Note' | 'Question';
_misskey_content: string; _misskey_content?: string;
_misskey_quote: string; _misskey_quote?: string;
_misskey_question: string; _misskey_question?: string;
} }
export interface IQuestion extends IObject { export interface IQuestion extends IObject {
type: 'Note' | 'Question'; type: 'Note' | 'Question';
_misskey_content: string; _misskey_content?: string;
_misskey_quote: string; _misskey_quote?: string;
_misskey_question: string; _misskey_question?: string;
oneOf?: IQuestionChoice[]; oneOf?: IQuestionChoice[];
anyOf?: IQuestionChoice[]; anyOf?: IQuestionChoice[];
endTime?: Date; endTime?: Date;
@ -129,7 +129,7 @@ export interface IRemove extends IActivity {
export interface ILike extends IActivity { export interface ILike extends IActivity {
type: 'Like'; type: 'Like';
_misskey_reaction: string; _misskey_reaction?: string;
} }
export interface IAnnounce extends IActivity { export interface IAnnounce extends IActivity {

View File

@ -1,7 +1,7 @@
import $ from 'cafy'; import $ from 'cafy';
import define from '../../../define'; import define from '../../../define';
import { Emojis } from '../../../../../models'; import { Emojis } from '../../../../../models';
import { toPuny } from '../../../../../misc/convert-host'; import { toPunyNullable } from '../../../../../misc/convert-host';
export const meta = { export const meta = {
desc: { desc: {
@ -23,7 +23,7 @@ export const meta = {
export default define(meta, async (ps) => { export default define(meta, async (ps) => {
const emojis = await Emojis.find({ const emojis = await Emojis.find({
host: ps.host ? toPuny(ps.host) : null host: toPunyNullable(ps.host)
}); });
return emojis.map(e => ({ return emojis.map(e => ({

View File

@ -124,7 +124,7 @@ export default define(meta, async (ps, user) => {
// Increment votes count // Increment votes count
const index = ps.choice + 1; // In SQL, array index is 1 based const index = ps.choice + 1; // In SQL, array index is 1 based
await Polls.query(`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE noteId = '${poll.noteId}'`); await Polls.query(`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`);
publishNoteStream(note.id, 'pollVoted', { publishNoteStream(note.id, 'pollVoted', {
choice: ps.choice, choice: ps.choice,

View File

@ -4,7 +4,7 @@ import define from '../../define';
import { ApiError } from '../../error'; import { ApiError } from '../../error';
import { Users, Followings } from '../../../../models'; import { Users, Followings } from '../../../../models';
import { makePaginationQuery } from '../../common/make-pagination-query'; import { makePaginationQuery } from '../../common/make-pagination-query';
import { toPuny } from '../../../../misc/convert-host'; import { toPunyNullable } from '../../../../misc/convert-host';
export const meta = { export const meta = {
desc: { desc: {
@ -66,7 +66,7 @@ export const meta = {
export default define(meta, async (ps, me) => { export default define(meta, async (ps, me) => {
const user = await Users.findOne(ps.userId != null const user = await Users.findOne(ps.userId != null
? { id: ps.userId } ? { id: ps.userId }
: { usernameLower: ps.username!.toLowerCase(), host: toPuny(ps.host!) }); : { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) });
if (user == null) { if (user == null) {
throw new ApiError(meta.errors.noSuchUser); throw new ApiError(meta.errors.noSuchUser);

View File

@ -4,7 +4,7 @@ import define from '../../define';
import { ApiError } from '../../error'; import { ApiError } from '../../error';
import { Users, Followings } from '../../../../models'; import { Users, Followings } from '../../../../models';
import { makePaginationQuery } from '../../common/make-pagination-query'; import { makePaginationQuery } from '../../common/make-pagination-query';
import { toPuny } from '../../../../misc/convert-host'; import { toPunyNullable } from '../../../../misc/convert-host';
export const meta = { export const meta = {
desc: { desc: {
@ -66,7 +66,7 @@ export const meta = {
export default define(meta, async (ps, me) => { export default define(meta, async (ps, me) => {
const user = await Users.findOne(ps.userId != null const user = await Users.findOne(ps.userId != null
? { id: ps.userId } ? { id: ps.userId }
: { usernameLower: ps.username!.toLowerCase(), host: toPuny(ps.host!) }); : { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) });
if (user == null) { if (user == null) {
throw new ApiError(meta.errors.noSuchUser); throw new ApiError(meta.errors.noSuchUser);

View File

@ -10,7 +10,7 @@ import { genId } from '../../../misc/gen-id';
import { usersChart } from '../../../services/chart'; import { usersChart } from '../../../services/chart';
import { User } from '../../../models/entities/user'; import { User } from '../../../models/entities/user';
import { UserKeypair } from '../../../models/entities/user-keypair'; import { UserKeypair } from '../../../models/entities/user-keypair';
import { toPuny } from '../../../misc/convert-host'; import { toPunyNullable } from '../../../misc/convert-host';
import { UserProfile } from '../../../models/entities/user-profile'; import { UserProfile } from '../../../models/entities/user-profile';
import { getConnection } from 'typeorm'; import { getConnection } from 'typeorm';
@ -109,7 +109,7 @@ export default async (ctx: Koa.BaseContext) => {
createdAt: new Date(), createdAt: new Date(),
username: username, username: username,
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
host: host ? toPuny(host) : null, host: toPunyNullable(host),
token: secret, token: secret,
isAdmin: config.autoAdmin && usersCount === 0, isAdmin: config.autoAdmin && usersCount === 0,
})); }));

View File

@ -8,7 +8,7 @@ import { genId } from '../../../misc/gen-id';
import { createNotification } from '../../create-notification'; import { createNotification } from '../../create-notification';
export default async function(user: User, note: Note, choice: number) { export default async function(user: User, note: Note, choice: number) {
const poll = await Polls.findOne({ noteId: note.id }); const poll = await Polls.findOne(note.id);
if (poll == null) throw 'poll not found'; if (poll == null) throw 'poll not found';

View File

@ -16,7 +16,7 @@ import { NoteReaction } from '../../../models/entities/note-reaction';
import { createNotification } from '../../create-notification'; import { createNotification } from '../../create-notification';
import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error'; import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error';
export default async (user: User, note: Note, reaction: string) => { export default async (user: User, note: Note, reaction?: string) => {
// Myself // Myself
if (note.userId === user.id) { if (note.userId === user.id) {
throw new IdentifiableError('2d8e7297-1873-4c00-8404-792c68d7bef0', 'cannot react to my note'); throw new IdentifiableError('2d8e7297-1873-4c00-8404-792c68d7bef0', 'cannot react to my note');

View File

@ -63,7 +63,9 @@ export async function updateHashtag(user: User, tag: string, isUserAttached = fa
} }
} }
if (Object.keys(set).length > 0) {
q.execute(); q.execute();
}
} else { } else {
if (isUserAttached) { if (isUserAttached) {
Hashtags.save({ Hashtags.save({