Improve error handling of API (#4345)
* wip
* wip
* wip
* Update attached_notes.ts
* wip
* Refactor
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Update call.ts
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* ✌️
* Fix
This commit is contained in:
parent
fc52e95ad0
commit
2756f553c6
13
src/misc/identifiable-error.ts
Normal file
13
src/misc/identifiable-error.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* ID付きエラー
|
||||
*/
|
||||
export class IdentifiableError extends Error {
|
||||
public message: string;
|
||||
public id: string;
|
||||
|
||||
constructor(id: string, message?: string) {
|
||||
super(message);
|
||||
this.message = message;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
@ -48,7 +48,6 @@ export default async (ctx: Router.IRouterContext) => {
|
||||
const partOf = `${config.url}/users/${userId}/followers`;
|
||||
|
||||
if (page) {
|
||||
// Construct query
|
||||
const query = {
|
||||
followeeId: user._id
|
||||
} as any;
|
||||
|
@ -48,7 +48,6 @@ export default async (ctx: Router.IRouterContext) => {
|
||||
const partOf = `${config.url}/users/${userId}/following`;
|
||||
|
||||
if (page) {
|
||||
// Construct query
|
||||
const query = {
|
||||
followerId: user._id
|
||||
} as any;
|
||||
|
@ -78,7 +78,6 @@ export default async (ctx: Router.IRouterContext) => {
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// Issue query
|
||||
const notes = await Note
|
||||
.find(query, {
|
||||
limit: limit,
|
||||
|
@ -5,18 +5,17 @@ import authenticate from './authenticate';
|
||||
import call from './call';
|
||||
import { IUser } from '../../models/user';
|
||||
import { IApp } from '../../models/app';
|
||||
import { ApiError } from './error';
|
||||
|
||||
export default async (endpoint: IEndpoint, ctx: Koa.BaseContext) => {
|
||||
const body = ctx.is('multipart/form-data') ? (ctx.req as any).body : ctx.request.body;
|
||||
|
||||
const reply = (x?: any, y?: any) => {
|
||||
if (x === undefined) {
|
||||
const reply = (x?: any, y?: ApiError) => {
|
||||
if (x == null) {
|
||||
ctx.status = 204;
|
||||
} else if (typeof x === 'number') {
|
||||
ctx.status = x;
|
||||
ctx.body = {
|
||||
error: x === 500 ? 'INTERNAL_ERROR' : y
|
||||
};
|
||||
ctx.body = y;
|
||||
} else {
|
||||
ctx.body = x;
|
||||
}
|
||||
@ -29,7 +28,11 @@ export default async (endpoint: IEndpoint, ctx: Koa.BaseContext) => {
|
||||
try {
|
||||
[user, app] = await authenticate(body['i']);
|
||||
} catch (e) {
|
||||
reply(403, 'AUTHENTICATION_FAILED');
|
||||
reply(403, new ApiError({
|
||||
message: 'Authentication failed. Please ensure your token is correct.',
|
||||
code: 'AUTHENTICATION_FAILED',
|
||||
id: 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14'
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -39,7 +42,11 @@ export default async (endpoint: IEndpoint, ctx: Koa.BaseContext) => {
|
||||
try {
|
||||
res = await call(endpoint.name, user, app, body, (ctx.req as any).file);
|
||||
} catch (e) {
|
||||
reply(400, e);
|
||||
if (e.kind == 'client') {
|
||||
reply(400, e);
|
||||
} else {
|
||||
reply(500, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,15 @@ import limiter from './limiter';
|
||||
import { IUser } from '../../models/user';
|
||||
import { IApp } from '../../models/app';
|
||||
import endpoints from './endpoints';
|
||||
import { ApiError } from './error';
|
||||
import { apiLogger } from './logger';
|
||||
import { Response } from './define';
|
||||
|
||||
const accessDenied = {
|
||||
message: 'Access denied.',
|
||||
code: 'ACCESS_DENIED',
|
||||
id: '56f35758-7dd5-468b-8439-5d6fb8ec9b8e'
|
||||
};
|
||||
|
||||
export default async (endpoint: string, user: IUser, app: IApp, data: any, file?: any) => {
|
||||
const isSecure = user != null && app == null;
|
||||
@ -9,31 +18,43 @@ export default async (endpoint: string, user: IUser, app: IApp, data: any, file?
|
||||
const ep = endpoints.find(e => e.name === endpoint);
|
||||
|
||||
if (ep == null) {
|
||||
throw 'ENDPOINT_NOT_FOUND';
|
||||
throw new ApiError({
|
||||
message: 'No such endpoint.',
|
||||
code: 'NO_SUCH_ENDPOINT',
|
||||
id: 'f8080b67-5f9c-4eb7-8c18-7f1eeae8f709',
|
||||
});
|
||||
}
|
||||
|
||||
if (ep.meta.secure && !isSecure) {
|
||||
throw 'ACCESS_DENIED';
|
||||
throw new ApiError(accessDenied);
|
||||
}
|
||||
|
||||
if (ep.meta.requireCredential && user == null) {
|
||||
throw 'CREDENTIAL_REQUIRED';
|
||||
throw new ApiError({
|
||||
message: 'Credential required.',
|
||||
code: 'CREDENTIAL_REQUIRED',
|
||||
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
|
||||
});
|
||||
}
|
||||
|
||||
if (ep.meta.requireCredential && user.isSuspended) {
|
||||
throw 'YOUR_ACCOUNT_HAS_BEEN_SUSPENDED';
|
||||
throw new ApiError(accessDenied, { reason: 'Your account has been suspended.' });
|
||||
}
|
||||
|
||||
if (ep.meta.requireAdmin && !user.isAdmin) {
|
||||
throw 'YOU_ARE_NOT_ADMIN';
|
||||
throw new ApiError(accessDenied, { reason: 'You are not the admin.' });
|
||||
}
|
||||
|
||||
if (ep.meta.requireModerator && !user.isAdmin && !user.isModerator) {
|
||||
throw 'YOU_ARE_NOT_MODERATOR';
|
||||
throw new ApiError(accessDenied, { reason: 'You are not a moderator.' });
|
||||
}
|
||||
|
||||
if (app && ep.meta.kind && !app.permission.some(p => p === ep.meta.kind)) {
|
||||
throw 'PERMISSION_DENIED';
|
||||
throw new ApiError({
|
||||
message: 'Your app does not have the necessary permissions to use this endpoint.',
|
||||
code: 'PERMISSION_DENIED',
|
||||
id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838',
|
||||
});
|
||||
}
|
||||
|
||||
if (ep.meta.requireCredential && ep.meta.limit) {
|
||||
@ -41,24 +62,31 @@ export default async (endpoint: string, user: IUser, app: IApp, data: any, file?
|
||||
await limiter(ep, user); // Rate limit
|
||||
} catch (e) {
|
||||
// drop request if limit exceeded
|
||||
throw 'RATE_LIMIT_EXCEEDED';
|
||||
throw new ApiError({
|
||||
message: 'Rate limit exceeded. Please try again later.',
|
||||
code: 'RATE_LIMIT_EXCEEDED',
|
||||
id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let res;
|
||||
let res: Response;
|
||||
|
||||
// API invoking
|
||||
try {
|
||||
res = await ep.exec(data, user, app, file);
|
||||
} catch (e) {
|
||||
if (e && e.name == 'INVALID_PARAM') {
|
||||
throw {
|
||||
code: e.name,
|
||||
param: e.param,
|
||||
reason: e.message
|
||||
};
|
||||
} else {
|
||||
if (e instanceof ApiError) {
|
||||
throw e;
|
||||
} else {
|
||||
apiLogger.error(e);
|
||||
throw new ApiError(null, {
|
||||
e: {
|
||||
message: e.message,
|
||||
code: e.code,
|
||||
stack: e.stack
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as mongo from 'mongodb';
|
||||
import Note from "../../../models/note";
|
||||
import User, { isRemoteUser, isLocalUser } from "../../../models/user";
|
||||
import Note from '../../../models/note';
|
||||
import User, { isRemoteUser, isLocalUser } from '../../../models/user';
|
||||
import { IdentifiableError } from '../../../misc/identifiable-error';
|
||||
|
||||
/**
|
||||
* Get valied note for API processing
|
||||
@ -12,7 +13,7 @@ export async function getValiedNote(noteId: mongo.ObjectID) {
|
||||
});
|
||||
|
||||
if (note === null) {
|
||||
throw 'note not found';
|
||||
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', 'No such note.');
|
||||
}
|
||||
|
||||
return note;
|
||||
@ -27,7 +28,7 @@ export async function getUser(userId: mongo.ObjectID) {
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
throw 'user not found';
|
||||
throw new IdentifiableError('15348ddd-432d-49c2-8a5a-8069753becff', 'No such user.');
|
||||
}
|
||||
|
||||
return user;
|
||||
|
@ -2,6 +2,7 @@ import * as fs from 'fs';
|
||||
import { ILocalUser } from '../../models/user';
|
||||
import { IApp } from '../../models/app';
|
||||
import { IEndpointMeta } from './endpoints';
|
||||
import { ApiError } from './error';
|
||||
|
||||
type Params<T extends IEndpointMeta> = {
|
||||
[P in keyof T['params']]: T['params'][P]['transform'] extends Function
|
||||
@ -9,13 +10,19 @@ type Params<T extends IEndpointMeta> = {
|
||||
: ReturnType<T['params'][P]['validator']['get']>[0];
|
||||
};
|
||||
|
||||
export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T>, user: ILocalUser, app: IApp, file?: any, cleanup?: Function) => Promise<any>): (params: any, user: ILocalUser, app: IApp, file?: any) => Promise<any> {
|
||||
export type Response = Record<string, any> | void;
|
||||
|
||||
export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T>, user: ILocalUser, app: IApp, file?: any, cleanup?: Function) => Promise<Response>): (params: any, user: ILocalUser, app: IApp, file?: any) => Promise<any> {
|
||||
return (params: any, user: ILocalUser, app: IApp, file?: any) => {
|
||||
function cleanup() {
|
||||
fs.unlink(file.path, () => {});
|
||||
}
|
||||
|
||||
if (meta.requireFile && file == null) return Promise.reject('file required');
|
||||
if (meta.requireFile && file == null) return Promise.reject(new ApiError({
|
||||
message: 'File required.',
|
||||
code: 'FILE_REQUIRED',
|
||||
id: '4267801e-70d1-416a-b011-4ee502885d8b',
|
||||
}));
|
||||
|
||||
const [ps, pserr] = getParams(meta, params);
|
||||
if (pserr) {
|
||||
@ -27,17 +34,22 @@ export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T
|
||||
};
|
||||
}
|
||||
|
||||
function getParams<T extends IEndpointMeta>(defs: T, params: any): [Params<T>, Error] {
|
||||
function getParams<T extends IEndpointMeta>(defs: T, params: any): [Params<T>, ApiError] {
|
||||
if (defs.params == null) return [params, null];
|
||||
|
||||
const x: any = {};
|
||||
let err: Error = null;
|
||||
let err: ApiError = null;
|
||||
Object.entries(defs.params).some(([k, def]) => {
|
||||
const [v, e] = def.validator.get(params[k]);
|
||||
if (e) {
|
||||
err = new Error(e.message);
|
||||
err.name = 'INVALID_PARAM';
|
||||
(err as any).param = k;
|
||||
err = new ApiError({
|
||||
message: 'Invalid param.',
|
||||
code: 'INVALID_PARAM',
|
||||
id: '3d81ceae-475f-4600-b2a8-2bc116157532',
|
||||
}, {
|
||||
param: k,
|
||||
reason: e.message
|
||||
});
|
||||
return true;
|
||||
} else {
|
||||
if (v === undefined && def.hasOwnProperty('default')) {
|
||||
|
@ -25,11 +25,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
if (ps.sinceId && ps.untilId) {
|
||||
return rej('cannot set sinceId and untilId');
|
||||
}
|
||||
|
||||
export default define(meta, async (ps) => {
|
||||
const sort = {
|
||||
_id: -1
|
||||
};
|
||||
@ -51,5 +47,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
sort: sort
|
||||
});
|
||||
|
||||
res(await packMany(reports));
|
||||
}));
|
||||
return await packMany(reports);
|
||||
});
|
||||
|
@ -46,7 +46,7 @@ const sort: any = { // < https://github.com/Microsoft/TypeScript/issues/1863
|
||||
[fallback]: { _id: -1 }
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const q = {
|
||||
'metadata.deletedAt': { $exists: false },
|
||||
} as any;
|
||||
@ -61,5 +61,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
skip: ps.offset
|
||||
});
|
||||
|
||||
res(await packMany(files, { detail: true, withUser: true, self: true }));
|
||||
}));
|
||||
return await packMany(files, { detail: true, withUser: true, self: true });
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
||||
import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import define from '../../../define';
|
||||
import DriveFile from '../../../../../models/drive-file';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
@ -12,17 +13,25 @@ export const meta = {
|
||||
validator: $.type(ID),
|
||||
transform: transform,
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const file = await DriveFile.findOne({
|
||||
_id: ps.fileId
|
||||
});
|
||||
|
||||
if (file == null) {
|
||||
return rej('file not found');
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
|
||||
res(file);
|
||||
}));
|
||||
return file;
|
||||
});
|
||||
|
@ -26,7 +26,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const emoji = await Emoji.insert({
|
||||
updatedAt: new Date(),
|
||||
name: ps.name,
|
||||
@ -35,7 +35,7 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
url: ps.url
|
||||
});
|
||||
|
||||
res({
|
||||
return {
|
||||
id: emoji._id
|
||||
});
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
@ -18,16 +18,16 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const emojis = await Emoji.find({
|
||||
host: ps.host
|
||||
});
|
||||
|
||||
res(emojis.map(e => ({
|
||||
return emojis.map(e => ({
|
||||
id: e._id,
|
||||
name: e.name,
|
||||
aliases: e.aliases,
|
||||
host: e.host,
|
||||
url: e.url
|
||||
})));
|
||||
}));
|
||||
}));
|
||||
});
|
||||
|
@ -18,14 +18,14 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const emoji = await Emoji.findOne({
|
||||
_id: ps.id
|
||||
});
|
||||
|
||||
if (emoji == null) return rej('emoji not found');
|
||||
if (emoji == null) throw new Error('emoji not found');
|
||||
|
||||
await Emoji.remove({ _id: emoji._id });
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -30,12 +30,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const emoji = await Emoji.findOne({
|
||||
_id: ps.id
|
||||
});
|
||||
|
||||
if (emoji == null) return rej('emoji not found');
|
||||
if (emoji == null) throw new Error('emoji not found');
|
||||
|
||||
await Emoji.update({ _id: emoji._id }, {
|
||||
$set: {
|
||||
@ -46,5 +46,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const followings = await Following.find({
|
||||
'_follower.host': ps.host
|
||||
});
|
||||
@ -29,5 +29,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
deleteFollowing(pair[0], pair[1]);
|
||||
}
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -21,11 +21,11 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const instance = await Instance.findOne({ host: ps.host });
|
||||
|
||||
if (instance == null) {
|
||||
return rej('instance not found');
|
||||
throw new Error('instance not found');
|
||||
}
|
||||
|
||||
Instance.update({ host: ps.host }, {
|
||||
@ -35,5 +35,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -13,7 +13,7 @@ export const meta = {
|
||||
params: {}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const code = rndstr({ length: 5, chars: '0-9' });
|
||||
|
||||
await RegistrationTicket.insert({
|
||||
@ -21,7 +21,7 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
code: code
|
||||
});
|
||||
|
||||
res({
|
||||
return {
|
||||
code: code
|
||||
});
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
@ -24,13 +24,13 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await User.update({
|
||||
@ -41,5 +41,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -24,13 +24,13 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await User.update({
|
||||
@ -41,5 +41,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -8,8 +8,8 @@ export const meta = {
|
||||
params: {}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
destroy();
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -15,18 +15,18 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const report = await AbuseUserReport.findOne({
|
||||
_id: ps.reportId
|
||||
});
|
||||
|
||||
if (report == null) {
|
||||
return rej('report not found');
|
||||
throw new Error('report not found');
|
||||
}
|
||||
|
||||
await AbuseUserReport.remove({
|
||||
_id: report._id
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -25,17 +25,17 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
if (user.isAdmin) {
|
||||
return rej('cannot reset password of admin');
|
||||
throw new Error('cannot reset password of admin');
|
||||
}
|
||||
|
||||
const passwd = rndstr('a-zA-Z0-9', 8);
|
||||
@ -46,12 +46,12 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
await User.findOneAndUpdate({
|
||||
_id: user._id
|
||||
}, {
|
||||
$set: {
|
||||
password: hash
|
||||
}
|
||||
});
|
||||
|
||||
res({
|
||||
password: passwd
|
||||
$set: {
|
||||
password: hash
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
return {
|
||||
password: passwd
|
||||
};
|
||||
});
|
||||
|
@ -23,18 +23,18 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
if (me.isModerator && user.isAdmin) {
|
||||
return rej('cannot show info of admin');
|
||||
throw new Error('cannot show info of admin');
|
||||
}
|
||||
|
||||
res(user);
|
||||
}));
|
||||
return user;
|
||||
});
|
||||
|
@ -63,7 +63,7 @@ const sort: any = { // < https://github.com/Microsoft/TypeScript/issues/1863
|
||||
[fallback]: { _id: -1 }
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const q = {
|
||||
$and: []
|
||||
} as any;
|
||||
@ -99,5 +99,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
skip: ps.offset
|
||||
});
|
||||
|
||||
res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
|
||||
}));
|
||||
return await Promise.all(users.map(user => pack(user, me, { detail: true })));
|
||||
});
|
||||
|
@ -24,17 +24,17 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
if (user.isAdmin) {
|
||||
return rej('cannot silence admin');
|
||||
throw new Error('cannot silence admin');
|
||||
}
|
||||
|
||||
await User.findOneAndUpdate({
|
||||
@ -45,5 +45,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -24,30 +24,30 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
if (user.isAdmin) {
|
||||
return rej('cannot suspend admin');
|
||||
throw new Error('cannot suspend admin');
|
||||
}
|
||||
|
||||
if (user.isModerator) {
|
||||
return rej('cannot suspend moderator');
|
||||
throw new Error('cannot suspend moderator');
|
||||
}
|
||||
|
||||
await User.findOneAndUpdate({
|
||||
_id: user._id
|
||||
}, {
|
||||
$set: {
|
||||
isSuspended: true
|
||||
}
|
||||
});
|
||||
$set: {
|
||||
isSuspended: true
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -24,13 +24,13 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await User.findOneAndUpdate({
|
||||
@ -41,5 +41,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -24,22 +24,22 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await User.findOneAndUpdate({
|
||||
_id: user._id
|
||||
}, {
|
||||
$set: {
|
||||
isSuspended: false
|
||||
}
|
||||
});
|
||||
$set: {
|
||||
isSuspended: false
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -24,22 +24,22 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await User.findOneAndUpdate({
|
||||
_id: user._id
|
||||
}, {
|
||||
$set: {
|
||||
isVerified: false
|
||||
}
|
||||
});
|
||||
$set: {
|
||||
isVerified: false
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -323,7 +323,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const set = {} as any;
|
||||
|
||||
if (ps.broadcasts) {
|
||||
@ -506,5 +506,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
$set: set
|
||||
}, { upsert: true });
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -26,9 +26,10 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise((res, rej) => {
|
||||
updatePersonById(ps.userId).then(() => res(), e => rej(e));
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
await updatePersonById(ps.userId);
|
||||
return;
|
||||
});
|
||||
|
||||
async function updatePersonById(userId: mongo.ObjectID) {
|
||||
const user = await getRemoteUser(userId);
|
||||
|
@ -24,22 +24,22 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (user == null) {
|
||||
return rej('user not found');
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await User.findOneAndUpdate({
|
||||
_id: user._id
|
||||
}, {
|
||||
$set: {
|
||||
isVerified: true
|
||||
}
|
||||
});
|
||||
$set: {
|
||||
isVerified: true
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ export const meta = {
|
||||
requireCredential: false,
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const instance = await fetchMeta();
|
||||
const hidedTags = instance.hidedTags.map(t => t.toLowerCase());
|
||||
|
||||
@ -40,7 +40,7 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
//#endregion
|
||||
|
||||
if (data.length == 0) {
|
||||
return res([]);
|
||||
return [];
|
||||
}
|
||||
|
||||
let tags: {
|
||||
@ -66,5 +66,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
|
||||
tags = tags.slice(0, 30);
|
||||
|
||||
res(tags);
|
||||
}));
|
||||
return tags;
|
||||
});
|
||||
|
@ -7,6 +7,7 @@ import { createPerson } from '../../../../remote/activitypub/models/person';
|
||||
import Note, { pack as packNote, INote } from '../../../../models/note';
|
||||
import { createNote } from '../../../../remote/activitypub/models/note';
|
||||
import Resolver from '../../../../remote/activitypub/resolver';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -23,13 +24,24 @@ export const meta = {
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchObject: {
|
||||
message: 'No such object.',
|
||||
code: 'NO_SUCH_OBJECT',
|
||||
id: 'dc94d745-1262-4e63-a17d-fecaa57efc82'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise((res, rej) => {
|
||||
fetchAny(ps.uri)
|
||||
.then(object => object != null ? res(object) : rej('object not found'))
|
||||
.catch(e => rej(e));
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
const object = await fetchAny(ps.uri);
|
||||
if (object) {
|
||||
return object;
|
||||
} else {
|
||||
throw new ApiError(meta.errors.noSuchObject);
|
||||
}
|
||||
});
|
||||
|
||||
/***
|
||||
* URIからUserかNoteを解決する
|
||||
|
@ -27,7 +27,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Generate secret
|
||||
const secret = rndstr('a-zA-Z0-9', 32);
|
||||
|
||||
@ -42,9 +42,8 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
secret: secret
|
||||
});
|
||||
|
||||
// Response
|
||||
res(await pack(app, null, {
|
||||
return await pack(app, null, {
|
||||
detail: true,
|
||||
includeSecret: true
|
||||
}));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
||||
import ID, { transform } from '../../../../misc/cafy-id';
|
||||
import App, { pack } from '../../../../models/app';
|
||||
import define from '../../define';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
params: {
|
||||
@ -9,22 +10,29 @@ export const meta = {
|
||||
validator: $.type(ID),
|
||||
transform: transform
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchApp: {
|
||||
message: 'No such app.',
|
||||
code: 'NO_SUCH_APP',
|
||||
id: 'dce83913-2dc6-4093-8a7b-71dbb11718a3'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user, app) => {
|
||||
const isSecure = user != null && app == null;
|
||||
|
||||
// Lookup app
|
||||
const ap = await App.findOne({ _id: ps.appId });
|
||||
|
||||
if (ap === null) {
|
||||
return rej('app not found');
|
||||
throw new ApiError(meta.errors.noSuchApp);
|
||||
}
|
||||
|
||||
// Send response
|
||||
res(await pack(ap, user, {
|
||||
return await pack(ap, user, {
|
||||
detail: true,
|
||||
includeSecret: isSecure && ap.userId.equals(user._id)
|
||||
}));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import App from '../../../../models/app';
|
||||
import AuthSess from '../../../../models/auth-session';
|
||||
import AccessToken from '../../../../models/access-token';
|
||||
import define from '../../define';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
@ -15,16 +16,24 @@ export const meta = {
|
||||
token: {
|
||||
validator: $.str
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchSession: {
|
||||
message: 'No such session.',
|
||||
code: 'NO_SUCH_SESSION',
|
||||
id: '9c72d8de-391a-43c1-9d06-08d29efde8df'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch token
|
||||
const session = await AuthSess
|
||||
.findOne({ token: ps.token });
|
||||
|
||||
if (session === null) {
|
||||
return rej('session not found');
|
||||
throw new ApiError(meta.errors.noSuchSession);
|
||||
}
|
||||
|
||||
// Generate access token
|
||||
@ -64,6 +73,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Response
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import App from '../../../../../models/app';
|
||||
import AuthSess from '../../../../../models/auth-session';
|
||||
import config from '../../../../../config';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: false,
|
||||
@ -12,17 +13,25 @@ export const meta = {
|
||||
appSecret: {
|
||||
validator: $.str
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchApp: {
|
||||
message: 'No such app.',
|
||||
code: 'NO_SUCH_APP',
|
||||
id: '92f93e63-428e-4f2f-a5a4-39e1407fe998'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
// Lookup app
|
||||
const app = await App.findOne({
|
||||
secret: ps.appSecret
|
||||
});
|
||||
|
||||
if (app == null) {
|
||||
return rej('app not found');
|
||||
throw new ApiError(meta.errors.noSuchApp);
|
||||
}
|
||||
|
||||
// Generate token
|
||||
@ -35,9 +44,8 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
token: token
|
||||
});
|
||||
|
||||
// Response
|
||||
res({
|
||||
return {
|
||||
token: doc.token,
|
||||
url: `${config.auth_url}/${doc.token}`
|
||||
});
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
@ -1,6 +1,7 @@
|
||||
import $ from 'cafy';
|
||||
import AuthSess, { pack } from '../../../../../models/auth-session';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: false,
|
||||
@ -9,19 +10,26 @@ export const meta = {
|
||||
token: {
|
||||
validator: $.str
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchSession: {
|
||||
message: 'No such session.',
|
||||
code: 'NO_SUCH_SESSION',
|
||||
id: 'bd72c97d-eba7-4adb-a467-f171b8847250'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Lookup session
|
||||
const session = await AuthSess.findOne({
|
||||
token: ps.token
|
||||
});
|
||||
|
||||
if (session == null) {
|
||||
return rej('session not found');
|
||||
throw new ApiError(meta.errors.noSuchSession);
|
||||
}
|
||||
|
||||
// Response
|
||||
res(await pack(session, user));
|
||||
}));
|
||||
return await pack(session, user);
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import AuthSess from '../../../../../models/auth-session';
|
||||
import AccessToken from '../../../../../models/access-token';
|
||||
import { pack } from '../../../../../models/user';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: false,
|
||||
@ -16,17 +17,37 @@ export const meta = {
|
||||
token: {
|
||||
validator: $.str
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchApp: {
|
||||
message: 'No such app.',
|
||||
code: 'NO_SUCH_APP',
|
||||
id: 'fcab192a-2c5a-43b7-8ad8-9b7054d8d40d'
|
||||
},
|
||||
|
||||
noSuchSession: {
|
||||
message: 'No such session.',
|
||||
code: 'NO_SUCH_SESSION',
|
||||
id: '5b5a1503-8bc8-4bd0-8054-dc189e8cdcb3'
|
||||
},
|
||||
|
||||
pendingSession: {
|
||||
message: 'This session is not completed yet.',
|
||||
code: 'PENDING_SESSION',
|
||||
id: '8c8a4145-02cc-4cca-8e66-29ba60445a8e'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
// Lookup app
|
||||
const app = await App.findOne({
|
||||
secret: ps.appSecret
|
||||
});
|
||||
|
||||
if (app == null) {
|
||||
return rej('app not found');
|
||||
throw new ApiError(meta.errors.noSuchApp);
|
||||
}
|
||||
|
||||
// Fetch token
|
||||
@ -37,11 +58,11 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (session === null) {
|
||||
return rej('session not found');
|
||||
throw new ApiError(meta.errors.noSuchSession);
|
||||
}
|
||||
|
||||
if (session.userId == null) {
|
||||
return rej('this session is not allowed yet');
|
||||
throw new ApiError(meta.errors.pendingSession);
|
||||
}
|
||||
|
||||
// Lookup access token
|
||||
@ -61,11 +82,10 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
_id: session._id
|
||||
});
|
||||
|
||||
// Response
|
||||
res({
|
||||
return {
|
||||
accessToken: accessToken.token,
|
||||
user: await pack(session.userId, null, {
|
||||
detail: true
|
||||
})
|
||||
});
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import User, { pack } from '../../../../models/user';
|
||||
import Blocking from '../../../../models/blocking';
|
||||
import create from '../../../../services/blocking/create';
|
||||
import define from '../../define';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -32,15 +33,35 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '7cc4f851-e2f1-4621-9633-ec9e1d00c01e'
|
||||
},
|
||||
|
||||
blockeeIsYourself: {
|
||||
message: 'Blockee is yourself.',
|
||||
code: 'BLOCKEE_IS_YOURSELF',
|
||||
id: '88b19138-f28d-42c0-8499-6a31bbd0fdc6'
|
||||
},
|
||||
|
||||
alreadyBlocking: {
|
||||
message: 'You are already blocking that user.',
|
||||
code: 'ALREADY_BLOCKING',
|
||||
id: '787fed64-acb9-464a-82eb-afbd745b9614'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const blocker = user;
|
||||
|
||||
// 自分自身
|
||||
if (user._id.equals(ps.userId)) {
|
||||
return rej('blockee is yourself');
|
||||
throw new ApiError(meta.errors.blockeeIsYourself);
|
||||
}
|
||||
|
||||
// Get blockee
|
||||
@ -54,7 +75,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (blockee === null) {
|
||||
return rej('user not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
// Check if already blocking
|
||||
@ -64,14 +85,13 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (exist !== null) {
|
||||
return rej('already blocking');
|
||||
throw new ApiError(meta.errors.alreadyBlocking);
|
||||
}
|
||||
|
||||
// Create blocking
|
||||
await create(blocker, blockee);
|
||||
|
||||
// Send response
|
||||
res(await pack(blockee._id, user, {
|
||||
return await pack(blockee._id, user, {
|
||||
detail: true
|
||||
}));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import User, { pack } from '../../../../models/user';
|
||||
import Blocking from '../../../../models/blocking';
|
||||
import deleteBlocking from '../../../../services/blocking/delete';
|
||||
import define from '../../define';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -32,15 +33,35 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '8621d8bf-c358-4303-a066-5ea78610eb3f'
|
||||
},
|
||||
|
||||
blockeeIsYourself: {
|
||||
message: 'Blockee is yourself.',
|
||||
code: 'BLOCKEE_IS_YOURSELF',
|
||||
id: '06f6fac6-524b-473c-a354-e97a40ae6eac'
|
||||
},
|
||||
|
||||
notBlocking: {
|
||||
message: 'You are not blocking that user.',
|
||||
code: 'NOT_BLOCKING',
|
||||
id: '291b2efa-60c6-45c0-9f6a-045c8f9b02cd'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const blocker = user;
|
||||
|
||||
// Check if the blockee is yourself
|
||||
if (user._id.equals(ps.userId)) {
|
||||
return rej('blockee is yourself');
|
||||
throw new ApiError(meta.errors.blockeeIsYourself);
|
||||
}
|
||||
|
||||
// Get blockee
|
||||
@ -54,7 +75,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (blockee === null) {
|
||||
return rej('user not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
// Check not blocking
|
||||
@ -64,14 +85,13 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (exist === null) {
|
||||
return rej('already not blocking');
|
||||
throw new ApiError(meta.errors.notBlocking);
|
||||
}
|
||||
|
||||
// Delete blocking
|
||||
await deleteBlocking(blocker, blockee);
|
||||
|
||||
// Send response
|
||||
res(await pack(blockee._id, user, {
|
||||
return await pack(blockee._id, user, {
|
||||
detail: true
|
||||
}));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -31,12 +31,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
// Check if both of sinceId and untilId is specified
|
||||
if (ps.sinceId && ps.untilId) {
|
||||
return rej('cannot set sinceId and untilId');
|
||||
}
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
const query = {
|
||||
blockerId: me._id
|
||||
} as any;
|
||||
@ -62,5 +57,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
sort: sort
|
||||
});
|
||||
|
||||
res(await packMany(blockings, me));
|
||||
}));
|
||||
return await packMany(blockings, me);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await activeUsersChart.getChart(ps.span as any, ps.limit);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await activeUsersChart.getChart(ps.span as any, ps.limit);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await driveChart.getChart(ps.span as any, ps.limit);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await driveChart.getChart(ps.span as any, ps.limit);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await federationChart.getChart(ps.span as any, ps.limit);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await federationChart.getChart(ps.span as any, ps.limit);
|
||||
});
|
||||
|
@ -34,8 +34,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await hashtagChart.getChart(ps.span as any, ps.limit, ps.tag);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await hashtagChart.getChart(ps.span as any, ps.limit, ps.tag);
|
||||
});
|
||||
|
@ -35,8 +35,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await instanceChart.getChart(ps.span as any, ps.limit, ps.host);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await instanceChart.getChart(ps.span as any, ps.limit, ps.host);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await networkChart.getChart(ps.span as any, ps.limit);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await networkChart.getChart(ps.span as any, ps.limit);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await notesChart.getChart(ps.span as any, ps.limit);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await notesChart.getChart(ps.span as any, ps.limit);
|
||||
});
|
||||
|
@ -37,8 +37,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await perUserDriveChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await perUserDriveChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
});
|
||||
|
@ -37,8 +37,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await perUserFollowingChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await perUserFollowingChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
});
|
||||
|
@ -37,8 +37,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await perUserNotesChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await perUserNotesChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
});
|
||||
|
@ -37,8 +37,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await perUserReactionsChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await perUserReactionsChart.getChart(ps.span as any, ps.limit, ps.userId);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
const stats = await usersChart.getChart(ps.span as any, ps.limit);
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
export default define(meta, async (ps) => {
|
||||
return await usersChart.getChart(ps.span as any, ps.limit);
|
||||
});
|
||||
|
@ -13,35 +13,34 @@ export const meta = {
|
||||
kind: 'drive-read'
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const instance = await fetchMeta();
|
||||
|
||||
// Calculate drive usage
|
||||
const usage = await DriveFile
|
||||
.aggregate([{
|
||||
$match: {
|
||||
'metadata.userId': user._id,
|
||||
'metadata.deletedAt': { $exists: false }
|
||||
}
|
||||
}, {
|
||||
$project: {
|
||||
length: true
|
||||
}
|
||||
}, {
|
||||
$group: {
|
||||
_id: null,
|
||||
usage: { $sum: '$length' }
|
||||
}
|
||||
}])
|
||||
.then((aggregates: any[]) => {
|
||||
if (aggregates.length > 0) {
|
||||
return aggregates[0].usage;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
const usage = await DriveFile.aggregate([{
|
||||
$match: {
|
||||
'metadata.userId': user._id,
|
||||
'metadata.deletedAt': { $exists: false }
|
||||
}
|
||||
}, {
|
||||
$project: {
|
||||
length: true
|
||||
}
|
||||
}, {
|
||||
$group: {
|
||||
_id: null,
|
||||
usage: { $sum: '$length' }
|
||||
}
|
||||
}])
|
||||
.then((aggregates: any[]) => {
|
||||
if (aggregates.length > 0) {
|
||||
return aggregates[0].usage;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
res({
|
||||
return {
|
||||
capacity: 1024 * 1024 * instance.localDriveCapacityMb,
|
||||
usage: usage
|
||||
});
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
@ -41,12 +41,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
// Check if both of sinceId and untilId is specified
|
||||
if (ps.sinceId && ps.untilId) {
|
||||
return rej('cannot set sinceId and untilId');
|
||||
}
|
||||
|
||||
export default define(meta, async (ps, user) => {
|
||||
const sort = {
|
||||
_id: -1
|
||||
};
|
||||
@ -78,5 +73,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
sort: sort
|
||||
});
|
||||
|
||||
res(await packMany(files, { detail: false, self: true }));
|
||||
}));
|
||||
return await packMany(files, { detail: false, self: true });
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import DriveFile from '../../../../../models/drive-file';
|
||||
import define from '../../../define';
|
||||
import { packMany } from '../../../../../models/note';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -25,10 +26,18 @@ export const meta = {
|
||||
'en-US': 'Target file ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'c118ece3-2e4b-4296-99d1-51756e32d232',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch file
|
||||
const file = await DriveFile
|
||||
.findOne({
|
||||
@ -38,10 +47,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (file === null) {
|
||||
return rej('file-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
|
||||
res(await packMany(file.metadata.attachedNoteIds || [], user, {
|
||||
return await packMany(file.metadata.attachedNoteIds || [], user, {
|
||||
detail: true
|
||||
}));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -22,16 +22,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const file = await DriveFile.findOne({
|
||||
md5: ps.md5,
|
||||
'metadata.userId': user._id,
|
||||
'metadata.deletedAt': { $exists: false }
|
||||
});
|
||||
|
||||
if (file === null) {
|
||||
res({ file: null });
|
||||
} else {
|
||||
res({ file: await pack(file, { self: true }) });
|
||||
}
|
||||
}));
|
||||
return { file: file ? await pack(file, { self: true }) : null };
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import { validateFileName, pack } from '../../../../../models/drive-file';
|
||||
import create from '../../../../../services/drive/add-file';
|
||||
import define from '../../../define';
|
||||
import { apiLogger } from '../../../logger';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -51,10 +52,18 @@ export const meta = {
|
||||
'ja-JP': 'true にすると、同じハッシュを持つファイルが既にアップロードされていても強制的にファイルを作成します。',
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
invalidFileName: {
|
||||
message: 'Invalid file name.',
|
||||
code: 'INVALID_FILE_NAME',
|
||||
id: 'f449b209-0c60-4e51-84d5-29486263bfd4'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user, app, file, cleanup) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user, app, file, cleanup) => {
|
||||
// Get 'name' parameter
|
||||
let name = file.originalname;
|
||||
if (name !== undefined && name !== null) {
|
||||
@ -64,7 +73,7 @@ export default define(meta, (ps, user, app, file, cleanup) => new Promise(async
|
||||
} else if (name === 'blob') {
|
||||
name = null;
|
||||
} else if (!validateFileName(name)) {
|
||||
return rej('invalid name');
|
||||
throw new ApiError(meta.errors.invalidFileName);
|
||||
}
|
||||
} else {
|
||||
name = null;
|
||||
@ -73,15 +82,11 @@ export default define(meta, (ps, user, app, file, cleanup) => new Promise(async
|
||||
try {
|
||||
// Create file
|
||||
const driveFile = await create(user, file.path, name, null, ps.folderId, ps.force, false, null, null, ps.isSensitive);
|
||||
|
||||
cleanup();
|
||||
|
||||
res(pack(driveFile, { self: true }));
|
||||
return pack(driveFile, { self: true });
|
||||
} catch (e) {
|
||||
apiLogger.error(e);
|
||||
|
||||
throw new ApiError();
|
||||
} finally {
|
||||
cleanup();
|
||||
|
||||
rej(e);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import DriveFile from '../../../../../models/drive-file';
|
||||
import del from '../../../../../services/drive/delete-file';
|
||||
import { publishDriveStream } from '../../../../../services/stream';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -26,10 +27,24 @@ export const meta = {
|
||||
'en-US': 'Target file ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: '908939ec-e52b-4458-b395-1025195cea58'
|
||||
},
|
||||
|
||||
accessDenied: {
|
||||
message: 'Access denied.',
|
||||
code: 'ACCESS_DENIED',
|
||||
id: '5eb8d909-2540-4970-90b8-dd6f86088121'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch file
|
||||
const file = await DriveFile
|
||||
.findOne({
|
||||
@ -37,11 +52,11 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (file === null) {
|
||||
return rej('file-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
|
||||
if (!user.isAdmin && !user.isModerator && !file.metadata.userId.equals(user._id)) {
|
||||
return rej('access denied');
|
||||
throw new ApiError(meta.errors.accessDenied);
|
||||
}
|
||||
|
||||
// Delete
|
||||
@ -50,5 +65,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
// Publish fileDeleted event
|
||||
publishDriveStream(user._id, 'fileDeleted', file._id);
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const files = await DriveFile
|
||||
.find({
|
||||
filename: ps.name,
|
||||
@ -32,5 +32,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
'metadata.folderId': ps.folderId
|
||||
});
|
||||
|
||||
res(await Promise.all(files.map(file => pack(file, { self: true }))));
|
||||
}));
|
||||
return await Promise.all(files.map(file => pack(file, { self: true })));
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import DriveFile, { pack, IDriveFile } from '../../../../../models/drive-file';
|
||||
import define from '../../../define';
|
||||
import config from '../../../../../config';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -34,10 +35,30 @@ export const meta = {
|
||||
'en-US': 'Target file URL'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: '067bc436-2718-4795-b0fb-ecbe43949e31'
|
||||
},
|
||||
|
||||
accessDenied: {
|
||||
message: 'Access denied.',
|
||||
code: 'ACCESS_DENIED',
|
||||
id: '25b73c73-68b1-41d0-bad1-381cfdf6579f'
|
||||
},
|
||||
|
||||
fileIdOrUrlRequired: {
|
||||
message: 'fileId or url required.',
|
||||
code: 'INVALID_PARAM',
|
||||
id: '89674805-722c-440c-8d88-5641830dc3e4'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
let file: IDriveFile;
|
||||
|
||||
if (ps.fileId) {
|
||||
@ -69,22 +90,19 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return rej('fileId or url required');
|
||||
throw new ApiError(meta.errors.fileIdOrUrlRequired);
|
||||
}
|
||||
|
||||
if (!user.isAdmin && !user.isModerator && !file.metadata.userId.equals(user._id)) {
|
||||
return rej('access denied');
|
||||
throw new ApiError(meta.errors.accessDenied);
|
||||
}
|
||||
|
||||
if (file === null) {
|
||||
return rej('file-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
|
||||
// Serialize
|
||||
const _file = await pack(file, {
|
||||
return await pack(file, {
|
||||
detail: true,
|
||||
self: true
|
||||
});
|
||||
|
||||
res(_file);
|
||||
}));
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import DriveFile, { validateFileName, pack } from '../../../../../models/drive-f
|
||||
import { publishDriveStream } from '../../../../../services/stream';
|
||||
import define from '../../../define';
|
||||
import Note from '../../../../../models/note';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -51,10 +52,30 @@ export const meta = {
|
||||
'en-US': 'Whether this media is NSFW'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'e7778c7e-3af9-49cd-9690-6dbc3e6c972d'
|
||||
},
|
||||
|
||||
accessDenied: {
|
||||
message: 'Access denied.',
|
||||
code: 'ACCESS_DENIED',
|
||||
id: '01a53b27-82fc-445b-a0c1-b558465a8ed2'
|
||||
},
|
||||
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: 'ea8fb7a5-af77-4a08-b608-c0218176cd73'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch file
|
||||
const file = await DriveFile
|
||||
.findOne({
|
||||
@ -62,11 +83,11 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (file === null) {
|
||||
return rej('file-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
|
||||
if (!user.isAdmin && !user.isModerator && !file.metadata.userId.equals(user._id)) {
|
||||
return rej('access denied');
|
||||
throw new ApiError(meta.errors.accessDenied);
|
||||
}
|
||||
|
||||
if (ps.name) file.filename = ps.name;
|
||||
@ -85,7 +106,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (folder === null) {
|
||||
return rej('folder-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
|
||||
file.metadata.folderId = folder._id;
|
||||
@ -114,12 +135,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Serialize
|
||||
const fileObj = await pack(file, { self: true });
|
||||
|
||||
// Response
|
||||
res(fileObj);
|
||||
|
||||
// Publish fileUpdated event
|
||||
publishDriveStream(user._id, 'fileUpdated', fileObj);
|
||||
}));
|
||||
|
||||
return fileObj;
|
||||
});
|
||||
|
@ -50,6 +50,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
res(pack(await uploadFromUrl(ps.url, user, ps.folderId, null, ps.isSensitive, ps.force), { self: true }));
|
||||
}));
|
||||
export default define(meta, async (ps, user) => {
|
||||
return await pack(await uploadFromUrl(ps.url, user, ps.folderId, null, ps.isSensitive, ps.force), { self: true });
|
||||
});
|
||||
|
@ -37,12 +37,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
// Check if both of sinceId and untilId is specified
|
||||
if (ps.sinceId && ps.untilId) {
|
||||
return rej('cannot set sinceId and untilId');
|
||||
}
|
||||
|
||||
export default define(meta, async (ps, user) => {
|
||||
const sort = {
|
||||
_id: -1
|
||||
};
|
||||
@ -67,5 +62,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
sort: sort
|
||||
});
|
||||
|
||||
res(await Promise.all(folders.map(folder => pack(folder))));
|
||||
}));
|
||||
return await Promise.all(folders.map(folder => pack(folder)));
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import DriveFolder, { isValidFolderName, pack } from '../../../../../models/drive-folder';
|
||||
import { publishDriveStream } from '../../../../../services/stream';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -34,10 +35,18 @@ export const meta = {
|
||||
'en-US': 'Parent folder ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: '53326628-a00d-40a6-a3cd-8975105c0f95'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// If the parent folder is specified
|
||||
let parent = null;
|
||||
if (ps.parentId) {
|
||||
@ -49,7 +58,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (parent === null) {
|
||||
return rej('parent-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,12 +70,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
userId: user._id
|
||||
});
|
||||
|
||||
// Serialize
|
||||
const folderObj = await pack(folder);
|
||||
|
||||
// Response
|
||||
res(folderObj);
|
||||
|
||||
// Publish folderCreated event
|
||||
publishDriveStream(user._id, 'folderCreated', folderObj);
|
||||
}));
|
||||
|
||||
return folderObj;
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import DriveFolder from '../../../../../models/drive-folder';
|
||||
import define from '../../../define';
|
||||
import { publishDriveStream } from '../../../../../services/stream';
|
||||
import DriveFile from '../../../../../models/drive-file';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -26,10 +27,24 @@ export const meta = {
|
||||
'en-US': 'Target folder ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: '1069098f-c281-440f-b085-f9932edbe091'
|
||||
},
|
||||
|
||||
hasChildFilesOrFolders: {
|
||||
message: 'This folder has child files or folders.',
|
||||
code: 'HAS_CHILD_FILES_OR_FOLDERS',
|
||||
id: 'b0fc8a17-963c-405d-bfbc-859a487295e1'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Get folder
|
||||
const folder = await DriveFolder
|
||||
.findOne({
|
||||
@ -38,7 +53,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (folder === null) {
|
||||
return rej('folder-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
|
||||
const [childFoldersCount, childFilesCount] = await Promise.all([
|
||||
@ -47,7 +62,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
]);
|
||||
|
||||
if (childFoldersCount !== 0 || childFilesCount !== 0) {
|
||||
return rej('has-child-contents');
|
||||
throw new ApiError(meta.errors.hasChildFilesOrFolders);
|
||||
}
|
||||
|
||||
await DriveFolder.remove({ _id: folder._id });
|
||||
@ -55,5 +70,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
// Publish folderCreated event
|
||||
publishDriveStream(user._id, 'folderDeleted', folder._id);
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const folders = await DriveFolder
|
||||
.find({
|
||||
name: ps.name,
|
||||
@ -32,5 +32,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
parentId: ps.parentId
|
||||
});
|
||||
|
||||
res(await Promise.all(folders.map(folder => pack(folder))));
|
||||
}));
|
||||
return await Promise.all(folders.map(folder => pack(folder)));
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
||||
import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import DriveFolder, { pack } from '../../../../../models/drive-folder';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -24,10 +25,18 @@ export const meta = {
|
||||
'en-US': 'Target folder ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: 'd74ab9eb-bb09-4bba-bf24-fb58f761e1e9'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Get folder
|
||||
const folder = await DriveFolder
|
||||
.findOne({
|
||||
@ -36,11 +45,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (folder === null) {
|
||||
return rej('folder-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
|
||||
// Serialize
|
||||
res(await pack(folder, {
|
||||
return await pack(folder, {
|
||||
detail: true
|
||||
}));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import DriveFolder, { isValidFolderName, pack } from '../../../../../models/drive-folder';
|
||||
import { publishDriveStream } from '../../../../../services/stream';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -42,10 +43,30 @@ export const meta = {
|
||||
'en-US': 'Parent folder ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: 'f7974dac-2c0d-4a27-926e-23583b28e98e'
|
||||
},
|
||||
|
||||
noSuchParentFolder: {
|
||||
message: 'No such parent folder.',
|
||||
code: 'NO_SUCH_PARENT_FOLDER',
|
||||
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1'
|
||||
},
|
||||
|
||||
recursiveNesting: {
|
||||
message: 'It can not be structured like nesting folders recursively.',
|
||||
code: 'NO_SUCH_PARENT_FOLDER',
|
||||
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch folder
|
||||
const folder = await DriveFolder
|
||||
.findOne({
|
||||
@ -54,7 +75,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (folder === null) {
|
||||
return rej('folder-not-found');
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
|
||||
if (ps.name) folder.name = ps.name;
|
||||
@ -71,7 +92,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (parent === null) {
|
||||
return rej('parent-folder-not-found');
|
||||
throw new ApiError(meta.errors.noSuchParentFolder);
|
||||
}
|
||||
|
||||
// Check if the circular reference will occur
|
||||
@ -95,7 +116,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
|
||||
if (parent.parentId !== null) {
|
||||
if (await checkCircle(parent.parentId)) {
|
||||
return rej('detected-circular-definition');
|
||||
throw new ApiError(meta.errors.recursiveNesting);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,12 +132,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Serialize
|
||||
const folderObj = await pack(folder);
|
||||
|
||||
// Response
|
||||
res(folderObj);
|
||||
|
||||
// Publish folderUpdated event
|
||||
publishDriveStream(user._id, 'folderUpdated', folderObj);
|
||||
}));
|
||||
|
||||
return folderObj;
|
||||
});
|
||||
|
@ -30,12 +30,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
// Check if both of sinceId and untilId is specified
|
||||
if (ps.sinceId && ps.untilId) {
|
||||
return rej('cannot set sinceId and untilId');
|
||||
}
|
||||
|
||||
export default define(meta, async (ps, user) => {
|
||||
const sort = {
|
||||
_id: -1
|
||||
};
|
||||
@ -66,5 +61,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
sort: sort
|
||||
});
|
||||
|
||||
res(await packMany(files, { self: true }));
|
||||
}));
|
||||
return await packMany(files, { self: true });
|
||||
});
|
||||
|
@ -34,7 +34,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
let sort;
|
||||
|
||||
if (ps.sort) {
|
||||
@ -122,5 +122,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
skip: ps.offset
|
||||
});
|
||||
|
||||
res(instances);
|
||||
}));
|
||||
return instances;
|
||||
});
|
||||
|
@ -12,9 +12,9 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const instance = await Instance
|
||||
.findOne({ host: ps.host });
|
||||
|
||||
res(instance);
|
||||
}));
|
||||
return instance;
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import User, { pack } from '../../../../models/user';
|
||||
import Following from '../../../../models/following';
|
||||
import create from '../../../../services/following/create';
|
||||
import define from '../../define';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -32,15 +33,47 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5'
|
||||
},
|
||||
|
||||
followeeIsYourself: {
|
||||
message: 'Followee is yourself.',
|
||||
code: 'FOLLOWEE_IS_YOURSELF',
|
||||
id: '26fbe7bb-a331-4857-af17-205b426669a9'
|
||||
},
|
||||
|
||||
alreadyFollowing: {
|
||||
message: 'You are already following that user.',
|
||||
code: 'ALREADY_FOLLOWING',
|
||||
id: '35387507-38c7-4cb9-9197-300b93783fa0'
|
||||
},
|
||||
|
||||
blocking: {
|
||||
message: 'You are blocking that user.',
|
||||
code: 'BLOCKING',
|
||||
id: '4e2206ec-aa4f-4960-b865-6c23ac38e2d9'
|
||||
},
|
||||
|
||||
blocked: {
|
||||
message: 'You are blocked by that user.',
|
||||
code: 'BLOCKED',
|
||||
id: 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const follower = user;
|
||||
|
||||
// 自分自身
|
||||
if (user._id.equals(ps.userId)) {
|
||||
return rej('followee is yourself');
|
||||
throw new ApiError(meta.errors.followeeIsYourself);
|
||||
}
|
||||
|
||||
// Get followee
|
||||
@ -54,7 +87,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (followee === null) {
|
||||
return rej('user not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
// Check if already following
|
||||
@ -64,16 +97,16 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (exist !== null) {
|
||||
return rej('already following');
|
||||
throw new ApiError(meta.errors.alreadyFollowing);
|
||||
}
|
||||
|
||||
// Create following
|
||||
try {
|
||||
await create(follower, followee);
|
||||
} catch (e) {
|
||||
return rej(e && e.message ? e.message : e);
|
||||
if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking);
|
||||
if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Send response
|
||||
res(await pack(followee._id, user));
|
||||
}));
|
||||
return await pack(followee._id, user);
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import User, { pack } from '../../../../models/user';
|
||||
import Following from '../../../../models/following';
|
||||
import deleteFollowing from '../../../../services/following/delete';
|
||||
import define from '../../define';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
stability: 'stable',
|
||||
@ -32,15 +33,35 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8'
|
||||
},
|
||||
|
||||
followeeIsYourself: {
|
||||
message: 'Followee is yourself.',
|
||||
code: 'FOLLOWEE_IS_YOURSELF',
|
||||
id: 'd9e400b9-36b0-4808-b1d8-79e707f1296c'
|
||||
},
|
||||
|
||||
notFollowing: {
|
||||
message: 'You are not following that user.',
|
||||
code: 'NOT_FOLLOWING',
|
||||
id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const follower = user;
|
||||
|
||||
// Check if the followee is yourself
|
||||
if (user._id.equals(ps.userId)) {
|
||||
return rej('followee is yourself');
|
||||
throw new ApiError(meta.errors.followeeIsYourself);
|
||||
}
|
||||
|
||||
// Get followee
|
||||
@ -54,7 +75,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (followee === null) {
|
||||
return rej('user not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
// Check not following
|
||||
@ -64,12 +85,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (exist === null) {
|
||||
return rej('already not following');
|
||||
throw new ApiError(meta.errors.notFollowing);
|
||||
}
|
||||
|
||||
// Delete following
|
||||
await deleteFollowing(follower, followee);
|
||||
|
||||
// Send response
|
||||
res(await pack(followee._id, user));
|
||||
}));
|
||||
return await pack(followee._id, user);
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import acceptFollowRequest from '../../../../../services/following/requests/accept';
|
||||
import User from '../../../../../models/user';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -23,20 +24,28 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '66ce1645-d66c-46bb-8b79-96739af885bd'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch follower
|
||||
const follower = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (follower === null) {
|
||||
return rej('follower not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
await acceptFollowRequest(user, follower);
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import cancelFollowRequest from '../../../../../services/following/requests/cancel';
|
||||
import User, { pack } from '../../../../../models/user';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -23,24 +24,39 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '4e68c551-fc4c-4e46-bb41-7d4a37bf9dab'
|
||||
},
|
||||
|
||||
followRequestNotFound: {
|
||||
message: 'Follow request not found.',
|
||||
code: 'FOLLOW_REQUEST_NOT_FOUND',
|
||||
id: '089b125b-d338-482a-9a09-e2622ac9f8d4'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch followee
|
||||
const followee = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (followee === null) {
|
||||
return rej('followee not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
try {
|
||||
await cancelFollowRequest(followee, user);
|
||||
} catch (e) {
|
||||
return rej(e);
|
||||
if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError(meta.errors.followRequestNotFound);
|
||||
throw e;
|
||||
}
|
||||
|
||||
res(await pack(followee._id, user));
|
||||
}));
|
||||
return await pack(followee._id, user);
|
||||
});
|
||||
|
@ -1,5 +1,3 @@
|
||||
// import $ from 'cafy';
|
||||
// import ID, { transform } from '../../../../../cafy-id';
|
||||
import FollowRequest, { pack } from '../../../../../models/follow-request';
|
||||
import define from '../../../define';
|
||||
|
||||
@ -14,11 +12,10 @@ export const meta = {
|
||||
kind: 'following-read'
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const reqs = await FollowRequest.find({
|
||||
followeeId: user._id
|
||||
});
|
||||
|
||||
// Send response
|
||||
res(await Promise.all(reqs.map(req => pack(req))));
|
||||
}));
|
||||
return await Promise.all(reqs.map(req => pack(req)));
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../misc/cafy-id';
|
||||
import rejectFollowRequest from '../../../../../services/following/requests/reject';
|
||||
import User from '../../../../../models/user';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -23,20 +24,28 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: 'abc2ffa6-25b2-4380-ba99-321ff3a94555'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Fetch follower
|
||||
const follower = await User.findOne({
|
||||
_id: ps.userId
|
||||
});
|
||||
|
||||
if (follower === null) {
|
||||
return rej('follower not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
await rejectFollowRequest(user, follower);
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -27,12 +27,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
// Check if both of sinceId and untilId is specified
|
||||
if (ps.sinceId && ps.untilId) {
|
||||
return rej('cannot set sinceId and untilId');
|
||||
}
|
||||
|
||||
export default define(meta, async (ps, user) => {
|
||||
const q: any = ps.my ? {
|
||||
isStarted: true,
|
||||
$or: [{
|
||||
@ -65,8 +60,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
limit: ps.limit
|
||||
});
|
||||
|
||||
// Reponse
|
||||
res(Promise.all(games.map(async (g) => await pack(g, user, {
|
||||
return await Promise.all(games.map((g) => pack(g, user, {
|
||||
detail: false
|
||||
}))));
|
||||
}));
|
||||
})));
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../../misc/cafy-id';
|
||||
import ReversiGame, { pack } from '../../../../../../models/games/reversi/game';
|
||||
import Reversi from '../../../../../../games/reversi/core';
|
||||
import define from '../../../../define';
|
||||
import { ApiError } from '../../../../error';
|
||||
|
||||
export const meta = {
|
||||
params: {
|
||||
@ -10,14 +11,22 @@ export const meta = {
|
||||
validator: $.type(ID),
|
||||
transform: transform,
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchGame: {
|
||||
message: 'No such game.',
|
||||
code: 'NO_SUCH_GAME',
|
||||
id: 'f13a03db-fae1-46c9-87f3-43c8165419e1'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const game = await ReversiGame.findOne({ _id: ps.gameId });
|
||||
|
||||
if (game == null) {
|
||||
return rej('game not found');
|
||||
throw new ApiError(meta.errors.noSuchGame);
|
||||
}
|
||||
|
||||
const o = new Reversi(game.settings.map, {
|
||||
@ -31,8 +40,8 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
|
||||
const packed = await pack(game, user);
|
||||
|
||||
res(Object.assign({
|
||||
return Object.assign({
|
||||
board: o.board,
|
||||
turn: o.turn
|
||||
}, packed));
|
||||
}));
|
||||
}, packed);
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import ID, { transform } from '../../../../../../misc/cafy-id';
|
||||
import ReversiGame, { pack } from '../../../../../../models/games/reversi/game';
|
||||
import { publishReversiGameStream } from '../../../../../../services/stream';
|
||||
import define from '../../../../define';
|
||||
import { ApiError } from '../../../../error';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -19,22 +20,42 @@ export const meta = {
|
||||
'ja-JP': '投了したい対局'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchGame: {
|
||||
message: 'No such game.',
|
||||
code: 'NO_SUCH_GAME',
|
||||
id: 'ace0b11f-e0a6-4076-a30d-e8284c81b2df'
|
||||
},
|
||||
|
||||
alreadyEnded: {
|
||||
message: 'That game has already ended.',
|
||||
code: 'ALREADY_ENDED',
|
||||
id: '6c2ad4a6-cbf1-4a5b-b187-b772826cfc6d'
|
||||
},
|
||||
|
||||
accessDenied: {
|
||||
message: 'Access denied.',
|
||||
code: 'ACCESS_DENIED',
|
||||
id: '6e04164b-a992-4c93-8489-2123069973e1'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const game = await ReversiGame.findOne({ _id: ps.gameId });
|
||||
|
||||
if (game == null) {
|
||||
return rej('game not found');
|
||||
throw new ApiError(meta.errors.noSuchGame);
|
||||
}
|
||||
|
||||
if (game.isEnded) {
|
||||
return rej('this game is already ended');
|
||||
throw new ApiError(meta.errors.alreadyEnded);
|
||||
}
|
||||
|
||||
if (!game.user1Id.equals(user._id) && !game.user2Id.equals(user._id)) {
|
||||
return rej('access denied');
|
||||
throw new ApiError(meta.errors.accessDenied);
|
||||
}
|
||||
|
||||
const winnerId = game.user1Id.equals(user._id) ? game.user2Id : game.user1Id;
|
||||
@ -54,5 +75,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
game: await pack(game._id, user)
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ export const meta = {
|
||||
requireCredential: true
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Find session
|
||||
const invitations = await Matching.find({
|
||||
childId: user._id
|
||||
@ -15,6 +15,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Reponse
|
||||
res(Promise.all(invitations.map(async (i) => await packMatching(i, user))));
|
||||
}));
|
||||
return await Promise.all(invitations.map((i) => packMatching(i, user)));
|
||||
});
|
||||
|
@ -6,6 +6,7 @@ import User from '../../../../../models/user';
|
||||
import { publishMainStream, publishReversiStream } from '../../../../../services/stream';
|
||||
import { eighteight } from '../../../../../games/reversi/maps';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
@ -19,13 +20,27 @@ export const meta = {
|
||||
'en-US': 'Target user ID'
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '0b4f0559-b484-4e31-9581-3f73cee89b28'
|
||||
},
|
||||
|
||||
isYourself: {
|
||||
message: 'Target user is yourself.',
|
||||
code: 'TARGET_IS_YOURSELF',
|
||||
id: '96fd7bd6-d2bc-426c-a865-d055dcd2828e'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Myself
|
||||
if (ps.userId.equals(user._id)) {
|
||||
return rej('invalid userId param');
|
||||
throw new ApiError(meta.errors.isYourself);
|
||||
}
|
||||
|
||||
// Find session
|
||||
@ -57,9 +72,6 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Reponse
|
||||
res(await packGame(game, user));
|
||||
|
||||
publishReversiStream(exist.parentId, 'matched', await packGame(game, exist.parentId));
|
||||
|
||||
const other = await Matching.count({
|
||||
@ -69,6 +81,8 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
if (other == 0) {
|
||||
publishMainStream(user._id, 'reversiNoInvites');
|
||||
}
|
||||
|
||||
return await packGame(game, user);
|
||||
} else {
|
||||
// Fetch child
|
||||
const child = await User.findOne({
|
||||
@ -80,7 +94,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (child === null) {
|
||||
return rej('user not found');
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
// 以前のセッションはすべて削除しておく
|
||||
@ -95,14 +109,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
childId: child._id
|
||||
});
|
||||
|
||||
// Reponse
|
||||
res();
|
||||
|
||||
const packed = await packMatching(matching, child);
|
||||
|
||||
// 招待
|
||||
publishReversiStream(child._id, 'invited', packed);
|
||||
|
||||
publishMainStream(child._id, 'reversiInvited', packed);
|
||||
|
||||
return;
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
@ -5,10 +5,10 @@ export const meta = {
|
||||
requireCredential: true
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
await Matching.remove({
|
||||
parentId: user._id
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -60,7 +60,7 @@ const sort: any = {
|
||||
'-attachedRemoteUsers': { attachedRemoteUsersCount: 1 },
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const q = {} as any;
|
||||
if (ps.attachedToUserOnly) q.attachedUsersCount = { $ne: 0 };
|
||||
if (ps.attachedToLocalUserOnly) q.attachedLocalUsersCount = { $ne: 0 };
|
||||
@ -80,5 +80,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res(tags);
|
||||
}));
|
||||
return tags;
|
||||
});
|
||||
|
@ -36,7 +36,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps) => {
|
||||
const hashtags = await Hashtag
|
||||
.find({
|
||||
tag: new RegExp('^' + escapeRegexp(ps.query.toLowerCase()))
|
||||
@ -48,5 +48,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||
skip: ps.offset
|
||||
});
|
||||
|
||||
res(hashtags.map(tag => tag.tag));
|
||||
}));
|
||||
return hashtags.map(tag => tag.tag);
|
||||
});
|
||||
|
@ -19,7 +19,7 @@ export const meta = {
|
||||
requireCredential: false,
|
||||
};
|
||||
|
||||
export default define(meta, () => new Promise(async (res, rej) => {
|
||||
export default define(meta, async () => {
|
||||
const instance = await fetchMeta();
|
||||
const hidedTags = instance.hidedTags.map(t => t.toLowerCase());
|
||||
|
||||
@ -49,7 +49,7 @@ export default define(meta, () => new Promise(async (res, rej) => {
|
||||
//#endregion
|
||||
|
||||
if (data.length == 0) {
|
||||
return res([]);
|
||||
return [];
|
||||
}
|
||||
|
||||
const tags: {
|
||||
@ -141,5 +141,5 @@ export default define(meta, () => new Promise(async (res, rej) => {
|
||||
usersCount: totalCounts[i].length
|
||||
}));
|
||||
|
||||
res(stats);
|
||||
}));
|
||||
return stats;
|
||||
});
|
||||
|
@ -54,7 +54,7 @@ const sort: any = {
|
||||
'-updatedAt': { updatedAt: 1 },
|
||||
};
|
||||
|
||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, me) => {
|
||||
const q = {
|
||||
tags: ps.tag,
|
||||
$and: []
|
||||
@ -79,5 +79,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||
sort: sort[ps.sort],
|
||||
});
|
||||
|
||||
res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
|
||||
}));
|
||||
return await Promise.all(users.map(user => pack(user, me, { detail: true })));
|
||||
});
|
||||
|
@ -18,13 +18,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user, app) => {
|
||||
const isSecure = user != null && app == null;
|
||||
|
||||
// Serialize
|
||||
res(await pack(user, user, {
|
||||
return await pack(user, user, {
|
||||
detail: true,
|
||||
includeHasUnreadNotes: true,
|
||||
includeSecrets: isSecure
|
||||
}));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -15,11 +15,11 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
const _token = ps.token.replace(/\s/g, '');
|
||||
|
||||
if (user.twoFactorTempSecret == null) {
|
||||
return rej('二段階認証の設定が開始されていません');
|
||||
throw new Error('二段階認証の設定が開始されていません');
|
||||
}
|
||||
|
||||
const verified = (speakeasy as any).totp.verify({
|
||||
@ -29,7 +29,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (!verified) {
|
||||
return rej('not verified');
|
||||
throw new Error('not verified');
|
||||
}
|
||||
|
||||
await User.update(user._id, {
|
||||
@ -39,5 +39,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -18,12 +18,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Compare password
|
||||
const same = await bcrypt.compare(ps.password, user.password);
|
||||
|
||||
if (!same) {
|
||||
return rej('incorrect password');
|
||||
throw new Error('incorrect password');
|
||||
}
|
||||
|
||||
// Generate user's secret key
|
||||
@ -38,17 +38,17 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
// Get the data URL of the authenticator URL
|
||||
QRCode.toDataURL(speakeasy.otpauthURL({
|
||||
const dataUrl = await QRCode.toDataURL(speakeasy.otpauthURL({
|
||||
secret: secret.base32,
|
||||
encoding: 'base32',
|
||||
label: user.username,
|
||||
issuer: config.host
|
||||
}), (err, data_url) => {
|
||||
res({
|
||||
qr: data_url,
|
||||
secret: secret.base32,
|
||||
label: user.username,
|
||||
issuer: config.host
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
|
||||
return {
|
||||
qr: dataUrl,
|
||||
secret: secret.base32,
|
||||
label: user.username,
|
||||
issuer: config.host
|
||||
};
|
||||
});
|
||||
|
@ -15,12 +15,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Compare password
|
||||
const same = await bcrypt.compare(ps.password, user.password);
|
||||
|
||||
if (!same) {
|
||||
return rej('incorrect password');
|
||||
throw new Error('incorrect password');
|
||||
}
|
||||
|
||||
await User.update(user._id, {
|
||||
@ -30,5 +30,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -26,7 +26,7 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Get tokens
|
||||
const tokens = await AccessToken
|
||||
.find({
|
||||
@ -39,7 +39,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res(await Promise.all(tokens.map(token => pack(token.appId, user, {
|
||||
return await Promise.all(tokens.map(token => pack(token.appId, user, {
|
||||
detail: true
|
||||
}))));
|
||||
}));
|
||||
})));
|
||||
});
|
||||
|
@ -19,12 +19,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Compare password
|
||||
const same = await bcrypt.compare(ps.currentPassword, user.password);
|
||||
|
||||
if (!same) {
|
||||
return rej('incorrect password');
|
||||
throw new Error('incorrect password');
|
||||
}
|
||||
|
||||
// Generate hash of password
|
||||
@ -37,5 +37,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -10,12 +10,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
await User.update({ _id: user._id }, {
|
||||
$set: {
|
||||
pendingReceivedFollowRequestsCount: 0
|
||||
}
|
||||
});
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -18,12 +18,12 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
// Compare password
|
||||
const same = await bcrypt.compare(ps.password, user.password);
|
||||
|
||||
if (!same) {
|
||||
return rej('incorrect password');
|
||||
throw new Error('incorrect password');
|
||||
}
|
||||
|
||||
await User.update({ _id: user._id }, {
|
||||
@ -49,5 +49,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
createDeleteNotesJob(user);
|
||||
createDeleteDriveFilesJob(user);
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
@ -11,8 +11,8 @@ export const meta = {
|
||||
},
|
||||
};
|
||||
|
||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
export default define(meta, async (ps, user) => {
|
||||
createExportBlockingJob(user);
|
||||
|
||||
res();
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user