Compare commits
17 Commits
11.0.0-bet
...
11.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
7e0d8dd4d7 | |||
146fb23d7d | |||
61455ffe29 | |||
c267baafdc | |||
42248a306a | |||
694ec7ebe1 | |||
e3b3f8fac1 | |||
b390363b25 | |||
f6f8cdbcf2 | |||
f46f53b8a3 | |||
a2fcae4383 | |||
483f043768 | |||
f8e0f4f21f | |||
9c3613e96d | |||
d9cacdc86d | |||
aa3d2deeaa | |||
e64912545a |
@ -127,28 +127,12 @@ drive:
|
||||
# change it according to your preferences.
|
||||
|
||||
# Available methods:
|
||||
# aid1 ... Use AID for ID generation (with random 1 char)
|
||||
# aid2 ... Use AID for ID generation (with random 2 chars)
|
||||
# aid3 ... Use AID for ID generation (with random 3 chars)
|
||||
# aid4 ... Use AID for ID generation (with random 4 chars)
|
||||
# ulid ... Use ulid for ID generation
|
||||
# objectid ... This is left for backward compatibility.
|
||||
# aid ... Short, Millisecond accuracy
|
||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
|
||||
# AID(n) is the original ID generation method.
|
||||
# The trailing n represents the number of random characters that
|
||||
# will be suffixed.
|
||||
# The larger n is the safer. If n is small, the possibility of
|
||||
# collision at the same time increases, but there are also
|
||||
# advantages such as shortening of the URL.
|
||||
|
||||
# ULID: Universally Unique Lexicographically Sortable Identifier.
|
||||
# for more details: https://github.com/ulid/spec
|
||||
# * Normally, AID should be sufficient.
|
||||
|
||||
# ObjectID is the method used in previous versions of Misskey.
|
||||
# * Choose this if you are migrating from a previous Misskey.
|
||||
|
||||
id: 'aid2'
|
||||
id: 'aid'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
@ -5,8 +5,8 @@ If you encounter any problems with updating, please try the following:
|
||||
1. `npm run clean` or `npm run cleanall`
|
||||
2. Retry update (Don't forget `npm i`)
|
||||
|
||||
11.0.0
|
||||
----------
|
||||
11.0.0 (daybreak)
|
||||
-----------------
|
||||
* **データベースがMongoDBからPostgreSQLに変更されました**
|
||||
* **Redisが必須に**
|
||||
* アカウントを完全に削除できるように
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "11.0.0-beta.11",
|
||||
"version": "11.0.0-beta.14",
|
||||
"codename": "daybreak",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -28,7 +28,7 @@ export default class MiOS extends EventEmitter {
|
||||
};
|
||||
|
||||
public get instanceName() {
|
||||
return this.meta ? this.meta.data.name : 'Misskey';
|
||||
return this.meta ? (this.meta.data.name || 'Misskey') : 'Misskey';
|
||||
}
|
||||
|
||||
private isMetaFetching = false;
|
||||
|
@ -1,26 +0,0 @@
|
||||
// AID
|
||||
// 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さnの[ランダムな文字列]
|
||||
|
||||
const CHARS = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||
const TIME2000 = 946684800000;
|
||||
|
||||
function getTime(time: number) {
|
||||
time = time - TIME2000;
|
||||
if (time < 0) time = 0;
|
||||
|
||||
return time.toString(36);
|
||||
}
|
||||
|
||||
function getRandom(length: number) {
|
||||
let str = '';
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
str += CHARS[Math.floor(Math.random() * CHARS.length)];
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function genAid(date: Date, rand: number): string {
|
||||
return getTime(date.getTime()).padStart(8, CHARS[0]) + getRandom(rand);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// AID(Cheep)
|
||||
// 長さ6の[2000年1月1日からの経過秒をbase36でエンコードしたもの] + 長さ3の[ランダムな文字列]
|
||||
|
||||
const CHARS = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||
const TIME2000 = 946684800000;
|
||||
|
||||
function getTime(time: number) {
|
||||
time = time - TIME2000;
|
||||
if (time < 0) time = 0;
|
||||
time = Math.floor(time / 1000);
|
||||
return time.toString(36);
|
||||
}
|
||||
|
||||
function getRandom() {
|
||||
let str = '';
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
str += CHARS[Math.floor(Math.random() * CHARS.length)];
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function genAidc(date: Date): string {
|
||||
return getTime(date.getTime()).padStart(6, CHARS[0]) + getRandom();
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { ulid } from 'ulid';
|
||||
import { genAid } from './aid';
|
||||
import { genAidc } from './aidc';
|
||||
import { genObjectId } from './object-id';
|
||||
import { genAid } from './id/aid';
|
||||
import { genMeid } from './id/meid';
|
||||
import { genObjectId } from './id/object-id';
|
||||
import config from '../config';
|
||||
|
||||
const metohd = config.id.toLowerCase();
|
||||
@ -10,13 +10,10 @@ export function genId(date?: Date): string {
|
||||
if (!date || (date > new Date())) date = new Date();
|
||||
|
||||
switch (metohd) {
|
||||
case 'aidc': return genAidc(date);
|
||||
case 'aid1': return genAid(date, 1);
|
||||
case 'aid2': return genAid(date, 2);
|
||||
case 'aid3': return genAid(date, 3);
|
||||
case 'aid4': return genAid(date, 4);
|
||||
case 'aid': return genAid(date);
|
||||
case 'meid': return genMeid(date);
|
||||
case 'ulid': return ulid(date.getTime());
|
||||
case 'objectid': return genObjectId(date);
|
||||
default: throw 'unknown id generation method';
|
||||
default: throw new Error('unknown id generation method');
|
||||
}
|
||||
}
|
||||
|
23
src/misc/id/aid.ts
Normal file
23
src/misc/id/aid.ts
Normal file
@ -0,0 +1,23 @@
|
||||
// AID
|
||||
// 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さ2の[ノイズ文字列]
|
||||
|
||||
import * as cluster from 'cluster';
|
||||
|
||||
const TIME2000 = 946684800000;
|
||||
let counter = process.pid + (cluster.isMaster ? 0 : cluster.worker.id);
|
||||
|
||||
function getTime(time: number) {
|
||||
time = time - TIME2000;
|
||||
if (time < 0) time = 0;
|
||||
|
||||
return time.toString(36).padStart(8, '0');
|
||||
}
|
||||
|
||||
function getNoise() {
|
||||
return counter.toString(36).padStart(2, '0').slice(-2);
|
||||
}
|
||||
|
||||
export function genAid(date: Date): string {
|
||||
counter++;
|
||||
return getTime(date.getTime()) + getNoise();
|
||||
}
|
26
src/misc/id/meid.ts
Normal file
26
src/misc/id/meid.ts
Normal file
@ -0,0 +1,26 @@
|
||||
const CHARS = '0123456789abcdef';
|
||||
|
||||
function getTime(time: number) {
|
||||
if (time < 0) time = 0;
|
||||
if (time === 0) {
|
||||
return CHARS[0];
|
||||
}
|
||||
|
||||
time += 0x800000000000;
|
||||
|
||||
return time.toString(16).padStart(12, CHARS[0]);
|
||||
}
|
||||
|
||||
function getRandom() {
|
||||
let str = '';
|
||||
|
||||
for (let i = 0; i < 12; i++) {
|
||||
str += CHARS[Math.floor(Math.random() * CHARS.length)];
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function genMeid(date: Date): string {
|
||||
return 'f' + getTime(date.getTime()) + getRandom();
|
||||
}
|
@ -8,7 +8,7 @@ function getTime(time: number) {
|
||||
|
||||
time = Math.floor(time / 1000);
|
||||
|
||||
return time.toString(16);
|
||||
return time.toString(16).padStart(8, CHARS[0]);
|
||||
}
|
||||
|
||||
function getRandom() {
|
@ -121,6 +121,7 @@ export class UserRepository extends Repository<User> {
|
||||
updatedAt: user.updatedAt,
|
||||
bannerUrl: user.bannerUrl,
|
||||
bannerColor: user.bannerColor,
|
||||
isLocked: user.isLocked,
|
||||
description: profile!.description,
|
||||
location: profile!.location,
|
||||
birthday: profile!.birthday,
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
export function ensure<T>(x: T): NonNullable<T> {
|
||||
if (x == null) {
|
||||
throw 'ぬるぽ';
|
||||
throw new Error('ぬるぽ');
|
||||
} else {
|
||||
return x!;
|
||||
}
|
||||
|
@ -23,6 +23,14 @@ function initializeQueue(name: string) {
|
||||
});
|
||||
}
|
||||
|
||||
function renderError(e: Error): any {
|
||||
return {
|
||||
stack: e.stack,
|
||||
message: e.message,
|
||||
name: e.name
|
||||
};
|
||||
}
|
||||
|
||||
export const deliverQueue = initializeQueue('deliver');
|
||||
export const inboxQueue = initializeQueue('inbox');
|
||||
export const dbQueue = initializeQueue('db');
|
||||
@ -34,16 +42,16 @@ deliverQueue
|
||||
.on('waiting', (jobId) => deliverLogger.debug(`waiting id=${jobId}`))
|
||||
.on('active', (job) => deliverLogger.debug(`active id=${job.id} to=${job.data.to}`))
|
||||
.on('completed', (job, result) => deliverLogger.debug(`completed(${result}) id=${job.id} to=${job.data.to}`))
|
||||
.on('failed', (job, err) => deliverLogger.warn(`failed(${err}) id=${job.id} to=${job.data.to}`))
|
||||
.on('error', (error) => deliverLogger.error(`error ${error}`))
|
||||
.on('failed', (job, err) => deliverLogger.warn(`failed(${err}) id=${job.id} to=${job.data.to}`, { job, e: renderError(err) }))
|
||||
.on('error', (job: any, err: Error) => deliverLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||
.on('stalled', (job) => deliverLogger.warn(`stalled id=${job.id} to=${job.data.to}`));
|
||||
|
||||
inboxQueue
|
||||
.on('waiting', (jobId) => inboxLogger.debug(`waiting id=${jobId}`))
|
||||
.on('active', (job) => inboxLogger.debug(`active id=${job.id}`))
|
||||
.on('completed', (job, result) => inboxLogger.debug(`completed(${result}) id=${job.id}`))
|
||||
.on('failed', (job, err) => inboxLogger.warn(`failed(${err}) id=${job.id} activity=${job.data.activity ? job.data.activity.id : 'none'}`))
|
||||
.on('error', (error) => inboxLogger.error(`error ${error}`))
|
||||
.on('failed', (job, err) => inboxLogger.warn(`failed(${err}) id=${job.id} activity=${job.data.activity ? job.data.activity.id : 'none'}`, { job, e: renderError(err) }))
|
||||
.on('error', (job: any, err: Error) => inboxLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||
.on('stalled', (job) => inboxLogger.warn(`stalled id=${job.id} activity=${job.data.activity ? job.data.activity.id : 'none'}`));
|
||||
|
||||
export function deliver(user: ILocalUser, content: any, to: any) {
|
||||
|
@ -6,7 +6,7 @@ import { Users } from '../../../../models';
|
||||
|
||||
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
|
||||
const id = typeof activity.actor == 'string' ? activity.actor : activity.actor.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
if (!id.startsWith(config.url + '/')) {
|
||||
return;
|
||||
|
@ -9,7 +9,7 @@ const logger = apLogger;
|
||||
|
||||
export default async (actor: IRemoteUser, activity: IBlock): Promise<void> => {
|
||||
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
const uri = activity.id || activity;
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { Users } from '../../../models';
|
||||
|
||||
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
|
||||
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
if (!id.startsWith(config.url + '/')) {
|
||||
return;
|
||||
|
@ -5,7 +5,7 @@ import { Notes } from '../../../models';
|
||||
|
||||
export default async (actor: IRemoteUser, activity: ILike) => {
|
||||
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
// Transform:
|
||||
// https://misskey.ex/notes/xxxx to
|
||||
|
@ -6,7 +6,7 @@ import { Users } from '../../../../models';
|
||||
|
||||
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
|
||||
const id = typeof activity.actor == 'string' ? activity.actor : activity.actor.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
if (!id.startsWith(config.url + '/')) {
|
||||
return;
|
||||
|
@ -9,7 +9,7 @@ const logger = apLogger;
|
||||
|
||||
export default async (actor: IRemoteUser, activity: IBlock): Promise<void> => {
|
||||
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
const uri = activity.id || activity;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { Users, FollowRequests, Followings } from '../../../../models';
|
||||
|
||||
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
|
||||
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
if (!id.startsWith(config.url + '/')) {
|
||||
return;
|
||||
|
@ -8,13 +8,13 @@ import { Notes } from '../../../../models';
|
||||
*/
|
||||
export default async (actor: IRemoteUser, activity: ILike): Promise<void> => {
|
||||
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
|
||||
if (id == null) throw 'missing id';
|
||||
if (id == null) throw new Error('missing id');
|
||||
|
||||
const noteId = id.split('/').pop();
|
||||
|
||||
const note = await Notes.findOne(noteId);
|
||||
if (note == null) {
|
||||
throw 'note not found';
|
||||
throw new Error('note not found');
|
||||
}
|
||||
|
||||
await deleteReaction(actor, note);
|
||||
|
@ -32,7 +32,7 @@ const logger = apLogger;
|
||||
*/
|
||||
export async function fetchNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> {
|
||||
const uri = typeof value == 'string' ? value : value.id;
|
||||
if (uri == null) throw 'missing uri';
|
||||
if (uri == null) throw new Error('missing uri');
|
||||
|
||||
// URIがこのサーバーを指しているならデータベースからフェッチ
|
||||
if (uri.startsWith(config.url + '/')) {
|
||||
@ -67,7 +67,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||
value: value,
|
||||
object: object
|
||||
});
|
||||
throw 'invalid note';
|
||||
throw new Error('invalid note');
|
||||
}
|
||||
|
||||
const note: INote = object;
|
||||
@ -81,7 +81,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||
|
||||
// 投稿者が凍結されていたらスキップ
|
||||
if (actor.isSuspended) {
|
||||
throw 'actor has been suspended';
|
||||
throw new Error('actor has been suspended');
|
||||
}
|
||||
|
||||
//#region Visibility
|
||||
@ -124,7 +124,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||
? await resolveNote(note.inReplyTo, resolver).then(x => {
|
||||
if (x == null) {
|
||||
logger.warn(`Specified inReplyTo, but nout found`);
|
||||
throw 'inReplyTo not found';
|
||||
throw new Error('inReplyTo not found');
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
@ -230,7 +230,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||
*/
|
||||
export async function resolveNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> {
|
||||
const uri = typeof value == 'string' ? value : value.id;
|
||||
if (uri == null) throw 'missing uri';
|
||||
if (uri == null) throw new Error('missing uri');
|
||||
|
||||
// ブロックしてたら中断
|
||||
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
|
||||
@ -252,7 +252,7 @@ export async function resolveNote(value: string | IObject, resolver?: Resolver):
|
||||
if (e.name === 'duplicated') {
|
||||
return fetchNote(uri).then(note => {
|
||||
if (note == null) {
|
||||
throw 'something happened';
|
||||
throw new Error('something happened');
|
||||
} else {
|
||||
return note;
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ function validatePerson(x: any, uri: string) {
|
||||
* Misskeyに対象のPersonが登録されていればそれを返します。
|
||||
*/
|
||||
export async function fetchPerson(uri: string, resolver?: Resolver): Promise<User | null> {
|
||||
if (typeof uri !== 'string') throw 'uri is not string';
|
||||
if (typeof uri !== 'string') throw new Error('uri is not string');
|
||||
|
||||
// URIがこのサーバーを指しているならデータベースからフェッチ
|
||||
if (uri.startsWith(config.url + '/')) {
|
||||
@ -111,7 +111,7 @@ export async function fetchPerson(uri: string, resolver?: Resolver): Promise<Use
|
||||
* Personを作成します。
|
||||
*/
|
||||
export async function createPerson(uri: string, resolver?: Resolver): Promise<User> {
|
||||
if (typeof uri !== 'string') throw 'uri is not string';
|
||||
if (typeof uri !== 'string') throw new Error('uri is not string');
|
||||
|
||||
if (resolver == null) resolver = new Resolver();
|
||||
|
||||
@ -256,7 +256,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
|
||||
* @param hint Hint of Person object (この値が正当なPersonの場合、Remote resolveをせずに更新に利用します)
|
||||
*/
|
||||
export async function updatePerson(uri: string, resolver?: Resolver | null, hint?: object): Promise<void> {
|
||||
if (typeof uri !== 'string') throw 'uri is not string';
|
||||
if (typeof uri !== 'string') throw new Error('uri is not string');
|
||||
|
||||
// URIがこのサーバーを指しているならスキップ
|
||||
if (uri.startsWith(config.url + '/')) {
|
||||
@ -380,7 +380,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
|
||||
* リモートサーバーからフェッチしてMisskeyに登録しそれを返します。
|
||||
*/
|
||||
export async function resolvePerson(uri: string, resolver?: Resolver): Promise<User> {
|
||||
if (typeof uri !== 'string') throw 'uri is not string';
|
||||
if (typeof uri !== 'string') throw new Error('uri is not string');
|
||||
|
||||
//#region このサーバーに既に登録されていたらそれを返す
|
||||
const exist = await fetchPerson(uri);
|
||||
|
@ -11,7 +11,7 @@ export async function extractPollFromQuestion(source: string | IQuestion): Promi
|
||||
const expiresAt = question.endTime ? new Date(question.endTime) : null;
|
||||
|
||||
if (multiple && !question.anyOf) {
|
||||
throw 'invalid question';
|
||||
throw new Error('invalid question');
|
||||
}
|
||||
|
||||
const choices = question[multiple ? 'anyOf' : 'oneOf']!
|
||||
@ -37,14 +37,14 @@ export async function updateQuestion(value: any) {
|
||||
const uri = typeof value == 'string' ? value : value.id;
|
||||
|
||||
// URIがこのサーバーを指しているならスキップ
|
||||
if (uri.startsWith(config.url + '/')) throw 'uri points local';
|
||||
if (uri.startsWith(config.url + '/')) throw new Error('uri points local');
|
||||
|
||||
//#region このサーバーに既に登録されているか
|
||||
const note = await Notes.findOne({ uri });
|
||||
if (note == null) throw 'Question is not registed';
|
||||
if (note == null) throw new Error('Question is not registed');
|
||||
|
||||
const poll = await Polls.findOne({ noteId: note.id });
|
||||
if (poll == null) throw 'Question is not registed';
|
||||
if (poll == null) throw new Error('Question is not registed');
|
||||
//#endregion
|
||||
|
||||
// resolve new Question object
|
||||
@ -52,7 +52,7 @@ export async function updateQuestion(value: any) {
|
||||
const question = await resolver.resolve(value) as IQuestion;
|
||||
apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`);
|
||||
|
||||
if (question.type !== 'Question') throw 'object is not a Question';
|
||||
if (question.type !== 'Question') throw new Error('object is not a Question');
|
||||
|
||||
const apChoices = question.oneOf || question.anyOf;
|
||||
|
||||
|
@ -17,7 +17,7 @@ export async function resolveUser(username: string, host: string | null, option?
|
||||
logger.info(`return local user: ${usernameLower}`);
|
||||
return await Users.findOne({ usernameLower, host: null }).then(u => {
|
||||
if (u == null) {
|
||||
throw 'user not found';
|
||||
throw new Error('user not found');
|
||||
} else {
|
||||
return u;
|
||||
}
|
||||
@ -30,7 +30,7 @@ export async function resolveUser(username: string, host: string | null, option?
|
||||
logger.info(`return local user: ${usernameLower}`);
|
||||
return await Users.findOne({ usernameLower, host: null }).then(u => {
|
||||
if (u == null) {
|
||||
throw 'user not found';
|
||||
throw new Error('user not found');
|
||||
} else {
|
||||
return u;
|
||||
}
|
||||
@ -78,7 +78,7 @@ export async function resolveUser(username: string, host: string | null, option?
|
||||
logger.info(`return resynced remote user: ${acctLower}`);
|
||||
return await Users.findOne({ uri: self.href }).then(u => {
|
||||
if (u == null) {
|
||||
throw 'user not found';
|
||||
throw new Error('user not found');
|
||||
} else {
|
||||
return u;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export default async (token: string): Promise<[User | null | undefined, App | nu
|
||||
.findOne({ token });
|
||||
|
||||
if (user == null) {
|
||||
throw 'user not found';
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
return [user, null];
|
||||
@ -24,7 +24,7 @@ export default async (token: string): Promise<[User | null | undefined, App | nu
|
||||
});
|
||||
|
||||
if (accessToken == null) {
|
||||
throw 'invalid signature';
|
||||
throw new Error('invalid signature');
|
||||
}
|
||||
|
||||
const app = await Apps
|
||||
|
@ -36,7 +36,7 @@ export async function getRemoteUser(userId: User['id']) {
|
||||
const user = await getUser(userId);
|
||||
|
||||
if (!Users.isRemoteUser(user)) {
|
||||
throw 'user is not a remote user';
|
||||
throw new Error('user is not a remote user');
|
||||
}
|
||||
|
||||
return user;
|
||||
@ -49,7 +49,7 @@ export async function getLocalUser(userId: User['id']) {
|
||||
const user = await getUser(userId);
|
||||
|
||||
if (!Users.isLocalUser(user)) {
|
||||
throw 'user is not a local user';
|
||||
throw new Error('user is not a local user');
|
||||
}
|
||||
|
||||
return user;
|
||||
|
@ -35,6 +35,7 @@ export default define(meta, async (ps, user) => {
|
||||
const day = 1000 * 60 * 60 * 24 * 3; // 3日前まで
|
||||
|
||||
const query = Notes.createQueryBuilder('note')
|
||||
.where('note.userHost IS NULL')
|
||||
.andWhere(`note.createdAt > :date`, { date: new Date(Date.now() - day) })
|
||||
.andWhere(`note.visibility = 'public'`)
|
||||
.leftJoinAndSelect('note.user', 'user');
|
||||
|
@ -43,7 +43,7 @@ export default class extends Channel {
|
||||
if (this.user == null) return;
|
||||
|
||||
const game = await ReversiGames.findOne(this.gameId!);
|
||||
if (game == null) throw 'game not found';
|
||||
if (game == null) throw new Error('game not found');
|
||||
|
||||
if (game.isStarted) return;
|
||||
if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return;
|
||||
@ -67,7 +67,7 @@ export default class extends Channel {
|
||||
if (this.user == null) return;
|
||||
|
||||
const game = await ReversiGames.findOne(this.gameId!);
|
||||
if (game == null) throw 'game not found';
|
||||
if (game == null) throw new Error('game not found');
|
||||
|
||||
if (game.isStarted) return;
|
||||
if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return;
|
||||
@ -91,7 +91,7 @@ export default class extends Channel {
|
||||
if (this.user == null) return;
|
||||
|
||||
const game = await ReversiGames.findOne(this.gameId!);
|
||||
if (game == null) throw 'game not found';
|
||||
if (game == null) throw new Error('game not found');
|
||||
|
||||
if (game.isStarted) return;
|
||||
if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return;
|
||||
@ -135,7 +135,7 @@ export default class extends Channel {
|
||||
if (this.user == null) return;
|
||||
|
||||
const game = await ReversiGames.findOne(this.gameId!);
|
||||
if (game == null) throw 'game not found';
|
||||
if (game == null) throw new Error('game not found');
|
||||
|
||||
if (game.isStarted) return;
|
||||
|
||||
@ -237,7 +237,7 @@ export default class extends Channel {
|
||||
if (this.user == null) return;
|
||||
|
||||
const game = await ReversiGames.findOne(this.gameId!);
|
||||
if (game == null) throw 'game not found';
|
||||
if (game == null) throw new Error('game not found');
|
||||
|
||||
if (!game.isStarted) return;
|
||||
if (game.isEnded) return;
|
||||
@ -304,7 +304,7 @@ export default class extends Channel {
|
||||
@autobind
|
||||
private async check(crc32: string) {
|
||||
const game = await ReversiGames.findOne(this.gameId!);
|
||||
if (game == null) throw 'game not found';
|
||||
if (game == null) throw new Error('game not found');
|
||||
|
||||
if (!game.isStarted) return;
|
||||
|
||||
|
@ -201,13 +201,20 @@ async function upload(key: string, stream: fs.ReadStream | Buffer, type: string,
|
||||
}
|
||||
|
||||
async function deleteOldFile(user: IRemoteUser) {
|
||||
const oldFile = await DriveFiles.createQueryBuilder()
|
||||
.select('file')
|
||||
.where('file.id != :avatarId', { avatarId: user.avatarId })
|
||||
.andWhere('file.id != :bannerId', { bannerId: user.bannerId })
|
||||
.andWhere('file.userId = :userId', { userId: user.id })
|
||||
.orderBy('file.id', 'DESC')
|
||||
.getOne();
|
||||
const q = DriveFiles.createQueryBuilder('file')
|
||||
.where('file.userId = :userId', { userId: user.id });
|
||||
|
||||
if (user.avatarId) {
|
||||
q.andWhere('file.id != :avatarId', { avatarId: user.avatarId });
|
||||
}
|
||||
|
||||
if (user.bannerId) {
|
||||
q.andWhere('file.id != :bannerId', { bannerId: user.bannerId })
|
||||
}
|
||||
|
||||
q.orderBy('file.id', 'DESC');
|
||||
|
||||
const oldFile = await q.getOne();
|
||||
|
||||
if (oldFile) {
|
||||
delFile(oldFile, true);
|
||||
@ -297,7 +304,7 @@ export default async function(
|
||||
// If usage limit exceeded
|
||||
if (usage + size > driveCapacity) {
|
||||
if (Users.isLocalUser(user)) {
|
||||
throw 'no-free-space';
|
||||
throw new Error('no-free-space');
|
||||
} else {
|
||||
// (アバターまたはバナーを含まず)最も古いファイルを削除する
|
||||
deleteOldFile(user as IRemoteUser);
|
||||
@ -316,7 +323,7 @@ export default async function(
|
||||
userId: user.id
|
||||
});
|
||||
|
||||
if (driveFolder == null) throw 'folder-not-found';
|
||||
if (driveFolder == null) throw new Error('folder-not-found');
|
||||
|
||||
return driveFolder;
|
||||
};
|
||||
|
@ -78,7 +78,7 @@ export async function removePinned(user: User, noteId: Note['id']) {
|
||||
|
||||
export async function deliverPinnedChange(userId: User['id'], noteId: Note['id'], isAddition: boolean) {
|
||||
const user = await Users.findOne(userId);
|
||||
if (user == null) throw 'user not found';
|
||||
if (user == null) throw new Error('user not found');
|
||||
|
||||
if (!Users.isLocalUser(user)) return;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { renderPerson } from '../../remote/activitypub/renderer/person';
|
||||
|
||||
export async function publishToFollowers(userId: User['id']) {
|
||||
const user = await Users.findOne(userId);
|
||||
if (user == null) throw 'user not found';
|
||||
if (user == null) throw new Error('user not found');
|
||||
|
||||
const followers = await Followings.find({
|
||||
followeeId: user.id
|
||||
|
@ -175,7 +175,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
|
||||
}
|
||||
|
||||
if (data.visibility == 'specified') {
|
||||
if (data.visibleUsers == null) throw 'invalid param';
|
||||
if (data.visibleUsers == null) throw new Error('invalid param');
|
||||
|
||||
for (const u of data.visibleUsers) {
|
||||
if (!mentionedUsers.some(x => x.id === u.id)) {
|
||||
@ -214,7 +214,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
|
||||
|
||||
// 未読通知を作成
|
||||
if (data.visibility == 'specified') {
|
||||
if (data.visibleUsers == null) throw 'invalid param';
|
||||
if (data.visibleUsers == null) throw new Error('invalid param');
|
||||
|
||||
for (const u of data.visibleUsers) {
|
||||
insertNoteUnread(u, note, true);
|
||||
@ -428,7 +428,7 @@ async function insertNote(user: User, data: Option, tags: string[], emojis: stri
|
||||
|
||||
console.error(e);
|
||||
|
||||
throw 'something happened';
|
||||
throw new Error('something happened');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,10 @@ import { Note } from '../../../models/entities/note';
|
||||
|
||||
export async function deliverQuestionUpdate(noteId: Note['id']) {
|
||||
const note = await Notes.findOne(noteId);
|
||||
if (note == null) throw 'note not found';
|
||||
if (note == null) throw new Error('note not found');
|
||||
|
||||
const user = await Users.findOne(note.userId);
|
||||
if (user == null) throw 'note not found';
|
||||
if (user == null) throw new Error('note not found');
|
||||
|
||||
const followers = await Followings.find({
|
||||
followeeId: user.id
|
||||
|
@ -10,7 +10,7 @@ import { createNotification } from '../../create-notification';
|
||||
export default async function(user: User, note: Note, choice: number) {
|
||||
const poll = await Polls.findOne(note.id);
|
||||
|
||||
if (poll == null) throw 'poll not found';
|
||||
if (poll == null) throw new Error('poll not found');
|
||||
|
||||
// Check whether is valid choice
|
||||
if (poll.choices[choice] == null) throw new Error('invalid choice param');
|
||||
|
@ -18,8 +18,8 @@ const args = process.argv.slice(2);
|
||||
const name = args[0];
|
||||
const url = args[1];
|
||||
|
||||
if (!name) throw 'require name';
|
||||
if (!url) throw 'require url';
|
||||
if (!name) throw new Error('require name');
|
||||
if (!url) throw new Error('require url');
|
||||
|
||||
main(name, url).then(() => {
|
||||
console.log('success');
|
||||
|
@ -15,7 +15,7 @@ async function main(username: string, headers?: string[]) {
|
||||
usernameLower: username.toLowerCase(),
|
||||
});
|
||||
|
||||
if (user == null) throw 'User not found';
|
||||
if (user == null) throw new Error('User not found');
|
||||
|
||||
const history = await Signins.find({
|
||||
userId: user.id
|
||||
|
Reference in New Issue
Block a user