forked from FoundKeyGang/FoundKey
server: refactor ApiError to store error descriptions centrally
The UUIDs are no longer used for errors and all errors should now have a descriptive message attached to them. Also, all errors should now have the proper HTTP status code for a reply instead of the generic 400 and 500 response codes. Because the errors all have more specific error codes, the "kind" of client or server is also abolished.
This commit is contained in:
parent
66d7b69377
commit
934ee82b8f
139 changed files with 768 additions and 2241 deletions
|
@ -13,7 +13,7 @@ export async function handler(endpoint: IEndpoint, ctx: Koa.Context): Promise<vo
|
||||||
: ctx.request.body;
|
: ctx.request.body;
|
||||||
|
|
||||||
const error = (e: ApiError): void => {
|
const error = (e: ApiError): void => {
|
||||||
ctx.status = e.httpStatusCode ?? 500;
|
ctx.status = e.httpStatusCode;
|
||||||
if (e.httpStatusCode === 401) {
|
if (e.httpStatusCode === 401) {
|
||||||
ctx.response.set('WWW-Authenticate', 'Bearer');
|
ctx.response.set('WWW-Authenticate', 'Bearer');
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,7 @@ export async function handler(endpoint: IEndpoint, ctx: Koa.Context): Promise<vo
|
||||||
});
|
});
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
if (e instanceof AuthenticationError) {
|
if (e instanceof AuthenticationError) {
|
||||||
error({
|
error(new ApiError('AUTHENTICATION_FAILED', e.message));
|
||||||
message: 'Authentication failed: ' + e.message,
|
|
||||||
code: 'AUTHENTICATION_FAILED',
|
|
||||||
id: 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14',
|
|
||||||
httpStatusCode: 401,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
error(new ApiError());
|
error(new ApiError());
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,29 +8,16 @@ import endpoints, { IEndpointMeta } from './endpoints.js';
|
||||||
import { ApiError } from './error.js';
|
import { ApiError } from './error.js';
|
||||||
import { apiLogger } from './logger.js';
|
import { apiLogger } from './logger.js';
|
||||||
|
|
||||||
const accessDenied = {
|
|
||||||
message: 'Access denied.',
|
|
||||||
code: 'ACCESS_DENIED',
|
|
||||||
id: '56f35758-7dd5-468b-8439-5d6fb8ec9b8e',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default async (endpoint: string, user: CacheableLocalUser | null | undefined, token: AccessToken | null | undefined, data: any, ctx?: Koa.Context) => {
|
export default async (endpoint: string, user: CacheableLocalUser | null | undefined, token: AccessToken | null | undefined, data: any, ctx?: Koa.Context) => {
|
||||||
const isSecure = user != null && token == null;
|
const isSecure = user != null && token == null;
|
||||||
const isModerator = user != null && (user.isModerator || user.isAdmin);
|
const isModerator = user != null && (user.isModerator || user.isAdmin);
|
||||||
|
|
||||||
const ep = endpoints.find(e => e.name === endpoint);
|
const ep = endpoints.find(e => e.name === endpoint);
|
||||||
|
|
||||||
if (ep == null) {
|
if (ep == null) throw new ApiError('NO_SUCH_ENDPOINT');
|
||||||
throw new ApiError({
|
|
||||||
message: 'No such endpoint.',
|
|
||||||
code: 'NO_SUCH_ENDPOINT',
|
|
||||||
id: 'f8080b67-5f9c-4eb7-8c18-7f1eeae8f709',
|
|
||||||
httpStatusCode: 404,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ep.meta.secure && !isSecure) {
|
if (ep.meta.secure && !isSecure) {
|
||||||
throw new ApiError(accessDenied);
|
throw new ApiError('ACCESS_DENIED', 'This operation can only be performed with a native token.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.limit && !isModerator) {
|
if (ep.meta.limit && !isModerator) {
|
||||||
|
@ -50,47 +37,28 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
|
||||||
|
|
||||||
// Rate limit
|
// Rate limit
|
||||||
await limiter(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor).catch(e => {
|
await limiter(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor).catch(e => {
|
||||||
throw new ApiError({
|
throw new ApiError('RATE_LIMIT_EXCEEDED');
|
||||||
message: 'Rate limit exceeded. Please try again later.',
|
|
||||||
code: 'RATE_LIMIT_EXCEEDED',
|
|
||||||
id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef',
|
|
||||||
httpStatusCode: 429,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireCredential && user == null) {
|
if (ep.meta.requireCredential && user == null) {
|
||||||
throw new ApiError({
|
throw new ApiError('AUTHENTICATION_REQUIRED');
|
||||||
message: 'Credential required.',
|
|
||||||
code: 'CREDENTIAL_REQUIRED',
|
|
||||||
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
|
|
||||||
httpStatusCode: 401,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireCredential && user!.isSuspended) {
|
if (ep.meta.requireCredential && user!.isSuspended) {
|
||||||
throw new ApiError({
|
throw new ApiError('SUSPENDED');
|
||||||
message: 'Your account has been suspended.',
|
|
||||||
code: 'YOUR_ACCOUNT_SUSPENDED',
|
|
||||||
id: 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370',
|
|
||||||
httpStatusCode: 403,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireAdmin && !user!.isAdmin) {
|
if (ep.meta.requireAdmin && !user!.isAdmin) {
|
||||||
throw new ApiError(accessDenied, { reason: 'You are not the admin.' });
|
throw new ApiError('ACCESS_DENIED', 'This operation requires administrator privileges.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireModerator && !isModerator) {
|
if (ep.meta.requireModerator && !isModerator) {
|
||||||
throw new ApiError(accessDenied, { reason: 'You are not a moderator.' });
|
throw new ApiError('ACCESS_DENIED', 'This operation requires moderator privileges.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token && ep.meta.kind && !token.permission.some(p => p === ep.meta.kind)) {
|
if (token && ep.meta.kind && !token.permission.some(p => p === ep.meta.kind)) {
|
||||||
throw new ApiError({
|
throw new ApiError('ACCESS_DENIED', 'This operation requires privileges which this token does not grant.');
|
||||||
message: 'Your app does not have the necessary permissions to use this endpoint.',
|
|
||||||
code: 'PERMISSION_DENIED',
|
|
||||||
id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cast non JSON input
|
// Cast non JSON input
|
||||||
|
@ -101,11 +69,7 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
|
||||||
try {
|
try {
|
||||||
data[k] = JSON.parse(data[k]);
|
data[k] = JSON.parse(data[k]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new ApiError({
|
throw new ApiError('INVALID_PARAM', {
|
||||||
message: 'Invalid param.',
|
|
||||||
code: 'INVALID_PARAM',
|
|
||||||
id: '0b5f1631-7c1a-41a6-b399-cce335f34d85',
|
|
||||||
}, {
|
|
||||||
param: k,
|
param: k,
|
||||||
reason: `cannot cast to ${param.type}`,
|
reason: `cannot cast to ${param.type}`,
|
||||||
});
|
});
|
||||||
|
@ -129,7 +93,7 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
|
||||||
stack: e.stack,
|
stack: e.stack,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
throw new ApiError(null, {
|
throw new ApiError('INTERNAL_ERROR', {
|
||||||
e: {
|
e: {
|
||||||
message: e.message,
|
message: e.message,
|
||||||
code: e.name,
|
code: e.name,
|
||||||
|
|
|
@ -24,25 +24,13 @@ export async function signup(opts: {
|
||||||
|
|
||||||
// Validate username
|
// Validate username
|
||||||
if (!Users.validateLocalUsername(username)) {
|
if (!Users.validateLocalUsername(username)) {
|
||||||
throw new ApiError({
|
throw new ApiError('INVALID_USERNAME');
|
||||||
message: 'This username is invalid.',
|
|
||||||
code: 'INVALID_USERNAME',
|
|
||||||
id: 'ece89f3c-d845-4d9a-850b-1735285e8cd4',
|
|
||||||
kind: 'client',
|
|
||||||
httpStatusCode: 400,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password != null && passwordHash == null) {
|
if (password != null && passwordHash == null) {
|
||||||
// Validate password
|
// Validate password
|
||||||
if (!Users.validatePassword(password)) {
|
if (!Users.validatePassword(password)) {
|
||||||
throw new ApiError({
|
throw new ApiError('INVALID_PASSWORD');
|
||||||
message: 'This password is invalid.',
|
|
||||||
code: 'INVALID_PASSWORD',
|
|
||||||
id: 'a941905b-fe7b-43e2-8ecd-50ad3a2287ab',
|
|
||||||
kind: 'client',
|
|
||||||
httpStatusCode: 400,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate hash of password
|
// Generate hash of password
|
||||||
|
@ -53,22 +41,14 @@ export async function signup(opts: {
|
||||||
// Generate secret
|
// Generate secret
|
||||||
const secret = generateUserToken();
|
const secret = generateUserToken();
|
||||||
|
|
||||||
const duplicateUsernameError = {
|
|
||||||
message: 'This username is not available.',
|
|
||||||
code: 'USED_USERNAME',
|
|
||||||
id: '7ddd595e-6860-4593-93c5-9fdbcb80cd81',
|
|
||||||
kind: 'client',
|
|
||||||
httpStatusCode: 409,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check username duplication
|
// Check username duplication
|
||||||
if (await Users.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull() })) {
|
if (await Users.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull() })) {
|
||||||
throw new ApiError(duplicateUsernameError);
|
throw new ApiError('USED_USERNAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check deleted username duplication
|
// Check deleted username duplication
|
||||||
if (await UsedUsernames.findOneBy({ username: username.toLowerCase() })) {
|
if (await UsedUsernames.findOneBy({ username: username.toLowerCase() })) {
|
||||||
throw new ApiError(duplicateUsernameError);
|
throw new ApiError('USED_USERNAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyPair = await new Promise<string[]>((res, rej) =>
|
const keyPair = await new Promise<string[]>((res, rej) =>
|
||||||
|
@ -97,7 +77,7 @@ export async function signup(opts: {
|
||||||
host: IsNull(),
|
host: IsNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist) throw new ApiError(duplicateUsernameError);
|
if (exist) throw new ApiError('USED_USERNAME');
|
||||||
|
|
||||||
account = await transactionalEntityManager.save(new User({
|
account = await transactionalEntityManager.save(new User({
|
||||||
id: genId(),
|
id: genId(),
|
||||||
|
|
|
@ -28,22 +28,16 @@ export default function <T extends IEndpointMeta, Ps extends Schema>(meta: T, pa
|
||||||
fs.unlink(file.path, () => {});
|
fs.unlink(file.path, () => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta.requireFile && file == null) return Promise.reject(new ApiError({
|
if (meta.requireFile && file == null) {
|
||||||
message: 'File required.',
|
return Promise.reject(new ApiError('FILE_REQUIRED'));
|
||||||
code: 'FILE_REQUIRED',
|
}
|
||||||
id: '4267801e-70d1-416a-b011-4ee502885d8b',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const valid = validate(params);
|
const valid = validate(params);
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
if (file) cleanup();
|
if (file) cleanup();
|
||||||
|
|
||||||
const errors = validate.errors!;
|
const errors = validate.errors!;
|
||||||
const err = new ApiError({
|
const err = new ApiError('INVALID_PARAM', {
|
||||||
message: 'Invalid param.',
|
|
||||||
code: 'INVALID_PARAM',
|
|
||||||
id: '3d81ceae-475f-4600-b2a8-2bc116157532',
|
|
||||||
}, {
|
|
||||||
param: errors[0].schemaPath,
|
param: errors[0].schemaPath,
|
||||||
reason: errors[0].message,
|
reason: errors[0].message,
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,13 +8,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_ANNOUNCEMENT'],
|
||||||
noSuchAnnouncement: {
|
|
||||||
message: 'No such announcement.',
|
|
||||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
|
||||||
id: 'ecad8040-a276-4e85-bda9-015a708d291e',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -29,7 +23,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, me) => {
|
export default define(meta, paramDef, async (ps, me) => {
|
||||||
const announcement = await Announcements.findOneBy({ id: ps.id });
|
const announcement = await Announcements.findOneBy({ id: ps.id });
|
||||||
|
|
||||||
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
|
if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');
|
||||||
|
|
||||||
await Announcements.delete(announcement.id);
|
await Announcements.delete(announcement.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,13 +8,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_ANNOUNCEMENT'],
|
||||||
noSuchAnnouncement: {
|
|
||||||
message: 'No such announcement.',
|
|
||||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
|
||||||
id: 'd3aae5a7-6372-4cb4-b61c-f511ffc2d7cc',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -32,7 +26,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, me) => {
|
export default define(meta, paramDef, async (ps, me) => {
|
||||||
const announcement = await Announcements.findOneBy({ id: ps.id });
|
const announcement = await Announcements.findOneBy({ id: ps.id });
|
||||||
|
|
||||||
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
|
if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');
|
||||||
|
|
||||||
await Announcements.update(announcement.id, {
|
await Announcements.update(announcement.id, {
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
|
|
|
@ -8,13 +8,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -180,9 +174,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -34,7 +28,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, me) => {
|
export default define(meta, paramDef, async (ps, me) => {
|
||||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||||
|
|
||||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
|
|
||||||
const name = file.name.split('.')[0].match(/^[a-z0-9_]+$/) ? file.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`;
|
const name = file.name.split('.')[0].match(/^[a-z0-9_]+$/) ? file.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`;
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_EMOJI', 'INTERNAL_ERROR'],
|
||||||
noSuchEmoji: {
|
|
||||||
message: 'No such emoji.',
|
|
||||||
code: 'NO_SUCH_EMOJI',
|
|
||||||
id: 'e2785b66-dca3-4087-9cac-b93c541cc425',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -46,9 +40,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, me) => {
|
export default define(meta, paramDef, async (ps, me) => {
|
||||||
const emoji = await Emojis.findOneBy({ id: ps.emojiId });
|
const emoji = await Emojis.findOneBy({ id: ps.emojiId });
|
||||||
|
|
||||||
if (emoji == null) {
|
if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');
|
||||||
throw new ApiError(meta.errors.noSuchEmoji);
|
|
||||||
}
|
|
||||||
|
|
||||||
let driveFile: DriveFile;
|
let driveFile: DriveFile;
|
||||||
|
|
||||||
|
@ -56,7 +48,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
// Create file
|
// Create file
|
||||||
driveFile = await uploadFromUrl({ url: emoji.originalUrl, user: null, force: true });
|
driveFile = await uploadFromUrl({ url: emoji.originalUrl, user: null, force: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new ApiError();
|
throw new ApiError('INTERNAL_ERROR', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
const copied = await Emojis.insert({
|
const copied = await Emojis.insert({
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_EMOJI'],
|
||||||
noSuchEmoji: {
|
|
||||||
message: 'No such emoji.',
|
|
||||||
code: 'NO_SUCH_EMOJI',
|
|
||||||
id: 'be83669b-773a-44b7-b1f8-e5e5170ac3c2',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -31,7 +25,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, me) => {
|
export default define(meta, paramDef, async (ps, me) => {
|
||||||
const emoji = await Emojis.findOneBy({ id: ps.id });
|
const emoji = await Emojis.findOneBy({ id: ps.id });
|
||||||
|
|
||||||
if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
|
if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');
|
||||||
|
|
||||||
await Emojis.delete(emoji.id);
|
await Emojis.delete(emoji.id);
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_EMOJI'],
|
||||||
noSuchEmoji: {
|
|
||||||
message: 'No such emoji.',
|
|
||||||
code: 'NO_SUCH_EMOJI',
|
|
||||||
id: '684dec9d-a8c2-4364-9aa8-456c49cb1dc8',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -39,7 +33,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps) => {
|
export default define(meta, paramDef, async (ps) => {
|
||||||
const emoji = await Emojis.findOneBy({ id: ps.id });
|
const emoji = await Emojis.findOneBy({ id: ps.id });
|
||||||
|
|
||||||
if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
|
if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');
|
||||||
|
|
||||||
await Emojis.update(emoji.id, {
|
await Emojis.update(emoji.id, {
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['INVALID_URL'],
|
||||||
invalidUrl: {
|
|
||||||
message: 'Invalid URL',
|
|
||||||
code: 'INVALID_URL',
|
|
||||||
id: 'fb8c92d3-d4e5-44e7-b3d4-800d5cef8b2c',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -58,8 +52,8 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
try {
|
try {
|
||||||
if (new URL(ps.inbox).protocol !== 'https:') throw new Error('https only');
|
if (new URL(ps.inbox).protocol !== 'https:') throw new Error('https only');
|
||||||
} catch {
|
} catch (e) {
|
||||||
throw new ApiError(meta.errors.invalidUrl);
|
throw new ApiError('INVALID_URL', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await addRelay(ps.inbox);
|
return await addRelay(ps.inbox);
|
||||||
|
|
|
@ -11,19 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER_LIST', 'NO_SUCH_GROUP'],
|
||||||
noSuchUserList: {
|
|
||||||
message: 'No such user list.',
|
|
||||||
code: 'NO_SUCH_USER_LIST',
|
|
||||||
id: '95063e93-a283-4b8b-9aa5-bcdb8df69a7f',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchUserGroup: {
|
|
||||||
message: 'No such user group.',
|
|
||||||
code: 'NO_SUCH_USER_GROUP',
|
|
||||||
id: 'aa3c0b9a-8cae-47c0-92ac-202ce5906682',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -71,18 +59,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (userList == null) {
|
if (userList == null) throw new ApiError('NO_SUCH_USER_LIST');
|
||||||
throw new ApiError(meta.errors.noSuchUserList);
|
|
||||||
}
|
|
||||||
} else if (ps.src === 'group' && ps.userGroupId) {
|
} else if (ps.src === 'group' && ps.userGroupId) {
|
||||||
userGroupJoining = await UserGroupJoinings.findOneBy({
|
userGroupJoining = await UserGroupJoinings.findOneBy({
|
||||||
userGroupId: ps.userGroupId,
|
userGroupId: ps.userGroupId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (userGroupJoining == null) {
|
if (userGroupJoining == null) throw new ApiError('NO_SUCH_GROUP');
|
||||||
throw new ApiError(meta.errors.noSuchUserGroup);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const antenna = await Antennas.insert({
|
const antenna = await Antennas.insert({
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_ANTENNA'],
|
||||||
noSuchAntenna: {
|
|
||||||
message: 'No such antenna.',
|
|
||||||
code: 'NO_SUCH_ANTENNA',
|
|
||||||
id: 'b34dcf9d-348f-44bb-99d0-6c9314cfe2df',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (antenna == null) {
|
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||||
throw new ApiError(meta.errors.noSuchAntenna);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Antennas.delete(antenna.id);
|
await Antennas.delete(antenna.id);
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'read:account',
|
kind: 'read:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_ANTENNA'],
|
||||||
noSuchAntenna: {
|
|
||||||
message: 'No such antenna.',
|
|
||||||
code: 'NO_SUCH_ANTENNA',
|
|
||||||
id: '850926e0-fd3b-49b6-b69a-b28a5dbd82fe',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
@ -53,9 +47,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (antenna == null) {
|
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||||
throw new ApiError(meta.errors.noSuchAntenna);
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = makePaginationQuery(Notes.createQueryBuilder('note'),
|
const query = makePaginationQuery(Notes.createQueryBuilder('note'),
|
||||||
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'read:account',
|
kind: 'read:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_ANTENNA'],
|
||||||
noSuchAntenna: {
|
|
||||||
message: 'No such antenna.',
|
|
||||||
code: 'NO_SUCH_ANTENNA',
|
|
||||||
id: 'c06569fb-b025-4f23-b22d-1fcd20d2816b',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -40,9 +34,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
userId: me.id,
|
userId: me.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (antenna == null) {
|
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||||
throw new ApiError(meta.errors.noSuchAntenna);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Antennas.pack(antenna);
|
return await Antennas.pack(antenna);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_ANTENNA', 'NO_SUCH_USER_LIST', 'NO_SUCH_GROUP'],
|
||||||
noSuchAntenna: {
|
|
||||||
message: 'No such antenna.',
|
|
||||||
code: 'NO_SUCH_ANTENNA',
|
|
||||||
id: '10c673ac-8852-48eb-aa1f-f5b67f069290',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchUserList: {
|
|
||||||
message: 'No such user list.',
|
|
||||||
code: 'NO_SUCH_USER_LIST',
|
|
||||||
id: '1c6b35c9-943e-48c2-81e4-2844989407f7',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchUserGroup: {
|
|
||||||
message: 'No such user group.',
|
|
||||||
code: 'NO_SUCH_USER_GROUP',
|
|
||||||
id: '109ed789-b6eb-456e-b8a9-6059d567d385',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -74,9 +56,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (antenna == null) {
|
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||||
throw new ApiError(meta.errors.noSuchAntenna);
|
|
||||||
}
|
|
||||||
|
|
||||||
let userList;
|
let userList;
|
||||||
let userGroupJoining;
|
let userGroupJoining;
|
||||||
|
@ -87,18 +67,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (userList == null) {
|
if (userList == null) throw new ApiError('NO_SUCH_USER_LIST');
|
||||||
throw new ApiError(meta.errors.noSuchUserList);
|
|
||||||
}
|
|
||||||
} else if (ps.src === 'group' && ps.userGroupId) {
|
} else if (ps.src === 'group' && ps.userGroupId) {
|
||||||
userGroupJoining = await UserGroupJoinings.findOneBy({
|
userGroupJoining = await UserGroupJoinings.findOneBy({
|
||||||
userGroupId: ps.userGroupId,
|
userGroupId: ps.userGroupId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (userGroupJoining == null) {
|
if (userGroupJoining == null) throw new ApiError('NO_SUCH_GROUP');
|
||||||
throw new ApiError(meta.errors.noSuchUserGroup);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Antennas.update(antenna.id, {
|
await Antennas.update(antenna.id, {
|
||||||
|
|
|
@ -12,9 +12,6 @@ export const meta = {
|
||||||
max: 30,
|
max: 30,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
|
|
|
@ -24,13 +24,7 @@ export const meta = {
|
||||||
max: 30,
|
max: 30,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_OBJECT'],
|
||||||
noSuchObject: {
|
|
||||||
message: 'No such object.',
|
|
||||||
code: 'NO_SUCH_OBJECT',
|
|
||||||
id: 'dc94d745-1262-4e63-a17d-fecaa57efc82',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
|
@ -83,7 +77,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
if (object) {
|
if (object) {
|
||||||
return object;
|
return object;
|
||||||
} else {
|
} else {
|
||||||
throw new ApiError(meta.errors.noSuchObject);
|
throw new ApiError('NO_SUCH_OBJECT');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,7 @@ import { ApiError } from '../../error.js';
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['app'],
|
tags: ['app'],
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_APP'],
|
||||||
noSuchApp: {
|
|
||||||
message: 'No such app.',
|
|
||||||
code: 'NO_SUCH_APP',
|
|
||||||
id: 'dce83913-2dc6-4093-8a7b-71dbb11718a3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -33,14 +27,12 @@ export default define(meta, paramDef, async (ps, user, token) => {
|
||||||
const isSecure = user != null && token == null;
|
const isSecure = user != null && token == null;
|
||||||
|
|
||||||
// Lookup app
|
// Lookup app
|
||||||
const ap = await Apps.findOneBy({ id: ps.appId });
|
const app = await Apps.findOneBy({ id: ps.appId });
|
||||||
|
|
||||||
if (ap == null) {
|
if (app == null) throw new ApiError('NO_SUCH_APP');
|
||||||
throw new ApiError(meta.errors.noSuchApp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Apps.pack(ap, user, {
|
return await Apps.pack(app, user, {
|
||||||
detail: true,
|
detail: true,
|
||||||
includeSecret: isSecure && (ap.userId === user!.id),
|
includeSecret: isSecure && (app.userId === user!.id),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,13 +12,7 @@ export const meta = {
|
||||||
|
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_SESSION'],
|
||||||
noSuchSession: {
|
|
||||||
message: 'No such session.',
|
|
||||||
code: 'NO_SUCH_SESSION',
|
|
||||||
id: '9c72d8de-391a-43c1-9d06-08d29efde8df',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -35,9 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const session = await AuthSessions
|
const session = await AuthSessions
|
||||||
.findOneBy({ token: ps.token });
|
.findOneBy({ token: ps.token });
|
||||||
|
|
||||||
if (session == null) {
|
if (session == null) throw new ApiError('NO_SUCH_SESSION');
|
||||||
throw new ApiError(meta.errors.noSuchSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate access token
|
// Generate access token
|
||||||
const accessToken = secureRndstr(32, true);
|
const accessToken = secureRndstr(32, true);
|
||||||
|
|
|
@ -26,13 +26,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_APP'],
|
||||||
noSuchApp: {
|
|
||||||
message: 'No such app.',
|
|
||||||
code: 'NO_SUCH_APP',
|
|
||||||
id: '92f93e63-428e-4f2f-a5a4-39e1407fe998',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -51,7 +45,7 @@ export default define(meta, paramDef, async (ps) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw new ApiError(meta.errors.noSuchApp);
|
throw new ApiError('NO_SUCH_APP');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate token
|
// Generate token
|
||||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_SESSION'],
|
||||||
noSuchSession: {
|
|
||||||
message: 'No such session.',
|
|
||||||
code: 'NO_SUCH_SESSION',
|
|
||||||
id: 'bd72c97d-eba7-4adb-a467-f171b8847250',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -52,9 +46,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
token: ps.token,
|
token: ps.token,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (session == null) {
|
if (session == null) throw new ApiError('NO_SUCH_SESSION');
|
||||||
throw new ApiError(meta.errors.noSuchSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await AuthSessions.pack(session, user);
|
return await AuthSessions.pack(session, user);
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,25 +24,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_APP', 'NO_SUCH_SESSION', 'PENDING_SESSION'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -61,9 +43,7 @@ export default define(meta, paramDef, async (ps) => {
|
||||||
secret: ps.appSecret,
|
secret: ps.appSecret,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (app == null) {
|
if (app == null) throw new ApiError('NO_SUCH_APP');
|
||||||
throw new ApiError(meta.errors.noSuchApp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch token
|
// Fetch token
|
||||||
const session = await AuthSessions.findOneBy({
|
const session = await AuthSessions.findOneBy({
|
||||||
|
@ -71,13 +51,9 @@ export default define(meta, paramDef, async (ps) => {
|
||||||
appId: app.id,
|
appId: app.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (session == null) {
|
if (session == null) throw new ApiError('NO_SUCH_SESSION');
|
||||||
throw new ApiError(meta.errors.noSuchSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session.userId == null) {
|
if (session.userId == null) throw new ApiError('PENDING_SESSION');
|
||||||
throw new ApiError(meta.errors.pendingSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup access token
|
// Lookup access token
|
||||||
const accessToken = await AccessTokens.findOneByOrFail({
|
const accessToken = await AccessTokens.findOneByOrFail({
|
||||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:blocks',
|
kind: 'write:blocks',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER', 'BLOCKEE_IS_YOURSELF', 'ALREADY_BLOCKING'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const blocker = await Users.findOneByOrFail({ id: user.id });
|
const blocker = await Users.findOneByOrFail({ id: user.id });
|
||||||
|
|
||||||
// 自分自身
|
// 自分自身
|
||||||
if (user.id === ps.userId) {
|
if (user.id === ps.userId) throw new ApiError('BLOCKEE_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.blockeeIsYourself);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get blockee
|
// Get blockee
|
||||||
const blockee = await getUser(ps.userId).catch(e => {
|
const blockee = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
blockeeId: blockee.id,
|
blockeeId: blockee.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist != null) {
|
if (exist != null) throw new ApiError('ALREADY_BLOCKING');
|
||||||
throw new ApiError(meta.errors.alreadyBlocking);
|
|
||||||
}
|
|
||||||
|
|
||||||
await create(blocker, blockee);
|
await create(blocker, blockee);
|
||||||
|
|
||||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:blocks',
|
kind: 'write:blocks',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER', 'BLOCKEE_IS_YOURSELF', 'NOT_BLOCKING'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -54,16 +36,14 @@ export const paramDef = {
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const blocker = await Users.findOneByOrFail({ id: user.id });
|
|
||||||
|
|
||||||
// Check if the blockee is yourself
|
// Check if the blockee is yourself
|
||||||
if (user.id === ps.userId) {
|
if (user.id === ps.userId) throw new ApiError('BLOCKEE_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.blockeeIsYourself);
|
|
||||||
}
|
const blocker = await Users.findOneByOrFail({ id: user.id });
|
||||||
|
|
||||||
// Get blockee
|
// Get blockee
|
||||||
const blockee = await getUser(ps.userId).catch(e => {
|
const blockee = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
blockeeId: blockee.id,
|
blockeeId: blockee.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) throw new ApiError('NOT_BLOCKING');
|
||||||
throw new ApiError(meta.errors.notBlocking);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete blocking
|
// Delete blocking
|
||||||
await deleteBlocking(blocker, blockee);
|
await deleteBlocking(blocker, blockee);
|
||||||
|
|
|
@ -17,13 +17,7 @@ export const meta = {
|
||||||
ref: 'Channel',
|
ref: 'Channel',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -45,9 +39,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (banner == null) {
|
if (banner == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = await Channels.insert({
|
const channel = await Channels.insert({
|
||||||
|
|
|
@ -11,13 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:channels',
|
kind: 'write:channels',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CHANNEL'],
|
||||||
noSuchChannel: {
|
|
||||||
message: 'No such channel.',
|
|
||||||
code: 'NO_SUCH_CHANNEL',
|
|
||||||
id: 'c0031718-d573-4e85-928e-10039f1fbb68',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
id: ps.channelId,
|
id: ps.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (channel == null) {
|
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||||
throw new ApiError(meta.errors.noSuchChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
await ChannelFollowings.insert({
|
await ChannelFollowings.insert({
|
||||||
id: genId(),
|
id: genId(),
|
||||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
||||||
ref: 'Channel',
|
ref: 'Channel',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CHANNEL'],
|
||||||
noSuchChannel: {
|
|
||||||
message: 'No such channel.',
|
|
||||||
code: 'NO_SUCH_CHANNEL',
|
|
||||||
id: '6f6c314b-7486-4897-8966-c04a66a02923',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -36,9 +30,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
id: ps.channelId,
|
id: ps.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (channel == null) {
|
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||||
throw new ApiError(meta.errors.noSuchChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Channels.pack(channel, me);
|
return await Channels.pack(channel, me);
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,13 +19,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CHANNEL'],
|
||||||
noSuchChannel: {
|
|
||||||
message: 'No such channel.',
|
|
||||||
code: 'NO_SUCH_CHANNEL',
|
|
||||||
id: '4d0eeeba-a02c-4c3c-9966-ef60d38d2e7f',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -47,9 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
id: ps.channelId,
|
id: ps.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (channel == null) {
|
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||||
throw new ApiError(meta.errors.noSuchChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Construct query
|
//#region Construct query
|
||||||
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:channels',
|
kind: 'write:channels',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CHANNEL'],
|
||||||
noSuchChannel: {
|
|
||||||
message: 'No such channel.',
|
|
||||||
code: 'NO_SUCH_CHANNEL',
|
|
||||||
id: '19959ee9-0153-4c51-bbd9-a98c49dc59d6',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
id: ps.channelId,
|
id: ps.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (channel == null) {
|
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||||
throw new ApiError(meta.errors.noSuchChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
await ChannelFollowings.delete({
|
await ChannelFollowings.delete({
|
||||||
followerId: user.id,
|
followerId: user.id,
|
||||||
|
|
|
@ -15,25 +15,7 @@ export const meta = {
|
||||||
ref: 'Channel',
|
ref: 'Channel',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['ACCESS_DENIED', 'NO_SUCH_CHANNEL', 'NO_SUCH_FILE'],
|
||||||
noSuchChannel: {
|
|
||||||
message: 'No such channel.',
|
|
||||||
code: 'NO_SUCH_CHANNEL',
|
|
||||||
id: 'f9c5467f-d492-4c3c-9a8d-a70dacc86512',
|
|
||||||
},
|
|
||||||
|
|
||||||
accessDenied: {
|
|
||||||
message: 'You do not have edit privilege of the channel.',
|
|
||||||
code: 'ACCESS_DENIED',
|
|
||||||
id: '1fb7cb09-d46a-4fdf-b8df-057788cce513',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'e86c14a4-0da2-4032-8df3-e737a04c7f3b',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -53,13 +35,9 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
id: ps.channelId,
|
id: ps.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (channel == null) {
|
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||||
throw new ApiError(meta.errors.noSuchChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel.userId !== me.id) {
|
if (channel.userId !== me.id) throw new ApiError('ACCESS_DENIED', 'You are not the owner of this channel.');
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint:disable-next-line:no-unnecessary-initializer
|
// eslint:disable-next-line:no-unnecessary-initializer
|
||||||
let banner = undefined;
|
let banner = undefined;
|
||||||
|
@ -69,9 +47,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
userId: me.id,
|
userId: me.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (banner == null) {
|
if (banner == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
} else if (ps.bannerId === null) {
|
} else if (ps.bannerId === null) {
|
||||||
banner = null;
|
banner = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,25 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['ALREADY_CLIPPED', 'NO_SUCH_CLIP', 'NO_SUCH_NOTE'],
|
||||||
noSuchClip: {
|
|
||||||
message: 'No such clip.',
|
|
||||||
code: 'NO_SUCH_CLIP',
|
|
||||||
id: 'd6e76cc0-a1b5-4c7c-a287-73fa9c716dcf',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: 'fc8c0b49-c7a3-4664-a0a6-b418d386bb8b',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyClipped: {
|
|
||||||
message: 'The note has already been clipped.',
|
|
||||||
code: 'ALREADY_CLIPPED',
|
|
||||||
id: '734806c4-542c-463a-9311-15c512803965',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -48,12 +30,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (clip == null) {
|
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,9 +42,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
clipId: clip.id,
|
clipId: clip.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist != null) {
|
if (exist != null) throw new ApiError('ALREADY_CLIPPED');
|
||||||
throw new ApiError(meta.errors.alreadyClipped);
|
|
||||||
}
|
|
||||||
|
|
||||||
await ClipNotes.insert({
|
await ClipNotes.insert({
|
||||||
id: genId(),
|
id: genId(),
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CLIP'],
|
||||||
noSuchClip: {
|
|
||||||
message: 'No such clip.',
|
|
||||||
code: 'NO_SUCH_CLIP',
|
|
||||||
id: '70ca08ba-6865-4630-b6fb-8494759aa754',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (clip == null) {
|
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Clips.delete(clip.id);
|
await Clips.delete(clip.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'read:account',
|
kind: 'read:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CLIP'],
|
||||||
noSuchClip: {
|
|
||||||
message: 'No such clip.',
|
|
||||||
code: 'NO_SUCH_CLIP',
|
|
||||||
id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
@ -49,12 +43,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
id: ps.clipId,
|
id: ps.clipId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (clip == null) {
|
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clip.isPublic && (user == null || (clip.userId !== user.id))) {
|
if (!clip.isPublic && (user == null || (clip.userId !== user.id))) {
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
throw new ApiError('NO_SUCH_CLIP');
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
|
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
|
||||||
|
|
|
@ -10,26 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CLIP', 'NO_SUCH_NOTE', 'NOT_CLIPPED'],
|
||||||
noSuchClip: {
|
|
||||||
message: 'No such clip.',
|
|
||||||
code: 'NO_SUCH_CLIP',
|
|
||||||
id: 'b80525c6-97f7-49d7-a42d-ebccd49cfd52',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: 'aff017de-190e-434b-893e-33a9ff5049d8',
|
|
||||||
},
|
|
||||||
|
|
||||||
notClipped: {
|
|
||||||
message: 'That note is not added to this clip.',
|
|
||||||
code: 'NOT_CLIPPED',
|
|
||||||
id: '6b20c697-6e51-4120-b340-0e47899c7a20',
|
|
||||||
httpStatusCode: 409,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -48,12 +29,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (clip == null) {
|
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
const note = await getNote(ps.noteId).catch(e => {
|
const note = await getNote(ps.noteId).catch(e => {
|
||||||
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,7 +41,5 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
clipId: clip.id,
|
clipId: clip.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (affected === 0) {
|
if (affected === 0) throw new ApiError('NOT_CLIPPED');
|
||||||
throw new ApiError(meta.errors.notClipped);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'read:account',
|
kind: 'read:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CLIP'],
|
||||||
noSuchClip: {
|
|
||||||
message: 'No such clip.',
|
|
||||||
code: 'NO_SUCH_CLIP',
|
|
||||||
id: 'c3c5fe33-d62c-44d2-9ea5-d997703f5c20',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -39,12 +33,10 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
id: ps.clipId,
|
id: ps.clipId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (clip == null) {
|
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clip.isPublic && (me == null || (clip.userId !== me.id))) {
|
if (!clip.isPublic && (me == null || (clip.userId !== me.id))) {
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
throw new ApiError('NO_SUCH_CLIP');
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Clips.pack(clip);
|
return await Clips.pack(clip);
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_CLIP'],
|
||||||
noSuchClip: {
|
|
||||||
message: 'No such clip.',
|
|
||||||
code: 'NO_SUCH_CLIP',
|
|
||||||
id: 'b4d92d70-b216-46fa-9a3f-a8c811699257',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -43,9 +37,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (clip == null) {
|
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||||
throw new ApiError(meta.errors.noSuchClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Clips.update(clip.id, {
|
await Clips.update(clip.id, {
|
||||||
name: ps.name,
|
name: ps.name,
|
||||||
|
|
|
@ -21,13 +21,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'c118ece3-2e4b-4296-99d1-51756e32d232',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -46,9 +40,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
const notes = await Notes.createQueryBuilder('note')
|
const notes = await Notes.createQueryBuilder('note')
|
||||||
.where(':file = ANY(note.fileIds)', { file: file.id })
|
.where(':file = ANY(note.fileIds)', { file: file.id })
|
||||||
|
|
|
@ -28,13 +28,7 @@ export const meta = {
|
||||||
ref: 'DriveFile',
|
ref: 'DriveFile',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['INTERNAL_ERROR', 'INVALID_FILE_NAME'],
|
||||||
invalidFileName: {
|
|
||||||
message: 'Invalid file name.',
|
|
||||||
code: 'INVALID_FILE_NAME',
|
|
||||||
id: 'f449b209-0c60-4e51-84d5-29486263bfd4',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -60,7 +54,7 @@ export default define(meta, paramDef, async (ps, user, _, file, cleanup) => {
|
||||||
} else if (name === 'blob') {
|
} else if (name === 'blob') {
|
||||||
name = null;
|
name = null;
|
||||||
} else if (!DriveFiles.validateFileName(name)) {
|
} else if (!DriveFiles.validateFileName(name)) {
|
||||||
throw new ApiError(meta.errors.invalidFileName);
|
throw new ApiError('INVALID_FILE_NAME');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
name = null;
|
name = null;
|
||||||
|
@ -74,7 +68,7 @@ export default define(meta, paramDef, async (ps, user, _, file, cleanup) => {
|
||||||
if (e instanceof Error || typeof e === 'string') {
|
if (e instanceof Error || typeof e === 'string') {
|
||||||
apiLogger.error(e);
|
apiLogger.error(e);
|
||||||
}
|
}
|
||||||
throw new ApiError();
|
throw new ApiError('INTERNAL_ERROR');
|
||||||
} finally {
|
} finally {
|
||||||
cleanup!();
|
cleanup!();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,19 +13,7 @@ export const meta = {
|
||||||
|
|
||||||
description: 'Delete an existing drive file.',
|
description: 'Delete an existing drive file.',
|
||||||
|
|
||||||
errors: {
|
errors: ['ACCESS_DENIED', 'NO_SUCH_FILE'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -40,12 +28,10 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
|
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
throw new ApiError('ACCESS_DENIED');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
|
|
|
@ -18,19 +18,7 @@ export const meta = {
|
||||||
ref: 'DriveFile',
|
ref: 'DriveFile',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['ACCESS_DENIED', 'NO_SUCH_FILE'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -69,12 +57,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
|
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
throw new ApiError('ACCESS_DENIED');
|
||||||
}
|
}
|
||||||
|
|
||||||
return await DriveFiles.pack(file, {
|
return await DriveFiles.pack(file, {
|
||||||
|
|
|
@ -12,31 +12,7 @@ export const meta = {
|
||||||
|
|
||||||
description: 'Update the properties of a drive file.',
|
description: 'Update the properties of a drive file.',
|
||||||
|
|
||||||
errors: {
|
errors: ['ACCESS_DENIED', 'INVALID_FILE_NAME', 'NO_SUCH_FILE', 'NO_SUCH_FOLDER'],
|
||||||
invalidFileName: {
|
|
||||||
message: 'Invalid file name.',
|
|
||||||
code: 'INVALID_FILE_NAME',
|
|
||||||
id: '395e7156-f9f0-475e-af89-53c3c23080c2',
|
|
||||||
},
|
|
||||||
|
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -61,17 +37,15 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
|
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
throw new ApiError('ACCESS_DENIED');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.name) file.name = ps.name;
|
if (ps.name) file.name = ps.name;
|
||||||
if (!DriveFiles.validateFileName(file.name)) {
|
if (!DriveFiles.validateFileName(file.name)) {
|
||||||
throw new ApiError(meta.errors.invalidFileName);
|
throw new ApiError('INVALID_FILE_NAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.comment !== undefined) file.comment = ps.comment;
|
if (ps.comment !== undefined) file.comment = ps.comment;
|
||||||
|
@ -87,9 +61,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (folder == null) {
|
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||||
throw new ApiError(meta.errors.noSuchFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.folderId = folder.id;
|
file.folderId = folder.id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:drive',
|
kind: 'write:drive',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_FOLDER'],
|
||||||
noSuchFolder: {
|
|
||||||
message: 'No such folder.',
|
|
||||||
code: 'NO_SUCH_FOLDER',
|
|
||||||
id: '53326628-a00d-40a6-a3cd-8975105c0f95',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object' as const,
|
type: 'object' as const,
|
||||||
|
@ -46,9 +40,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (parent == null) {
|
if (parent == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||||
throw new ApiError(meta.errors.noSuchFolder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create folder
|
// Create folder
|
||||||
|
|
|
@ -10,19 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:drive',
|
kind: 'write:drive',
|
||||||
|
|
||||||
errors: {
|
errors: ['HAS_CHILD_FILES_OR_FOLDERS', 'NO_SUCH_FOLDER'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -41,9 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (folder == null) {
|
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||||
throw new ApiError(meta.errors.noSuchFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [childFoldersCount, childFilesCount] = await Promise.all([
|
const [childFoldersCount, childFilesCount] = await Promise.all([
|
||||||
DriveFolders.countBy({ parentId: folder.id }),
|
DriveFolders.countBy({ parentId: folder.id }),
|
||||||
|
@ -51,7 +37,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (childFoldersCount !== 0 || childFilesCount !== 0) {
|
if (childFoldersCount !== 0 || childFilesCount !== 0) {
|
||||||
throw new ApiError(meta.errors.hasChildFilesOrFolders);
|
throw new ApiError('HAS_CHILD_FILES_OR_FOLDERS');
|
||||||
}
|
}
|
||||||
|
|
||||||
await DriveFolders.delete(folder.id);
|
await DriveFolders.delete(folder.id);
|
||||||
|
|
|
@ -15,13 +15,7 @@ export const meta = {
|
||||||
ref: 'DriveFolder',
|
ref: 'DriveFolder',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_FOLDER'],
|
||||||
noSuchFolder: {
|
|
||||||
message: 'No such folder.',
|
|
||||||
code: 'NO_SUCH_FOLDER',
|
|
||||||
id: 'd74ab9eb-bb09-4bba-bf24-fb58f761e1e9',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -40,9 +34,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (folder == null) {
|
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||||
throw new ApiError(meta.errors.noSuchFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await DriveFolders.pack(folder, {
|
return await DriveFolders.pack(folder, {
|
||||||
detail: true,
|
detail: true,
|
||||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:drive',
|
kind: 'write:drive',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_FOLDER', 'NO_SUCH_PARENT_FOLDER', 'RECURSIVE_FOLDER'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -55,15 +37,13 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (folder == null) {
|
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||||
throw new ApiError(meta.errors.noSuchFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.name) folder.name = ps.name;
|
if (ps.name) folder.name = ps.name;
|
||||||
|
|
||||||
if (ps.parentId !== undefined) {
|
if (ps.parentId !== undefined) {
|
||||||
if (ps.parentId === folder.id) {
|
if (ps.parentId === folder.id) {
|
||||||
throw new ApiError(meta.errors.recursiveNesting);
|
throw new ApiError('RECURSIVE_FOLDER');
|
||||||
} else if (ps.parentId === null) {
|
} else if (ps.parentId === null) {
|
||||||
folder.parentId = null;
|
folder.parentId = null;
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (parent == null) {
|
if (parent == null) throw new ApiError('NO_SUCH_PARENT_FOLDER');
|
||||||
throw new ApiError(meta.errors.noSuchParentFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the circular reference will occur
|
// Check if the circular reference will occur
|
||||||
async function checkCircle(folderId: string): Promise<boolean> {
|
async function checkCircle(folderId: string): Promise<boolean> {
|
||||||
|
@ -95,7 +73,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
if (parent.parentId !== null) {
|
if (parent.parentId !== null) {
|
||||||
if (await checkCircle(parent.parentId)) {
|
if (await checkCircle(parent.parentId)) {
|
||||||
throw new ApiError(meta.errors.recursiveNesting);
|
throw new ApiError('RECURSIVE_FOLDER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,37 +18,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:following',
|
kind: 'write:following',
|
||||||
|
|
||||||
errors: {
|
errors: ['ALREADY_FOLLOWING', 'BLOCKING', 'BLOCKED', 'FOLLOWEE_IS_YOURSELF', 'NO_SUCH_USER'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -70,13 +40,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const follower = user;
|
const follower = user;
|
||||||
|
|
||||||
// 自分自身
|
// 自分自身
|
||||||
if (user.id === ps.userId) {
|
if (user.id === ps.userId) throw new ApiError('FOLLOWEE_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.followeeIsYourself);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get followee
|
// Get followee
|
||||||
const followee = await getUser(ps.userId).catch(e => {
|
const followee = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -86,16 +54,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
followeeId: followee.id,
|
followeeId: followee.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist != null) {
|
if (exist != null) throw new ApiError('ALREADY_FOLLOWING');
|
||||||
throw new ApiError(meta.errors.alreadyFollowing);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await create(follower, followee);
|
await create(follower, followee);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof IdentifiableError) {
|
if (e instanceof IdentifiableError) {
|
||||||
if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking);
|
if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError('BLOCKING');
|
||||||
if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked);
|
if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError('BLOCKED');
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:following',
|
kind: 'write:following',
|
||||||
|
|
||||||
errors: {
|
errors: ['FOLLOWEE_IS_YOURSELF', 'NO_SUCH_USER', 'NOT_FOLLOWING'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const follower = user;
|
const follower = user;
|
||||||
|
|
||||||
// Check if the followee is yourself
|
// Check if the followee is yourself
|
||||||
if (user.id === ps.userId) {
|
if (user.id === ps.userId) throw new ApiError('FOLLOWEE_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.followeeIsYourself);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get followee
|
// Get followee
|
||||||
const followee = await getUser(ps.userId).catch(e => {
|
const followee = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
followeeId: followee.id,
|
followeeId: followee.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) throw new ApiError('NOT_FOLLOWING');
|
||||||
throw new ApiError(meta.errors.notFollowing);
|
|
||||||
}
|
|
||||||
|
|
||||||
await deleteFollowing(follower, followee);
|
await deleteFollowing(follower, followee);
|
||||||
|
|
||||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:following',
|
kind: 'write:following',
|
||||||
|
|
||||||
errors: {
|
errors: ['FOLLOWER_IS_YOURSELF', 'NO_SUCH_USER', 'NOT_FOLLOWING'],
|
||||||
noSuchUser: {
|
|
||||||
message: 'No such user.',
|
|
||||||
code: 'NO_SUCH_USER',
|
|
||||||
id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8',
|
|
||||||
},
|
|
||||||
|
|
||||||
followerIsYourself: {
|
|
||||||
message: 'Follower is yourself.',
|
|
||||||
code: 'FOLLOWER_IS_YOURSELF',
|
|
||||||
id: '07dc03b9-03da-422d-885b-438313707662',
|
|
||||||
},
|
|
||||||
|
|
||||||
notFollowing: {
|
|
||||||
message: 'The other use is not following you.',
|
|
||||||
code: 'NOT_FOLLOWING',
|
|
||||||
id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const followee = user;
|
const followee = user;
|
||||||
|
|
||||||
// Check if the follower is yourself
|
// Check if the follower is yourself
|
||||||
if (user.id === ps.userId) {
|
if (user.id === ps.userId) throw new ApiError('FOLLOWER_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.followerIsYourself);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get follower
|
// Get follower
|
||||||
const follower = await getUser(ps.userId).catch(e => {
|
const follower = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
followeeId: followee.id,
|
followeeId: followee.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) throw new ApiError('NOT_FOLLOWING');
|
||||||
throw new ApiError(meta.errors.notFollowing);
|
|
||||||
}
|
|
||||||
|
|
||||||
await deleteFollowing(follower, followee);
|
await deleteFollowing(follower, followee);
|
||||||
|
|
||||||
|
|
|
@ -10,18 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:following',
|
kind: 'write:following',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER', 'NO_SUCH_FOLLOW_REQUEST'],
|
||||||
noSuchUser: {
|
|
||||||
message: 'No such user.',
|
|
||||||
code: 'NO_SUCH_USER',
|
|
||||||
id: '66ce1645-d66c-46bb-8b79-96739af885bd',
|
|
||||||
},
|
|
||||||
noFollowRequest: {
|
|
||||||
message: 'No follow request.',
|
|
||||||
code: 'NO_FOLLOW_REQUEST',
|
|
||||||
id: 'bcde4f8b-0913-4614-8881-614e522fb041',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -36,12 +25,12 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Fetch follower
|
// Fetch follower
|
||||||
const follower = await getUser(ps.userId).catch(e => {
|
const follower = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
await acceptFollowRequest(user, follower).catch(e => {
|
await acceptFollowRequest(user, follower).catch(e => {
|
||||||
if (e.id === '8884c2dd-5795-4ac9-b27e-6a01d38190f9') throw new ApiError(meta.errors.noFollowRequest);
|
if (e.id === '8884c2dd-5795-4ac9-b27e-6a01d38190f9') throw new ApiError('NO_SUCH_FOLLOW_REQUEST');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -12,19 +12,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:following',
|
kind: 'write:following',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER', 'NO_SUCH_FOLLOW_REQUEST'],
|
||||||
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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -45,7 +33,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Fetch followee
|
// Fetch followee
|
||||||
const followee = await getUser(ps.userId).catch(e => {
|
const followee = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,7 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
await cancelFollowRequest(followee, user);
|
await cancelFollowRequest(followee, user);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof IdentifiableError) {
|
if (e instanceof IdentifiableError) {
|
||||||
if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError(meta.errors.followRequestNotFound);
|
if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError('NO_SUCH_FOLLOW_REQUEST');
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:following',
|
kind: 'write:following',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER'],
|
||||||
noSuchUser: {
|
|
||||||
message: 'No such user.',
|
|
||||||
code: 'NO_SUCH_USER',
|
|
||||||
id: 'abc2ffa6-25b2-4380-ba99-321ff3a94555',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -31,7 +25,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Fetch follower
|
// Fetch follower
|
||||||
const follower = await getUser(ps.userId).catch(e => {
|
const follower = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,6 @@ export const meta = {
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
ref: 'GalleryPost',
|
ref: 'GalleryPost',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
|
||||||
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:gallery',
|
kind: 'write:gallery',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_POST'],
|
||||||
noSuchPost: {
|
|
||||||
message: 'No such post.',
|
|
||||||
code: 'NO_SUCH_POST',
|
|
||||||
id: 'ae52f367-4bd7-4ecd-afc6-5672fff427f5',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (post == null) {
|
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||||
throw new ApiError(meta.errors.noSuchPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
await GalleryPosts.delete(post.id);
|
await GalleryPosts.delete(post.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,19 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:gallery-likes',
|
kind: 'write:gallery-likes',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_POST', 'ALREADY_LIKED'],
|
||||||
noSuchPost: {
|
|
||||||
message: 'No such post.',
|
|
||||||
code: 'NO_SUCH_POST',
|
|
||||||
id: '56c06af3-1287-442f-9701-c93f7c4a62ff',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyLiked: {
|
|
||||||
message: 'The post has already been liked.',
|
|
||||||
code: 'ALREADY_LIKED',
|
|
||||||
id: '40e9ed56-a59c-473a-bf3f-f289c54fb5a7',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -36,9 +24,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const post = await GalleryPosts.findOneBy({ id: ps.postId });
|
const post = await GalleryPosts.findOneBy({ id: ps.postId });
|
||||||
if (post == null) {
|
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||||
throw new ApiError(meta.errors.noSuchPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if already liked
|
// if already liked
|
||||||
const exist = await GalleryLikes.findOneBy({
|
const exist = await GalleryLikes.findOneBy({
|
||||||
|
@ -46,9 +32,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist != null) {
|
if (exist != null) throw new ApiError('ALREADY_LIKED');
|
||||||
throw new ApiError(meta.errors.alreadyLiked);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create like
|
// Create like
|
||||||
await GalleryLikes.insert({
|
await GalleryLikes.insert({
|
||||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_POST'],
|
||||||
noSuchPost: {
|
|
||||||
message: 'No such post.',
|
|
||||||
code: 'NO_SUCH_POST',
|
|
||||||
id: '1137bf14-c5b0-4604-85bb-5b5371b1cd45',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -36,9 +30,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
id: ps.postId,
|
id: ps.postId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (post == null) {
|
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||||
throw new ApiError(meta.errors.noSuchPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await GalleryPosts.pack(post, me);
|
return await GalleryPosts.pack(post, me);
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,19 +9,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:gallery-likes',
|
kind: 'write:gallery-likes',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_POST', 'NOT_LIKED'],
|
||||||
noSuchPost: {
|
|
||||||
message: 'No such post.',
|
|
||||||
code: 'NO_SUCH_POST',
|
|
||||||
id: 'c32e6dd0-b555-4413-925e-b3757d19ed84',
|
|
||||||
},
|
|
||||||
|
|
||||||
notLiked: {
|
|
||||||
message: 'You have not liked that post.',
|
|
||||||
code: 'NOT_LIKED',
|
|
||||||
id: 'e3e8e06e-be37-41f7-a5b4-87a8250288f0',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -35,18 +23,14 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const post = await GalleryPosts.findOneBy({ id: ps.postId });
|
const post = await GalleryPosts.findOneBy({ id: ps.postId });
|
||||||
if (post == null) {
|
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||||
throw new ApiError(meta.errors.noSuchPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
const exist = await GalleryLikes.findOneBy({
|
const exist = await GalleryLikes.findOneBy({
|
||||||
postId: post.id,
|
postId: post.id,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) throw new ApiError('NOT_LIKED');
|
||||||
throw new ApiError(meta.errors.notLiked);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete like
|
// Delete like
|
||||||
await GalleryLikes.delete(exist.id);
|
await GalleryLikes.delete(exist.id);
|
||||||
|
|
|
@ -20,10 +20,6 @@ export const meta = {
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
ref: 'GalleryPost',
|
ref: 'GalleryPost',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
|
||||||
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
|
|
@ -14,13 +14,7 @@ export const meta = {
|
||||||
ref: 'Hashtag',
|
ref: 'Hashtag',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_HASHTAG'],
|
||||||
noSuchHashtag: {
|
|
||||||
message: 'No such hashtag.',
|
|
||||||
code: 'NO_SUCH_HASHTAG',
|
|
||||||
id: '110ee688-193e-4a3a-9ecf-c167b2e6981e',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -34,9 +28,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const hashtag = await Hashtags.findOneBy({ name: normalizeForSearch(ps.tag) });
|
const hashtag = await Hashtags.findOneBy({ name: normalizeForSearch(ps.tag) });
|
||||||
if (hashtag == null) {
|
if (hashtag == null) throw new ApiError('NO_SUCH_HASHTAG');
|
||||||
throw new ApiError(meta.errors.noSuchHashtag);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Hashtags.pack(hashtag);
|
return await Hashtags.pack(hashtag);
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,31 +13,7 @@ export const meta = {
|
||||||
max: 1,
|
max: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'ebb53e5f-6574-9c0c-0b92-7ca6def56d7e',
|
|
||||||
},
|
|
||||||
|
|
||||||
unexpectedFileType: {
|
|
||||||
message: 'We need csv file.',
|
|
||||||
code: 'UNEXPECTED_FILE_TYPE',
|
|
||||||
id: 'b6fab7d6-d945-d67c-dfdb-32da1cd12cfe',
|
|
||||||
},
|
|
||||||
|
|
||||||
tooBigFile: {
|
|
||||||
message: 'That file is too big.',
|
|
||||||
code: 'TOO_BIG_FILE',
|
|
||||||
id: 'b7fbf0b1-aeef-3b21-29ef-fadd4cb72ccf',
|
|
||||||
},
|
|
||||||
|
|
||||||
emptyFile: {
|
|
||||||
message: 'That file is empty.',
|
|
||||||
code: 'EMPTY_FILE',
|
|
||||||
id: '6f3a4dcc-f060-a707-4950-806fbdbe60d6',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -52,10 +28,9 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||||
|
|
||||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
if (file == null) throw new ApiError('EMPTY_FILE');
|
||||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
|
||||||
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
|
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
|
||||||
|
|
||||||
createImportBlockingJob(user, file.id);
|
createImportBlockingJob(user, file.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,31 +12,7 @@ export const meta = {
|
||||||
max: 1,
|
max: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'b98644cf-a5ac-4277-a502-0b8054a709a3',
|
|
||||||
},
|
|
||||||
|
|
||||||
unexpectedFileType: {
|
|
||||||
message: 'We need csv file.',
|
|
||||||
code: 'UNEXPECTED_FILE_TYPE',
|
|
||||||
id: '660f3599-bce0-4f95-9dde-311fd841c183',
|
|
||||||
},
|
|
||||||
|
|
||||||
tooBigFile: {
|
|
||||||
message: 'That file is too big.',
|
|
||||||
code: 'TOO_BIG_FILE',
|
|
||||||
id: 'dee9d4ed-ad07-43ed-8b34-b2856398bc60',
|
|
||||||
},
|
|
||||||
|
|
||||||
emptyFile: {
|
|
||||||
message: 'That file is empty.',
|
|
||||||
code: 'EMPTY_FILE',
|
|
||||||
id: '31a1b42c-06f7-42ae-8a38-a661c5c9f691',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -51,10 +27,9 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||||
|
|
||||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
|
||||||
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
|
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
|
||||||
|
|
||||||
createImportFollowingJob(user, file.id);
|
createImportFollowingJob(user, file.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,31 +13,7 @@ export const meta = {
|
||||||
max: 1,
|
max: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'e674141e-bd2a-ba85-e616-aefb187c9c2a',
|
|
||||||
},
|
|
||||||
|
|
||||||
unexpectedFileType: {
|
|
||||||
message: 'We need csv file.',
|
|
||||||
code: 'UNEXPECTED_FILE_TYPE',
|
|
||||||
id: '568c6e42-c86c-ba09-c004-517f83f9f1a8',
|
|
||||||
},
|
|
||||||
|
|
||||||
tooBigFile: {
|
|
||||||
message: 'That file is too big.',
|
|
||||||
code: 'TOO_BIG_FILE',
|
|
||||||
id: '9b4ada6d-d7f7-0472-0713-4f558bd1ec9c',
|
|
||||||
},
|
|
||||||
|
|
||||||
emptyFile: {
|
|
||||||
message: 'That file is empty.',
|
|
||||||
code: 'EMPTY_FILE',
|
|
||||||
id: 'd2f12af1-e7b4-feac-86a3-519548f2728e',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -52,10 +28,9 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||||
|
|
||||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
|
||||||
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
|
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
|
||||||
|
|
||||||
createImportMutingJob(user, file.id);
|
createImportMutingJob(user, file.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,31 +12,7 @@ export const meta = {
|
||||||
max: 1,
|
max: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'ea9cc34f-c415-4bc6-a6fe-28ac40357049',
|
|
||||||
},
|
|
||||||
|
|
||||||
unexpectedFileType: {
|
|
||||||
message: 'We need csv file.',
|
|
||||||
code: 'UNEXPECTED_FILE_TYPE',
|
|
||||||
id: 'a3c9edda-dd9b-4596-be6a-150ef813745c',
|
|
||||||
},
|
|
||||||
|
|
||||||
tooBigFile: {
|
|
||||||
message: 'That file is too big.',
|
|
||||||
code: 'TOO_BIG_FILE',
|
|
||||||
id: 'ae6e7a22-971b-4b52-b2be-fc0b9b121fe9',
|
|
||||||
},
|
|
||||||
|
|
||||||
emptyFile: {
|
|
||||||
message: 'That file is empty.',
|
|
||||||
code: 'EMPTY_FILE',
|
|
||||||
id: '99efe367-ce6e-4d44-93f8-5fae7b040356',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -51,10 +27,9 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||||
|
|
||||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
if (file.size > 30000) throw new ApiError('FILE_TOO_BIG');
|
||||||
if (file.size > 30000) throw new ApiError(meta.errors.tooBigFile);
|
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
|
||||||
|
|
||||||
createImportUserListsJob(user, file.id);
|
createImportUserListsJob(user, file.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['ALREADY_PINNED', 'NO_SUCH_NOTE', 'PIN_LIMIT_EXCEEDED'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '56734f8b-3928-431e-bf80-6ff87df40cb3',
|
|
||||||
},
|
|
||||||
|
|
||||||
pinLimitExceeded: {
|
|
||||||
message: 'You can not pin notes any more.',
|
|
||||||
code: 'PIN_LIMIT_EXCEEDED',
|
|
||||||
id: '72dab508-c64d-498f-8740-a8eec1ba385a',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyPinned: {
|
|
||||||
message: 'That note has already been pinned.',
|
|
||||||
code: 'ALREADY_PINNED',
|
|
||||||
id: '8b18c2b7-68fe-4edb-9892-c0cbaeb6c913',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -48,9 +30,9 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
await addPinned(user, ps.noteId).catch(e => {
|
await addPinned(user, ps.noteId).catch(e => {
|
||||||
if (e.id === '70c4e51f-5bea-449c-a030-53bee3cce202') throw new ApiError(meta.errors.noSuchNote);
|
if (e.id === '70c4e51f-5bea-449c-a030-53bee3cce202') throw new ApiError('NO_SUCH_NOTE');
|
||||||
if (e.id === '15a018eb-58e5-4da1-93be-330fcc5e4e1a') throw new ApiError(meta.errors.pinLimitExceeded);
|
if (e.id === '15a018eb-58e5-4da1-93be-330fcc5e4e1a') throw new ApiError('PIN_LIMIT_EXCEEDED');
|
||||||
if (e.id === '23f0cf4e-59a3-4276-a91d-61a5891c1514') throw new ApiError(meta.errors.alreadyPinned);
|
if (e.id === '23f0cf4e-59a3-4276-a91d-61a5891c1514') throw new ApiError('ALREADY_PINNED');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_ANNOUNCEMENT'],
|
||||||
noSuchAnnouncement: {
|
|
||||||
message: 'No such announcement.',
|
|
||||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
|
||||||
id: '184663db-df88-4bc2-8b52-fb85f0681939',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Check if announcement exists
|
// Check if announcement exists
|
||||||
const announcement = await Announcements.findOneBy({ id: ps.announcementId });
|
const announcement = await Announcements.findOneBy({ id: ps.announcementId });
|
||||||
|
|
||||||
if (announcement == null) {
|
if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');
|
||||||
throw new ApiError(meta.errors.noSuchAnnouncement);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if already read
|
// Check if already read
|
||||||
const read = await AnnouncementReads.findOneBy({
|
const read = await AnnouncementReads.findOneBy({
|
||||||
|
@ -43,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (read != null) {
|
if (read != null) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create read
|
// Create read
|
||||||
await AnnouncementReads.insert({
|
await AnnouncementReads.insert({
|
||||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
||||||
|
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_KEY'],
|
||||||
noSuchKey: {
|
|
||||||
message: 'No such key.',
|
|
||||||
code: 'NO_SUCH_KEY',
|
|
||||||
id: '97a1e8e7-c0f7-47d2-957a-92e61256e01a',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
const item = await query.getOne();
|
const item = await query.getOne();
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) throw new ApiError('NO_SUCH_KEY');
|
||||||
throw new ApiError(meta.errors.noSuchKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
updatedAt: item.updatedAt,
|
updatedAt: item.updatedAt,
|
||||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
||||||
|
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_KEY'],
|
||||||
noSuchKey: {
|
|
||||||
message: 'No such key.',
|
|
||||||
code: 'NO_SUCH_KEY',
|
|
||||||
id: 'ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
const item = await query.getOne();
|
const item = await query.getOne();
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) throw new ApiError('NO_SUCH_KEY');
|
||||||
throw new ApiError(meta.errors.noSuchKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
return item.value;
|
return item.value;
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
||||||
|
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_KEY'],
|
||||||
noSuchKey: {
|
|
||||||
message: 'No such key.',
|
|
||||||
code: 'NO_SUCH_KEY',
|
|
||||||
id: '1fac4e8a-a6cd-4e39-a4a5-3a7e11f1b019',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
const item = await query.getOne();
|
const item = await query.getOne();
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) throw new ApiError('NO_SUCH_KEY');
|
||||||
throw new ApiError(meta.errors.noSuchKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
await RegistryItems.remove(item);
|
await RegistryItems.remove(item);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '454170ce-9d63-4a43-9da1-ea10afe81e21',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -36,7 +30,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
await removePinned(user, ps.noteId).catch(e => {
|
await removePinned(user, ps.noteId).catch(e => {
|
||||||
if (e.id === 'b302d4cf-c050-400a-bbb3-be208681f40c') throw new ApiError(meta.errors.noSuchNote);
|
if (e.id === 'b302d4cf-c050-400a-bbb3-be208681f40c') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -19,19 +19,9 @@ export const meta = {
|
||||||
max: 3,
|
max: 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
// FIXME: refactor to remove both of these errors?
|
||||||
incorrectPassword: {
|
// the password should not be passed as it is not compatible with using OAuth
|
||||||
message: 'Incorrect password.',
|
errors: ['ACCESS_DENIED', 'INTERNAL_ERROR'],
|
||||||
code: 'INCORRECT_PASSWORD',
|
|
||||||
id: 'e54c1d7e-e7d6-4103-86b6-0a95069b4ad3',
|
|
||||||
},
|
|
||||||
|
|
||||||
unavailable: {
|
|
||||||
message: 'Unavailable email address.',
|
|
||||||
code: 'UNAVAILABLE',
|
|
||||||
id: 'a2defefb-f220-8849-0af6-17f816099323',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -50,15 +40,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(ps.password, profile.password!);
|
const same = await bcrypt.compare(ps.password, profile.password!);
|
||||||
|
|
||||||
if (!same) {
|
if (!same) throw new ApiError('ACCESS_DENIED');
|
||||||
throw new ApiError(meta.errors.incorrectPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.email != null) {
|
if (ps.email != null) {
|
||||||
const available = await validateEmailForAccount(ps.email);
|
const available = await validateEmailForAccount(ps.email);
|
||||||
if (!available) {
|
if (!available) throw new ApiError('INTERNAL_ERROR');
|
||||||
throw new ApiError(meta.errors.unavailable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await UserProfiles.update(user.id, {
|
await UserProfiles.update(user.id, {
|
||||||
|
|
|
@ -22,43 +22,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['INVALID_REGEXP', 'NO_SUCH_FILE', 'NO_SUCH_PAGE', 'NOT_AN_IMAGE'],
|
||||||
noSuchAvatar: {
|
|
||||||
message: 'No such avatar file.',
|
|
||||||
code: 'NO_SUCH_AVATAR',
|
|
||||||
id: '539f3a45-f215-4f81-a9a8-31293640207f',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchBanner: {
|
|
||||||
message: 'No such banner file.',
|
|
||||||
code: 'NO_SUCH_BANNER',
|
|
||||||
id: '0d8f5629-f210-41c2-9433-735831a58595',
|
|
||||||
},
|
|
||||||
|
|
||||||
avatarNotAnImage: {
|
|
||||||
message: 'The file specified as an avatar is not an image.',
|
|
||||||
code: 'AVATAR_NOT_AN_IMAGE',
|
|
||||||
id: 'f419f9f8-2f4d-46b1-9fb4-49d3a2fd7191',
|
|
||||||
},
|
|
||||||
|
|
||||||
bannerNotAnImage: {
|
|
||||||
message: 'The file specified as a banner is not an image.',
|
|
||||||
code: 'BANNER_NOT_AN_IMAGE',
|
|
||||||
id: '75aedb19-2afd-4e6d-87fc-67941256fa60',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchPage: {
|
|
||||||
message: 'No such page.',
|
|
||||||
code: 'NO_SUCH_PAGE',
|
|
||||||
id: '8e01b590-7eb9-431b-a239-860e086c408e',
|
|
||||||
},
|
|
||||||
|
|
||||||
invalidRegexp: {
|
|
||||||
message: 'Invalid Regular Expression.',
|
|
||||||
code: 'INVALID_REGEXP',
|
|
||||||
id: '0d786918-10df-41cd-8f33-8dec7d9a89a5',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -142,12 +106,12 @@ export default define(meta, paramDef, async (ps, _user, token) => {
|
||||||
// validate regular expression syntax
|
// validate regular expression syntax
|
||||||
ps.mutedWords.filter(x => !Array.isArray(x)).forEach(x => {
|
ps.mutedWords.filter(x => !Array.isArray(x)).forEach(x => {
|
||||||
const regexp = x.match(/^\/(.+)\/(.*)$/);
|
const regexp = x.match(/^\/(.+)\/(.*)$/);
|
||||||
if (!regexp) throw new ApiError(meta.errors.invalidRegexp);
|
if (!regexp) throw new ApiError('INVALID_REGEXP');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new RE2(regexp[1], regexp[2]);
|
new RE2(regexp[1], regexp[2]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new ApiError(meta.errors.invalidRegexp);
|
throw new ApiError('INVALID_REGEXP');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -174,21 +138,21 @@ export default define(meta, paramDef, async (ps, _user, token) => {
|
||||||
if (ps.avatarId) {
|
if (ps.avatarId) {
|
||||||
const avatar = await DriveFiles.findOneBy({ id: ps.avatarId });
|
const avatar = await DriveFiles.findOneBy({ id: ps.avatarId });
|
||||||
|
|
||||||
if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar);
|
if (avatar == null || avatar.userId !== user.id) throw new ApiError('NO_SUCH_FILE', 'Avatar file not found.');
|
||||||
if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage);
|
if (!avatar.type.startsWith('image/')) throw new ApiError('NOT_AN_IMAGE', 'Avatar file is not an image.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.bannerId) {
|
if (ps.bannerId) {
|
||||||
const banner = await DriveFiles.findOneBy({ id: ps.bannerId });
|
const banner = await DriveFiles.findOneBy({ id: ps.bannerId });
|
||||||
|
|
||||||
if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner);
|
if (banner == null || banner.userId !== user.id) throw new ApiError('NO_SUCH_FILE', 'Banner file not found.');
|
||||||
if (!banner.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage);
|
if (!banner.type.startsWith('image/')) throw new ApiError('BANNER_NOT_AN_IMAGE', 'Banner file is not an image.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.pinnedPageId) {
|
if (ps.pinnedPageId) {
|
||||||
const page = await Pages.findOneBy({ id: ps.pinnedPageId });
|
const page = await Pages.findOneBy({ id: ps.pinnedPageId });
|
||||||
|
|
||||||
if (page == null || page.userId !== user.id) throw new ApiError(meta.errors.noSuchPage);
|
if (page == null || page.userId !== user.id) throw new ApiError('NO_SUCH_PAGE');
|
||||||
|
|
||||||
profileUpdates.pinnedPageId = page.id;
|
profileUpdates.pinnedPageId = page.id;
|
||||||
} else if (ps.pinnedPageId === null) {
|
} else if (ps.pinnedPageId === null) {
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_WEBHOOK'],
|
||||||
noSuchWebhook: {
|
|
||||||
message: 'No such webhook.',
|
|
||||||
code: 'NO_SUCH_WEBHOOK',
|
|
||||||
id: 'bae73e5a-5522-4965-ae19-3a8688e71d82',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (webhook == null) {
|
if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
|
||||||
throw new ApiError(meta.errors.noSuchWebhook);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Webhooks.delete(webhook.id);
|
await Webhooks.delete(webhook.id);
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'read:account',
|
kind: 'read:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_WEBHOOK'],
|
||||||
noSuchWebhook: {
|
|
||||||
message: 'No such webhook.',
|
|
||||||
code: 'NO_SUCH_WEBHOOK',
|
|
||||||
id: '50f614d9-3047-4f7e-90d8-ad6b2d5fb098',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (webhook == null) {
|
if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
|
||||||
throw new ApiError(meta.errors.noSuchWebhook);
|
|
||||||
}
|
|
||||||
|
|
||||||
return webhook;
|
return webhook;
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,14 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_WEBHOOK'],
|
||||||
noSuchWebhook: {
|
|
||||||
message: 'No such webhook.',
|
|
||||||
code: 'NO_SUCH_WEBHOOK',
|
|
||||||
id: 'fb0fea69-da18-45b1-828d-bd4fd1612518',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -43,9 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (webhook == null) {
|
if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
|
||||||
throw new ApiError(meta.errors.noSuchWebhook);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Webhooks.update(webhook.id, {
|
await Webhooks.update(webhook.id, {
|
||||||
name: ps.name,
|
name: ps.name,
|
||||||
|
|
|
@ -23,25 +23,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['ACCESS_DENIED', 'NO_SUCH_USER', 'NO_SUCH_GROUP'],
|
||||||
noSuchUser: {
|
|
||||||
message: 'No such user.',
|
|
||||||
code: 'NO_SUCH_USER',
|
|
||||||
id: '11795c64-40ea-4198-b06e-3c873ed9039d',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchGroup: {
|
|
||||||
message: 'No such group.',
|
|
||||||
code: 'NO_SUCH_GROUP',
|
|
||||||
id: 'c4d9f88c-9270-4632-b032-6ed8cee36f7f',
|
|
||||||
},
|
|
||||||
|
|
||||||
groupAccessDenied: {
|
|
||||||
message: 'You can not read messages of groups that you have not joined.',
|
|
||||||
code: 'GROUP_ACCESS_DENIED',
|
|
||||||
id: 'a053a8dd-a491-4718-8f87-50775aad9284',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -73,7 +55,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
if (ps.userId != null) {
|
if (ps.userId != null) {
|
||||||
// Fetch recipient (user)
|
// Fetch recipient (user)
|
||||||
const recipient = await getUser(ps.userId).catch(e => {
|
const recipient = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -110,9 +92,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Fetch recipient (group)
|
// Fetch recipient (group)
|
||||||
const recipientGroup = await UserGroups.findOneBy({ id: ps.groupId });
|
const recipientGroup = await UserGroups.findOneBy({ id: ps.groupId });
|
||||||
|
|
||||||
if (recipientGroup == null) {
|
if (recipientGroup == null) throw new ApiError('NO_SUCH_GROUP');
|
||||||
throw new ApiError(meta.errors.noSuchGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check joined
|
// check joined
|
||||||
const joining = await UserGroupJoinings.findOneBy({
|
const joining = await UserGroupJoinings.findOneBy({
|
||||||
|
@ -120,9 +100,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userGroupId: recipientGroup.id,
|
userGroupId: recipientGroup.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (joining == null) {
|
if (joining == null) throw new ApiError('ACCESS_DENIED', 'You have to join a group to read messages in it.');
|
||||||
throw new ApiError(meta.errors.groupAccessDenied);
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = makePaginationQuery(MessagingMessages.createQueryBuilder('message'), ps.sinceId, ps.untilId)
|
const query = makePaginationQuery(MessagingMessages.createQueryBuilder('message'), ps.sinceId, ps.untilId)
|
||||||
.andWhere('message.groupId = :groupId', { groupId: recipientGroup.id });
|
.andWhere('message.groupId = :groupId', { groupId: recipientGroup.id });
|
||||||
|
|
|
@ -19,51 +19,11 @@ export const meta = {
|
||||||
ref: 'MessagingMessage',
|
ref: 'MessagingMessage',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['ACCESS_DENIED', 'BLOCKED', 'NO_SUCH_FILE', 'NO_SUCH_USER', 'NO_SUCH_GROUP', 'RECIPIENT_IS_YOURSELF'],
|
||||||
recipientIsYourself: {
|
|
||||||
message: 'You can not send a message to yourself.',
|
|
||||||
code: 'RECIPIENT_IS_YOURSELF',
|
|
||||||
id: '17e2ba79-e22a-4cbc-bf91-d327643f4a7e',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchUser: {
|
|
||||||
message: 'No such user.',
|
|
||||||
code: 'NO_SUCH_USER',
|
|
||||||
id: '11795c64-40ea-4198-b06e-3c873ed9039d',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchGroup: {
|
|
||||||
message: 'No such group.',
|
|
||||||
code: 'NO_SUCH_GROUP',
|
|
||||||
id: 'c94e2a5d-06aa-4914-8fa6-6a42e73d6537',
|
|
||||||
},
|
|
||||||
|
|
||||||
groupAccessDenied: {
|
|
||||||
message: 'You can not send messages to groups that you have not joined.',
|
|
||||||
code: 'GROUP_ACCESS_DENIED',
|
|
||||||
id: 'd96b3cca-5ad1-438b-ad8b-02f931308fbd',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: '4372b8e2-185d-4146-8749-2f68864a3e5f',
|
|
||||||
},
|
|
||||||
|
|
||||||
youHaveBeenBlocked: {
|
|
||||||
message: 'You cannot send a message because you have been blocked by this user.',
|
|
||||||
code: 'YOU_HAVE_BEEN_BLOCKED',
|
|
||||||
id: 'c15a5199-7422-4968-941a-2a462c478f7d',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
|
||||||
text: { type: 'string', nullable: true, maxLength: 3000 },
|
|
||||||
fileId: { type: 'string', format: 'misskey:id' },
|
|
||||||
},
|
|
||||||
anyOf: [
|
anyOf: [
|
||||||
{
|
{
|
||||||
properties: {
|
properties: {
|
||||||
|
@ -137,13 +97,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
if (ps.userId != null) {
|
if (ps.userId != null) {
|
||||||
// Myself
|
// Myself
|
||||||
if (ps.userId === user.id) {
|
if (ps.userId === user.id) throw new ApiError('RECIPIENT_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.recipientIsYourself);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch recipient (user)
|
// Fetch recipient (user)
|
||||||
recipientUser = await getUser(ps.userId).catch(e => {
|
recipientUser = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -152,16 +110,12 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
blockerId: recipientUser.id,
|
blockerId: recipientUser.id,
|
||||||
blockeeId: user.id,
|
blockeeId: user.id,
|
||||||
});
|
});
|
||||||
if (block) {
|
if (block) throw new ApiError('BLOCKED');
|
||||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
|
||||||
}
|
|
||||||
} else if (ps.groupId != null) {
|
} else if (ps.groupId != null) {
|
||||||
// Fetch recipient (group)
|
// Fetch recipient (group)
|
||||||
recipientGroup = await UserGroups.findOneBy({ id: ps.groupId! });
|
recipientGroup = await UserGroups.findOneBy({ id: ps.groupId! });
|
||||||
|
|
||||||
if (recipientGroup == null) {
|
if (recipientGroup == null) throw new ApiError('NO_SUCH_GROUP');
|
||||||
throw new ApiError(meta.errors.noSuchGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check joined
|
// check joined
|
||||||
const joining = await UserGroupJoinings.findOneBy({
|
const joining = await UserGroupJoinings.findOneBy({
|
||||||
|
@ -169,9 +123,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userGroupId: recipientGroup.id,
|
userGroupId: recipientGroup.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (joining == null) {
|
if (joining == null) throw new ApiError('ACCESS_DENIED', 'You have to join a group to send a message in it.');
|
||||||
throw new ApiError(meta.errors.groupAccessDenied);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let file = null;
|
let file = null;
|
||||||
|
@ -181,9 +133,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await createMessage(user, recipientUser, recipientGroup, ps.text, file);
|
return await createMessage(user, recipientUser, recipientGroup, ps.text, file);
|
||||||
|
|
|
@ -17,13 +17,7 @@ export const meta = {
|
||||||
minInterval: SECOND,
|
minInterval: SECOND,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_MESSAGE'],
|
||||||
noSuchMessage: {
|
|
||||||
message: 'No such message.',
|
|
||||||
code: 'NO_SUCH_MESSAGE',
|
|
||||||
id: '54b5b326-7925-42cf-8019-130fda8b56af',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -41,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (message == null) {
|
if (message == null) throw new ApiError('NO_SUCH_MESSAGE');
|
||||||
throw new ApiError(meta.errors.noSuchMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
await deleteMessage(message);
|
await deleteMessage(message);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:messaging',
|
kind: 'write:messaging',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_MESSAGE'],
|
||||||
noSuchMessage: {
|
|
||||||
message: 'No such message.',
|
|
||||||
code: 'NO_SUCH_MESSAGE',
|
|
||||||
id: '86d56a2f-a9c3-4afb-b13c-3e9bfef9aa14',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -31,18 +25,16 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const message = await MessagingMessages.findOneBy({ id: ps.messageId });
|
const message = await MessagingMessages.findOneBy({ id: ps.messageId });
|
||||||
|
|
||||||
if (message == null) {
|
if (message == null) throw new ApiError('NO_SUCH_MESSAGE');
|
||||||
throw new ApiError(meta.errors.noSuchMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.recipientId) {
|
if (message.recipientId) {
|
||||||
await readUserMessagingMessage(user.id, message.userId, [message.id]).catch(e => {
|
await readUserMessagingMessage(user.id, message.userId, [message.id]).catch(e => {
|
||||||
if (e.id === 'e140a4bf-49ce-4fb6-b67c-b78dadf6b52f') throw new ApiError(meta.errors.noSuchMessage);
|
if (e.id === 'e140a4bf-49ce-4fb6-b67c-b78dadf6b52f') throw new ApiError('NO_SUCH_MESSAGE');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
} else if (message.groupId) {
|
} else if (message.groupId) {
|
||||||
await readGroupMessagingMessage(user.id, message.groupId, [message.id]).catch(e => {
|
await readGroupMessagingMessage(user.id, message.groupId, [message.id]).catch(e => {
|
||||||
if (e.id === '930a270c-714a-46b2-b776-ad27276dc569') throw new ApiError(meta.errors.noSuchMessage);
|
if (e.id === '930a270c-714a-46b2-b776-ad27276dc569') throw new ApiError('NO_SUCH_MESSAGE');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,25 +13,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:mutes',
|
kind: 'write:mutes',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER', 'MUTEE_IS_YOURSELF', 'ALREADY_MUTING'],
|
||||||
noSuchUser: {
|
|
||||||
message: 'No such user.',
|
|
||||||
code: 'NO_SUCH_USER',
|
|
||||||
id: '6fef56f3-e765-4957-88e5-c6f65329b8a5',
|
|
||||||
},
|
|
||||||
|
|
||||||
muteeIsYourself: {
|
|
||||||
message: 'Mutee is yourself.',
|
|
||||||
code: 'MUTEE_IS_YOURSELF',
|
|
||||||
id: 'a4619cb2-5f23-484b-9301-94c903074e10',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyMuting: {
|
|
||||||
message: 'You are already muting that user.',
|
|
||||||
code: 'ALREADY_MUTING',
|
|
||||||
id: '7e7359cb-160c-4956-b08f-4d1c653cd007',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -52,13 +34,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const muter = user;
|
const muter = user;
|
||||||
|
|
||||||
// 自分自身
|
// 自分自身
|
||||||
if (user.id === ps.userId) {
|
if (user.id === ps.userId) throw new ApiError('MUTEE_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.muteeIsYourself);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get mutee
|
// Get mutee
|
||||||
const mutee = await getUser(ps.userId).catch(e => {
|
const mutee = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,9 +48,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
muteeId: mutee.id,
|
muteeId: mutee.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist != null) {
|
if (exist != null) throw new ApiError('ALREADY_MUTING');
|
||||||
throw new ApiError(meta.errors.alreadyMuting);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.expiresAt && ps.expiresAt <= Date.now()) {
|
if (ps.expiresAt && ps.expiresAt <= Date.now()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -11,25 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:mutes',
|
kind: 'write:mutes',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_USER', 'MUTEE_IS_YOURSELF', 'NOT_MUTING'],
|
||||||
noSuchUser: {
|
|
||||||
message: 'No such user.',
|
|
||||||
code: 'NO_SUCH_USER',
|
|
||||||
id: 'b851d00b-8ab1-4a56-8b1b-e24187cb48ef',
|
|
||||||
},
|
|
||||||
|
|
||||||
muteeIsYourself: {
|
|
||||||
message: 'Mutee is yourself.',
|
|
||||||
code: 'MUTEE_IS_YOURSELF',
|
|
||||||
id: 'f428b029-6b39-4d48-a1d2-cc1ae6dd5cf9',
|
|
||||||
},
|
|
||||||
|
|
||||||
notMuting: {
|
|
||||||
message: 'You are not muting that user.',
|
|
||||||
code: 'NOT_MUTING',
|
|
||||||
id: '5467d020-daa9-4553-81e1-135c0c35a96d',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -45,13 +27,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const muter = user;
|
const muter = user;
|
||||||
|
|
||||||
// Check if the mutee is yourself
|
// Check if the mutee is yourself
|
||||||
if (user.id === ps.userId) {
|
if (user.id === ps.userId) throw new ApiError('MUTEE_IS_YOURSELF');
|
||||||
throw new ApiError(meta.errors.muteeIsYourself);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get mutee
|
// Get mutee
|
||||||
const mutee = await getUser(ps.userId).catch(e => {
|
const mutee = await getUser(ps.userId).catch(e => {
|
||||||
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,9 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
muteeId: mutee.id,
|
muteeId: mutee.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) throw new ApiError('NOT_MUTING');
|
||||||
throw new ApiError(meta.errors.notMuting);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete mute
|
// Delete mute
|
||||||
await Mutings.delete({
|
await Mutings.delete({
|
||||||
|
|
|
@ -19,13 +19,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '47db1a1c-b0af-458d-8fb4-986e4efafe1e',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -39,7 +33,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, me) => {
|
export default define(meta, paramDef, async (ps, me) => {
|
||||||
const note = await getNote(ps.noteId, me).catch(err => {
|
const note = await getNote(ps.noteId, me).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: 'e1035875-9551-45ec-afa8-1ded1fcb53c8',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -41,7 +35,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -37,55 +37,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE', 'PURE_RENOTE', 'EXPIRED_POLL', 'NO_SUCH_CHANNEL', 'BLOCKED', 'LESS_RESTRICTIVE_VISIBILITY'],
|
||||||
noSuchRenoteTarget: {
|
|
||||||
message: 'No such renote target.',
|
|
||||||
code: 'NO_SUCH_RENOTE_TARGET',
|
|
||||||
id: 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4',
|
|
||||||
},
|
|
||||||
|
|
||||||
cannotReRenote: {
|
|
||||||
message: 'You can not Renote a pure Renote.',
|
|
||||||
code: 'CANNOT_RENOTE_TO_A_PURE_RENOTE',
|
|
||||||
id: 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchReplyTarget: {
|
|
||||||
message: 'No such reply target.',
|
|
||||||
code: 'NO_SUCH_REPLY_TARGET',
|
|
||||||
id: '749ee0f6-d3da-459a-bf02-282e2da4292c',
|
|
||||||
},
|
|
||||||
|
|
||||||
cannotReplyToPureRenote: {
|
|
||||||
message: 'You can not reply to a pure Renote.',
|
|
||||||
code: 'CANNOT_REPLY_TO_A_PURE_RENOTE',
|
|
||||||
id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15',
|
|
||||||
},
|
|
||||||
|
|
||||||
cannotCreateAlreadyExpiredPoll: {
|
|
||||||
message: 'Poll is already expired.',
|
|
||||||
code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL',
|
|
||||||
id: '04da457d-b083-4055-9082-955525eda5a5',
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchChannel: {
|
|
||||||
message: 'No such channel.',
|
|
||||||
code: 'NO_SUCH_CHANNEL',
|
|
||||||
id: 'b1653923-5453-4edc-b786-7c4f39bb0bbb',
|
|
||||||
},
|
|
||||||
|
|
||||||
youHaveBeenBlocked: {
|
|
||||||
message: 'You have been blocked by this user.',
|
|
||||||
code: 'YOU_HAVE_BEEN_BLOCKED',
|
|
||||||
id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3',
|
|
||||||
},
|
|
||||||
|
|
||||||
lessRestrictiveVisibility: {
|
|
||||||
message: 'The visibility cannot be less restrictive than the parent note.',
|
|
||||||
code: 'LESS_RESTRICTIVE_VISIBILITY',
|
|
||||||
id: 'c8ab7a7a-8852-41e2-8b24-079bbaceb585',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -199,17 +151,15 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
if (ps.renoteId != null) {
|
if (ps.renoteId != null) {
|
||||||
// Fetch renote to note
|
// Fetch renote to note
|
||||||
renote = await getNote(ps.renoteId, user).catch(e => {
|
renote = await getNote(ps.renoteId, user).catch(e => {
|
||||||
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchRenoteTarget);
|
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE', 'Note to be renoted not found.');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isPureRenote(renote)) {
|
if (isPureRenote(renote)) throw new ApiError('PURE_RENOTE', 'Cannot renote a pure renote.');
|
||||||
throw new ApiError(meta.errors.cannotReRenote);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the visibility is not less restrictive
|
// check that the visibility is not less restrictive
|
||||||
if (noteVisibilities.indexOf(renote.visibility) > noteVisibilities.indexOf(ps.visibility)) {
|
if (noteVisibilities.indexOf(renote.visibility) > noteVisibilities.indexOf(ps.visibility)) {
|
||||||
throw new ApiError(meta.errors.lessRestrictiveVisibility);
|
throw new ApiError('LESS_RESTRICTIVE_VISIBILITY', `The renote has visibility ${renote.visibility}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check blocking
|
// Check blocking
|
||||||
|
@ -218,9 +168,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
blockerId: renote.userId,
|
blockerId: renote.userId,
|
||||||
blockeeId: user.id,
|
blockeeId: user.id,
|
||||||
});
|
});
|
||||||
if (block) {
|
if (block) throw new ApiError('BLOCKED', 'Blocked by author of note to be renoted.');
|
||||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,17 +176,15 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
if (ps.replyId != null) {
|
if (ps.replyId != null) {
|
||||||
// Fetch reply
|
// Fetch reply
|
||||||
reply = await getNote(ps.replyId, user).catch(e => {
|
reply = await getNote(ps.replyId, user).catch(e => {
|
||||||
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchReplyTarget);
|
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE', 'Replied to note not found.');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isPureRenote(reply)) {
|
if (isPureRenote(reply)) throw new ApiError('PURE_RENOTE', 'Cannot reply to a pure renote.');
|
||||||
throw new ApiError(meta.errors.cannotReplyToPureRenote);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the visibility is not less restrictive
|
// check that the visibility is not less restrictive
|
||||||
if (noteVisibilities.indexOf(reply.visibility) > noteVisibilities.indexOf(ps.visibility)) {
|
if (noteVisibilities.indexOf(reply.visibility) > noteVisibilities.indexOf(ps.visibility)) {
|
||||||
throw new ApiError(meta.errors.lessRestrictiveVisibility);
|
throw new ApiError('LESS_RESTRICTIVE_VISIBILITY', `The replied to note has visibility ${reply.visibility}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check blocking
|
// Check blocking
|
||||||
|
@ -247,16 +193,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
blockerId: reply.userId,
|
blockerId: reply.userId,
|
||||||
blockeeId: user.id,
|
blockeeId: user.id,
|
||||||
});
|
});
|
||||||
if (block) {
|
if (block) throw new ApiError('BLOCKED', 'Blocked by author of replied to note.');
|
||||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.poll) {
|
if (ps.poll) {
|
||||||
if (typeof ps.poll.expiresAt === 'number') {
|
if (typeof ps.poll.expiresAt === 'number') {
|
||||||
if (ps.poll.expiresAt < Date.now()) {
|
if (ps.poll.expiresAt < Date.now()) {
|
||||||
throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll);
|
throw new ApiError('EXPIRED_POLL');
|
||||||
}
|
}
|
||||||
} else if (typeof ps.poll.expiredAfter === 'number') {
|
} else if (typeof ps.poll.expiredAfter === 'number') {
|
||||||
ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
|
ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
|
||||||
|
@ -267,9 +211,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
if (ps.channelId != null) {
|
if (ps.channelId != null) {
|
||||||
channel = await Channels.findOneBy({ id: ps.channelId });
|
channel = await Channels.findOneBy({ id: ps.channelId });
|
||||||
|
|
||||||
if (channel == null) {
|
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||||
throw new ApiError(meta.errors.noSuchChannel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 投稿を作成
|
// 投稿を作成
|
||||||
|
|
|
@ -18,19 +18,7 @@ export const meta = {
|
||||||
minInterval: SECOND,
|
minInterval: SECOND,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['ACCESS_DENIED', 'NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '490be23f-8c1f-4796-819f-94cb4f9d1630',
|
|
||||||
},
|
|
||||||
|
|
||||||
accessDenied: {
|
|
||||||
message: 'Access denied.',
|
|
||||||
code: 'ACCESS_DENIED',
|
|
||||||
id: 'fe8d7103-0ea8-4ec3-814d-f8b401dc69e9',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -44,12 +32,12 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ((!user.isAdmin && !user.isModerator) && (note.userId !== user.id)) {
|
if ((!user.isAdmin && !user.isModerator) && (note.userId !== user.id)) {
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
throw new ApiError('ACCESS_DENIED');
|
||||||
}
|
}
|
||||||
|
|
||||||
// この操作を行うのが投稿者とは限らない(例えばモデレーター)ため
|
// この操作を行うのが投稿者とは限らない(例えばモデレーター)ため
|
||||||
|
|
|
@ -11,19 +11,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:favorites',
|
kind: 'write:favorites',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE', 'ALREADY_FAVORITED'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '6dd26674-e060-4816-909a-45ba3f4da458',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyFavorited: {
|
|
||||||
message: 'The note has already been marked as a favorite.',
|
|
||||||
code: 'ALREADY_FAVORITED',
|
|
||||||
id: 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -38,7 +26,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Get favoritee
|
// Get favoritee
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -48,9 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist != null) {
|
if (exist != null) throw new ApiError('ALREADY_FAVORITED');
|
||||||
throw new ApiError(meta.errors.alreadyFavorited);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create favorite
|
// Create favorite
|
||||||
await NoteFavorites.insert({
|
await NoteFavorites.insert({
|
||||||
|
|
|
@ -10,19 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:favorites',
|
kind: 'write:favorites',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE', 'NOT_FAVORITED'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '80848a2c-398f-4343-baa9-df1d57696c56',
|
|
||||||
},
|
|
||||||
|
|
||||||
notFavorited: {
|
|
||||||
message: 'You have not marked that note a favorite.',
|
|
||||||
code: 'NOT_FAVORITED',
|
|
||||||
id: 'b625fc69-635e-45e9-86f4-dbefbef35af5',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -37,7 +25,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
// Get favoritee
|
// Get favoritee
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -47,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) throw new ApiError('NOT_FAVORITED');
|
||||||
throw new ApiError(meta.errors.notFavorited);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete favorite
|
// Delete favorite
|
||||||
await NoteFavorites.delete(exist.id);
|
await NoteFavorites.delete(exist.id);
|
||||||
|
|
|
@ -23,13 +23,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['TIMELINE_DISABLED'],
|
||||||
gtlDisabled: {
|
|
||||||
message: 'Global timeline has been disabled.',
|
|
||||||
code: 'GTL_DISABLED',
|
|
||||||
id: '0332fc13-6ab2-4427-ae80-a9fadffd1a6b',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -54,7 +48,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const m = await fetchMeta();
|
const m = await fetchMeta();
|
||||||
if (m.disableGlobalTimeline) {
|
if (m.disableGlobalTimeline) {
|
||||||
if (user == null || (!user.isAdmin && !user.isModerator)) {
|
if (user == null || (!user.isAdmin && !user.isModerator)) {
|
||||||
throw new ApiError(meta.errors.gtlDisabled);
|
throw new ApiError('TIMELINE_DISABLED');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['TIMELINE_DISABLED'],
|
||||||
stlDisabled: {
|
|
||||||
message: 'Hybrid timeline has been disabled.',
|
|
||||||
code: 'STL_DISABLED',
|
|
||||||
id: '620763f4-f621-4533-ab33-0577a1a3c342',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -61,7 +55,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const m = await fetchMeta();
|
const m = await fetchMeta();
|
||||||
if (m.disableLocalTimeline && (!user.isAdmin && !user.isModerator)) {
|
if (m.disableLocalTimeline && (!user.isAdmin && !user.isModerator)) {
|
||||||
throw new ApiError(meta.errors.stlDisabled);
|
throw new ApiError('TIMELINE_DISABLED');
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region Construct query
|
//#region Construct query
|
||||||
|
|
|
@ -26,13 +26,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['TIMELINE_DISABLED'],
|
||||||
ltlDisabled: {
|
|
||||||
message: 'Local timeline has been disabled.',
|
|
||||||
code: 'LTL_DISABLED',
|
|
||||||
id: '45a6eb02-7695-4393-b023-dd3be9aaaefd',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -61,7 +55,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
const m = await fetchMeta();
|
const m = await fetchMeta();
|
||||||
if (m.disableLocalTimeline) {
|
if (m.disableLocalTimeline) {
|
||||||
if (user == null || (!user.isAdmin && !user.isModerator)) {
|
if (user == null || (!user.isAdmin && !user.isModerator)) {
|
||||||
throw new ApiError(meta.errors.ltlDisabled);
|
throw new ApiError('TIMELINE_DISABLED');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,50 +19,14 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:votes',
|
kind: 'write:votes',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE', 'INVALID_CHOICE', 'ALREADY_VOTED', 'EXPIRED_POLL', 'BLOCKED'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: 'ecafbd2e-c283-4d6d-aecb-1a0a33b75396',
|
|
||||||
},
|
|
||||||
|
|
||||||
noPoll: {
|
|
||||||
message: 'The note does not attach a poll.',
|
|
||||||
code: 'NO_POLL',
|
|
||||||
id: '5f979967-52d9-4314-a911-1c673727f92f',
|
|
||||||
},
|
|
||||||
|
|
||||||
invalidChoice: {
|
|
||||||
message: 'Choice ID is invalid.',
|
|
||||||
code: 'INVALID_CHOICE',
|
|
||||||
id: 'e0cc9a04-f2e8-41e4-a5f1-4127293260cc',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyVoted: {
|
|
||||||
message: 'You have already voted.',
|
|
||||||
code: 'ALREADY_VOTED',
|
|
||||||
id: '0963fc77-efac-419b-9424-b391608dc6d8',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyExpired: {
|
|
||||||
message: 'The poll is already expired.',
|
|
||||||
code: 'ALREADY_EXPIRED',
|
|
||||||
id: '1022a357-b085-4054-9083-8f8de358337e',
|
|
||||||
},
|
|
||||||
|
|
||||||
youHaveBeenBlocked: {
|
|
||||||
message: 'You cannot vote this poll because you have been blocked by this user.',
|
|
||||||
code: 'YOU_HAVE_BEEN_BLOCKED',
|
|
||||||
id: '85a5377e-b1e9-4617-b0b9-5bea73331e49',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
noteId: { type: 'string', format: 'misskey:id' },
|
noteId: { type: 'string', format: 'misskey:id' },
|
||||||
choice: { type: 'integer' },
|
choice: { type: 'integer', minimum: 0 },
|
||||||
},
|
},
|
||||||
required: ['noteId', 'choice'],
|
required: ['noteId', 'choice'],
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -73,12 +37,12 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
// Get votee
|
// Get votee
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!note.hasPoll) {
|
if (!note.hasPoll) {
|
||||||
throw new ApiError(meta.errors.noPoll);
|
throw new ApiError('NO_SUCH_NOTE', 'The note exists but does not have a poll attached.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check blocking
|
// Check blocking
|
||||||
|
@ -87,19 +51,17 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
blockerId: note.userId,
|
blockerId: note.userId,
|
||||||
blockeeId: user.id,
|
blockeeId: user.id,
|
||||||
});
|
});
|
||||||
if (block) {
|
if (block) throw new ApiError('BLOCKED');
|
||||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const poll = await Polls.findOneByOrFail({ noteId: note.id });
|
const poll = await Polls.findOneByOrFail({ noteId: note.id });
|
||||||
|
|
||||||
if (poll.expiresAt && poll.expiresAt < createdAt) {
|
if (poll.expiresAt && poll.expiresAt < createdAt) {
|
||||||
throw new ApiError(meta.errors.alreadyExpired);
|
throw new ApiError('EXPIRED_POLL');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll.choices[ps.choice] == null) {
|
if (poll.choices[ps.choice] == null) {
|
||||||
throw new ApiError(meta.errors.invalidChoice);
|
throw new ApiError('INVALID_CHOICE', `There are only ${poll.choices.length} choices.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if already voted
|
// if already voted
|
||||||
|
@ -111,10 +73,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
if (exist.length) {
|
if (exist.length) {
|
||||||
if (poll.multiple) {
|
if (poll.multiple) {
|
||||||
if (exist.some(x => x.choice === ps.choice)) {
|
if (exist.some(x => x.choice === ps.choice)) {
|
||||||
throw new ApiError(meta.errors.alreadyVoted);
|
throw new ApiError('ALREADY_VOTED', 'This is a multiple choice poll, but you already voted for that option.');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ApiError(meta.errors.alreadyVoted);
|
throw new ApiError('ALREADY_VOTED', 'This is a single choice poll.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '263fff3d-d0e1-4af4-bea7-8408059b451a',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -53,7 +47,7 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
// check note visibility
|
// check note visibility
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:reactions',
|
kind: 'write:reactions',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE', 'ALREADY_REACTED', 'BLOCKED'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '033d0620-5bfe-4027-965d-980b0c85a3ea',
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyReacted: {
|
|
||||||
message: 'You are already reacting to that note.',
|
|
||||||
code: 'ALREADY_REACTED',
|
|
||||||
id: '71efcf98-86d6-4e2b-b2ad-9d032369366b',
|
|
||||||
},
|
|
||||||
|
|
||||||
youHaveBeenBlocked: {
|
|
||||||
message: 'You cannot react this note because you have been blocked by this user.',
|
|
||||||
code: 'YOU_HAVE_BEEN_BLOCKED',
|
|
||||||
id: '20ef5475-9f38-4e4c-bd33-de6d979498ec',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -43,12 +25,12 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
await createReaction(user, note, ps.reaction).catch(e => {
|
await createReaction(user, note, ps.reaction).catch(e => {
|
||||||
if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') throw new ApiError(meta.errors.alreadyReacted);
|
if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') throw new ApiError('ALREADY_REACTED');
|
||||||
if (e.id === 'e70412a4-7197-4726-8e74-f3e0deb92aa7') throw new ApiError(meta.errors.youHaveBeenBlocked);
|
if (e.id === 'e70412a4-7197-4726-8e74-f3e0deb92aa7') throw new ApiError('BLOCKED');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -17,19 +17,7 @@ export const meta = {
|
||||||
minInterval: 3 * SECOND,
|
minInterval: 3 * SECOND,
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE', 'NOT_REACTED'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '764d9fce-f9f2-4a0e-92b1-6ceac9a7ad37',
|
|
||||||
},
|
|
||||||
|
|
||||||
notReacted: {
|
|
||||||
message: 'You are not reacting to that note.',
|
|
||||||
code: 'NOT_REACTED',
|
|
||||||
id: '92f4426d-4196-4125-aa5b-02943e2ec8fc',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -43,11 +31,11 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
await deleteReaction(user, note).catch(e => {
|
await deleteReaction(user, note).catch(e => {
|
||||||
if (e.id === '60527ec9-b4cb-4a88-a6bd-32d3ad26817d') throw new ApiError(meta.errors.notReacted);
|
if (e.id === '60527ec9-b4cb-4a88-a6bd-32d3ad26817d') throw new ApiError('NOT_REACTED');
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,13 +22,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '12908022-2e21-46cd-ba6a-3edaf6093f46',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -45,7 +39,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,6 @@ export const meta = {
|
||||||
ref: 'Note',
|
ref: 'Note',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
|
|
@ -14,13 +14,7 @@ export const meta = {
|
||||||
ref: 'Note',
|
ref: 'Note',
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '24fcbfc6-2e37-42b6-8388-c29b3861a08d',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -34,7 +28,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -42,7 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
// FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774)
|
// FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774)
|
||||||
detail: true,
|
detail: true,
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: '5ff67ada-ed3b-2e71-8e87-a1a421e177d2',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -41,7 +35,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: 'bddd57ac-ceb3-b29d-4334-86ea5fae481a',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -30,7 +24,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -55,13 +55,7 @@ export const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: ['NO_SUCH_NOTE'],
|
||||||
noSuchNote: {
|
|
||||||
message: 'No such note.',
|
|
||||||
code: 'NO_SUCH_NOTE',
|
|
||||||
id: 'bea9b03f-36e0-49c5-a4db-627a029f8971',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// List of permitted languages from https://www.deepl.com/docs-api/translate-text/translate-text/
|
// List of permitted languages from https://www.deepl.com/docs-api/translate-text/translate-text/
|
||||||
|
@ -116,7 +110,7 @@ export const paramDef = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const note = await getNote(ps.noteId, user).catch(err => {
|
const note = await getNote(ps.noteId, user).catch(err => {
|
||||||
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue