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;
|
||||
|
||||
const error = (e: ApiError): void => {
|
||||
ctx.status = e.httpStatusCode ?? 500;
|
||||
ctx.status = e.httpStatusCode;
|
||||
if (e.httpStatusCode === 401) {
|
||||
ctx.response.set('WWW-Authenticate', 'Bearer');
|
||||
}
|
||||
|
@ -47,12 +47,7 @@ export async function handler(endpoint: IEndpoint, ctx: Koa.Context): Promise<vo
|
|||
});
|
||||
}).catch(e => {
|
||||
if (e instanceof AuthenticationError) {
|
||||
error({
|
||||
message: 'Authentication failed: ' + e.message,
|
||||
code: 'AUTHENTICATION_FAILED',
|
||||
id: 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14',
|
||||
httpStatusCode: 401,
|
||||
});
|
||||
error(new ApiError('AUTHENTICATION_FAILED', e.message));
|
||||
} else {
|
||||
error(new ApiError());
|
||||
}
|
||||
|
|
|
@ -8,29 +8,16 @@ import endpoints, { IEndpointMeta } from './endpoints.js';
|
|||
import { ApiError } from './error.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) => {
|
||||
const isSecure = user != null && token == null;
|
||||
const isModerator = user != null && (user.isModerator || user.isAdmin);
|
||||
|
||||
const ep = endpoints.find(e => e.name === endpoint);
|
||||
|
||||
if (ep == null) {
|
||||
throw new ApiError({
|
||||
message: 'No such endpoint.',
|
||||
code: 'NO_SUCH_ENDPOINT',
|
||||
id: 'f8080b67-5f9c-4eb7-8c18-7f1eeae8f709',
|
||||
httpStatusCode: 404,
|
||||
});
|
||||
}
|
||||
if (ep == null) throw new ApiError('NO_SUCH_ENDPOINT');
|
||||
|
||||
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) {
|
||||
|
@ -50,47 +37,28 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
|
|||
|
||||
// Rate limit
|
||||
await limiter(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor).catch(e => {
|
||||
throw new ApiError({
|
||||
message: 'Rate limit exceeded. Please try again later.',
|
||||
code: 'RATE_LIMIT_EXCEEDED',
|
||||
id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef',
|
||||
httpStatusCode: 429,
|
||||
});
|
||||
throw new ApiError('RATE_LIMIT_EXCEEDED');
|
||||
});
|
||||
}
|
||||
|
||||
if (ep.meta.requireCredential && user == null) {
|
||||
throw new ApiError({
|
||||
message: 'Credential required.',
|
||||
code: 'CREDENTIAL_REQUIRED',
|
||||
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
|
||||
httpStatusCode: 401,
|
||||
});
|
||||
throw new ApiError('AUTHENTICATION_REQUIRED');
|
||||
}
|
||||
|
||||
if (ep.meta.requireCredential && user!.isSuspended) {
|
||||
throw new ApiError({
|
||||
message: 'Your account has been suspended.',
|
||||
code: 'YOUR_ACCOUNT_SUSPENDED',
|
||||
id: 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370',
|
||||
httpStatusCode: 403,
|
||||
});
|
||||
throw new ApiError('SUSPENDED');
|
||||
}
|
||||
|
||||
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) {
|
||||
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)) {
|
||||
throw new ApiError({
|
||||
message: 'Your app does not have the necessary permissions to use this endpoint.',
|
||||
code: 'PERMISSION_DENIED',
|
||||
id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838',
|
||||
});
|
||||
throw new ApiError('ACCESS_DENIED', 'This operation requires privileges which this token does not grant.');
|
||||
}
|
||||
|
||||
// Cast non JSON input
|
||||
|
@ -101,11 +69,7 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
|
|||
try {
|
||||
data[k] = JSON.parse(data[k]);
|
||||
} catch (e) {
|
||||
throw new ApiError({
|
||||
message: 'Invalid param.',
|
||||
code: 'INVALID_PARAM',
|
||||
id: '0b5f1631-7c1a-41a6-b399-cce335f34d85',
|
||||
}, {
|
||||
throw new ApiError('INVALID_PARAM', {
|
||||
param: k,
|
||||
reason: `cannot cast to ${param.type}`,
|
||||
});
|
||||
|
@ -129,7 +93,7 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
|
|||
stack: e.stack,
|
||||
},
|
||||
});
|
||||
throw new ApiError(null, {
|
||||
throw new ApiError('INTERNAL_ERROR', {
|
||||
e: {
|
||||
message: e.message,
|
||||
code: e.name,
|
||||
|
|
|
@ -24,25 +24,13 @@ export async function signup(opts: {
|
|||
|
||||
// Validate username
|
||||
if (!Users.validateLocalUsername(username)) {
|
||||
throw new ApiError({
|
||||
message: 'This username is invalid.',
|
||||
code: 'INVALID_USERNAME',
|
||||
id: 'ece89f3c-d845-4d9a-850b-1735285e8cd4',
|
||||
kind: 'client',
|
||||
httpStatusCode: 400,
|
||||
});
|
||||
throw new ApiError('INVALID_USERNAME');
|
||||
}
|
||||
|
||||
if (password != null && passwordHash == null) {
|
||||
// Validate password
|
||||
if (!Users.validatePassword(password)) {
|
||||
throw new ApiError({
|
||||
message: 'This password is invalid.',
|
||||
code: 'INVALID_PASSWORD',
|
||||
id: 'a941905b-fe7b-43e2-8ecd-50ad3a2287ab',
|
||||
kind: 'client',
|
||||
httpStatusCode: 400,
|
||||
});
|
||||
throw new ApiError('INVALID_PASSWORD');
|
||||
}
|
||||
|
||||
// Generate hash of password
|
||||
|
@ -53,22 +41,14 @@ export async function signup(opts: {
|
|||
// Generate secret
|
||||
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
|
||||
if (await Users.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull() })) {
|
||||
throw new ApiError(duplicateUsernameError);
|
||||
throw new ApiError('USED_USERNAME');
|
||||
}
|
||||
|
||||
// Check deleted username duplication
|
||||
if (await UsedUsernames.findOneBy({ username: username.toLowerCase() })) {
|
||||
throw new ApiError(duplicateUsernameError);
|
||||
throw new ApiError('USED_USERNAME');
|
||||
}
|
||||
|
||||
const keyPair = await new Promise<string[]>((res, rej) =>
|
||||
|
@ -97,7 +77,7 @@ export async function signup(opts: {
|
|||
host: IsNull(),
|
||||
});
|
||||
|
||||
if (exist) throw new ApiError(duplicateUsernameError);
|
||||
if (exist) throw new ApiError('USED_USERNAME');
|
||||
|
||||
account = await transactionalEntityManager.save(new User({
|
||||
id: genId(),
|
||||
|
|
|
@ -28,22 +28,16 @@ export default function <T extends IEndpointMeta, Ps extends Schema>(meta: T, pa
|
|||
fs.unlink(file.path, () => {});
|
||||
}
|
||||
|
||||
if (meta.requireFile && file == null) return Promise.reject(new ApiError({
|
||||
message: 'File required.',
|
||||
code: 'FILE_REQUIRED',
|
||||
id: '4267801e-70d1-416a-b011-4ee502885d8b',
|
||||
}));
|
||||
if (meta.requireFile && file == null) {
|
||||
return Promise.reject(new ApiError('FILE_REQUIRED'));
|
||||
}
|
||||
|
||||
const valid = validate(params);
|
||||
if (!valid) {
|
||||
if (file) cleanup();
|
||||
|
||||
const errors = validate.errors!;
|
||||
const err = new ApiError({
|
||||
message: 'Invalid param.',
|
||||
code: 'INVALID_PARAM',
|
||||
id: '3d81ceae-475f-4600-b2a8-2bc116157532',
|
||||
}, {
|
||||
const err = new ApiError('INVALID_PARAM', {
|
||||
param: errors[0].schemaPath,
|
||||
reason: errors[0].message,
|
||||
});
|
||||
|
|
|
@ -8,13 +8,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchAnnouncement: {
|
||||
message: 'No such announcement.',
|
||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
||||
id: 'ecad8040-a276-4e85-bda9-015a708d291e',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_ANNOUNCEMENT'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -29,7 +23,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, me) => {
|
||||
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);
|
||||
});
|
||||
|
|
|
@ -8,13 +8,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchAnnouncement: {
|
||||
message: 'No such announcement.',
|
||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
||||
id: 'd3aae5a7-6372-4cb4-b61c-f511ffc2d7cc',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_ANNOUNCEMENT'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -32,7 +26,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, me) => {
|
||||
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, {
|
||||
updatedAt: new Date(),
|
||||
|
|
|
@ -8,13 +8,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_FILE'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -180,9 +174,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
}],
|
||||
});
|
||||
|
||||
if (file == null) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||
|
||||
return file;
|
||||
});
|
||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -34,7 +28,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, me) => {
|
||||
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)}_`;
|
||||
|
||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchEmoji: {
|
||||
message: 'No such emoji.',
|
||||
code: 'NO_SUCH_EMOJI',
|
||||
id: 'e2785b66-dca3-4087-9cac-b93c541cc425',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_EMOJI', 'INTERNAL_ERROR'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -46,9 +40,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, me) => {
|
||||
const emoji = await Emojis.findOneBy({ id: ps.emojiId });
|
||||
|
||||
if (emoji == null) {
|
||||
throw new ApiError(meta.errors.noSuchEmoji);
|
||||
}
|
||||
if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');
|
||||
|
||||
let driveFile: DriveFile;
|
||||
|
||||
|
@ -56,7 +48,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
// Create file
|
||||
driveFile = await uploadFromUrl({ url: emoji.originalUrl, user: null, force: true });
|
||||
} catch (e) {
|
||||
throw new ApiError();
|
||||
throw new ApiError('INTERNAL_ERROR', e);
|
||||
}
|
||||
|
||||
const copied = await Emojis.insert({
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchEmoji: {
|
||||
message: 'No such emoji.',
|
||||
code: 'NO_SUCH_EMOJI',
|
||||
id: 'be83669b-773a-44b7-b1f8-e5e5170ac3c2',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_EMOJI'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -31,7 +25,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, me) => {
|
||||
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);
|
||||
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchEmoji: {
|
||||
message: 'No such emoji.',
|
||||
code: 'NO_SUCH_EMOJI',
|
||||
id: '684dec9d-a8c2-4364-9aa8-456c49cb1dc8',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_EMOJI'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -39,7 +33,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps) => {
|
||||
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, {
|
||||
updatedAt: new Date(),
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
invalidUrl: {
|
||||
message: 'Invalid URL',
|
||||
code: 'INVALID_URL',
|
||||
id: 'fb8c92d3-d4e5-44e7-b3d4-800d5cef8b2c',
|
||||
},
|
||||
},
|
||||
errors: ['INVALID_URL'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -58,8 +52,8 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
try {
|
||||
if (new URL(ps.inbox).protocol !== 'https:') throw new Error('https only');
|
||||
} catch {
|
||||
throw new ApiError(meta.errors.invalidUrl);
|
||||
} catch (e) {
|
||||
throw new ApiError('INVALID_URL', e);
|
||||
}
|
||||
|
||||
return await addRelay(ps.inbox);
|
||||
|
|
|
@ -11,19 +11,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER_LIST', 'NO_SUCH_GROUP'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -71,18 +59,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (userList == null) {
|
||||
throw new ApiError(meta.errors.noSuchUserList);
|
||||
}
|
||||
if (userList == null) throw new ApiError('NO_SUCH_USER_LIST');
|
||||
} else if (ps.src === 'group' && ps.userGroupId) {
|
||||
userGroupJoining = await UserGroupJoinings.findOneBy({
|
||||
userGroupId: ps.userGroupId,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (userGroupJoining == null) {
|
||||
throw new ApiError(meta.errors.noSuchUserGroup);
|
||||
}
|
||||
if (userGroupJoining == null) throw new ApiError('NO_SUCH_GROUP');
|
||||
}
|
||||
|
||||
const antenna = await Antennas.insert({
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchAntenna: {
|
||||
message: 'No such antenna.',
|
||||
code: 'NO_SUCH_ANTENNA',
|
||||
id: 'b34dcf9d-348f-44bb-99d0-6c9314cfe2df',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_ANTENNA'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (antenna == null) {
|
||||
throw new ApiError(meta.errors.noSuchAntenna);
|
||||
}
|
||||
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||
|
||||
await Antennas.delete(antenna.id);
|
||||
|
||||
|
|
|
@ -14,13 +14,7 @@ export const meta = {
|
|||
|
||||
kind: 'read:account',
|
||||
|
||||
errors: {
|
||||
noSuchAntenna: {
|
||||
message: 'No such antenna.',
|
||||
code: 'NO_SUCH_ANTENNA',
|
||||
id: '850926e0-fd3b-49b6-b69a-b28a5dbd82fe',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_ANTENNA'],
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
|
@ -53,9 +47,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (antenna == null) {
|
||||
throw new ApiError(meta.errors.noSuchAntenna);
|
||||
}
|
||||
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||
|
||||
const query = makePaginationQuery(Notes.createQueryBuilder('note'),
|
||||
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
|
||||
kind: 'read:account',
|
||||
|
||||
errors: {
|
||||
noSuchAntenna: {
|
||||
message: 'No such antenna.',
|
||||
code: 'NO_SUCH_ANTENNA',
|
||||
id: 'c06569fb-b025-4f23-b22d-1fcd20d2816b',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_ANTENNA'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -40,9 +34,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
userId: me.id,
|
||||
});
|
||||
|
||||
if (antenna == null) {
|
||||
throw new ApiError(meta.errors.noSuchAntenna);
|
||||
}
|
||||
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||
|
||||
return await Antennas.pack(antenna);
|
||||
});
|
||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_ANTENNA', 'NO_SUCH_USER_LIST', 'NO_SUCH_GROUP'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -74,9 +56,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (antenna == null) {
|
||||
throw new ApiError(meta.errors.noSuchAntenna);
|
||||
}
|
||||
if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
|
||||
|
||||
let userList;
|
||||
let userGroupJoining;
|
||||
|
@ -87,18 +67,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (userList == null) {
|
||||
throw new ApiError(meta.errors.noSuchUserList);
|
||||
}
|
||||
if (userList == null) throw new ApiError('NO_SUCH_USER_LIST');
|
||||
} else if (ps.src === 'group' && ps.userGroupId) {
|
||||
userGroupJoining = await UserGroupJoinings.findOneBy({
|
||||
userGroupId: ps.userGroupId,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (userGroupJoining == null) {
|
||||
throw new ApiError(meta.errors.noSuchUserGroup);
|
||||
}
|
||||
if (userGroupJoining == null) throw new ApiError('NO_SUCH_GROUP');
|
||||
}
|
||||
|
||||
await Antennas.update(antenna.id, {
|
||||
|
|
|
@ -12,9 +12,6 @@ export const meta = {
|
|||
max: 30,
|
||||
},
|
||||
|
||||
errors: {
|
||||
},
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
|
|
|
@ -24,13 +24,7 @@ export const meta = {
|
|||
max: 30,
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchObject: {
|
||||
message: 'No such object.',
|
||||
code: 'NO_SUCH_OBJECT',
|
||||
id: 'dc94d745-1262-4e63-a17d-fecaa57efc82',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_OBJECT'],
|
||||
|
||||
res: {
|
||||
optional: false, nullable: false,
|
||||
|
@ -83,7 +77,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
if (object) {
|
||||
return object;
|
||||
} 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 = {
|
||||
tags: ['app'],
|
||||
|
||||
errors: {
|
||||
noSuchApp: {
|
||||
message: 'No such app.',
|
||||
code: 'NO_SUCH_APP',
|
||||
id: 'dce83913-2dc6-4093-8a7b-71dbb11718a3',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_APP'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -33,14 +27,12 @@ export default define(meta, paramDef, async (ps, user, token) => {
|
|||
const isSecure = user != null && token == null;
|
||||
|
||||
// Lookup app
|
||||
const ap = await Apps.findOneBy({ id: ps.appId });
|
||||
const app = await Apps.findOneBy({ id: ps.appId });
|
||||
|
||||
if (ap == null) {
|
||||
throw new ApiError(meta.errors.noSuchApp);
|
||||
}
|
||||
if (app == null) throw new ApiError('NO_SUCH_APP');
|
||||
|
||||
return await Apps.pack(ap, user, {
|
||||
return await Apps.pack(app, user, {
|
||||
detail: true,
|
||||
includeSecret: isSecure && (ap.userId === user!.id),
|
||||
includeSecret: isSecure && (app.userId === user!.id),
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,13 +12,7 @@ export const meta = {
|
|||
|
||||
secure: true,
|
||||
|
||||
errors: {
|
||||
noSuchSession: {
|
||||
message: 'No such session.',
|
||||
code: 'NO_SUCH_SESSION',
|
||||
id: '9c72d8de-391a-43c1-9d06-08d29efde8df',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_SESSION'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -35,9 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const session = await AuthSessions
|
||||
.findOneBy({ token: ps.token });
|
||||
|
||||
if (session == null) {
|
||||
throw new ApiError(meta.errors.noSuchSession);
|
||||
}
|
||||
if (session == null) throw new ApiError('NO_SUCH_SESSION');
|
||||
|
||||
// Generate access token
|
||||
const accessToken = secureRndstr(32, true);
|
||||
|
|
|
@ -26,13 +26,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchApp: {
|
||||
message: 'No such app.',
|
||||
code: 'NO_SUCH_APP',
|
||||
id: '92f93e63-428e-4f2f-a5a4-39e1407fe998',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_APP'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -51,7 +45,7 @@ export default define(meta, paramDef, async (ps) => {
|
|||
});
|
||||
|
||||
if (app == null) {
|
||||
throw new ApiError(meta.errors.noSuchApp);
|
||||
throw new ApiError('NO_SUCH_APP');
|
||||
}
|
||||
|
||||
// Generate token
|
||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
|||
|
||||
requireCredential: false,
|
||||
|
||||
errors: {
|
||||
noSuchSession: {
|
||||
message: 'No such session.',
|
||||
code: 'NO_SUCH_SESSION',
|
||||
id: 'bd72c97d-eba7-4adb-a467-f171b8847250',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_SESSION'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -52,9 +46,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
token: ps.token,
|
||||
});
|
||||
|
||||
if (session == null) {
|
||||
throw new ApiError(meta.errors.noSuchSession);
|
||||
}
|
||||
if (session == null) throw new ApiError('NO_SUCH_SESSION');
|
||||
|
||||
return await AuthSessions.pack(session, user);
|
||||
});
|
||||
|
|
|
@ -24,25 +24,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchApp: {
|
||||
message: 'No such app.',
|
||||
code: 'NO_SUCH_APP',
|
||||
id: 'fcab192a-2c5a-43b7-8ad8-9b7054d8d40d',
|
||||
},
|
||||
|
||||
noSuchSession: {
|
||||
message: 'No such session.',
|
||||
code: 'NO_SUCH_SESSION',
|
||||
id: '5b5a1503-8bc8-4bd0-8054-dc189e8cdcb3',
|
||||
},
|
||||
|
||||
pendingSession: {
|
||||
message: 'This session is not completed yet.',
|
||||
code: 'PENDING_SESSION',
|
||||
id: '8c8a4145-02cc-4cca-8e66-29ba60445a8e',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_APP', 'NO_SUCH_SESSION', 'PENDING_SESSION'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -61,9 +43,7 @@ export default define(meta, paramDef, async (ps) => {
|
|||
secret: ps.appSecret,
|
||||
});
|
||||
|
||||
if (app == null) {
|
||||
throw new ApiError(meta.errors.noSuchApp);
|
||||
}
|
||||
if (app == null) throw new ApiError('NO_SUCH_APP');
|
||||
|
||||
// Fetch token
|
||||
const session = await AuthSessions.findOneBy({
|
||||
|
@ -71,13 +51,9 @@ export default define(meta, paramDef, async (ps) => {
|
|||
appId: app.id,
|
||||
});
|
||||
|
||||
if (session == null) {
|
||||
throw new ApiError(meta.errors.noSuchSession);
|
||||
}
|
||||
if (session == null) throw new ApiError('NO_SUCH_SESSION');
|
||||
|
||||
if (session.userId == null) {
|
||||
throw new ApiError(meta.errors.pendingSession);
|
||||
}
|
||||
if (session.userId == null) throw new ApiError('PENDING_SESSION');
|
||||
|
||||
// Lookup access token
|
||||
const accessToken = await AccessTokens.findOneByOrFail({
|
||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:blocks',
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '7cc4f851-e2f1-4621-9633-ec9e1d00c01e',
|
||||
},
|
||||
|
||||
blockeeIsYourself: {
|
||||
message: 'Blockee is yourself.',
|
||||
code: 'BLOCKEE_IS_YOURSELF',
|
||||
id: '88b19138-f28d-42c0-8499-6a31bbd0fdc6',
|
||||
},
|
||||
|
||||
alreadyBlocking: {
|
||||
message: 'You are already blocking that user.',
|
||||
code: 'ALREADY_BLOCKING',
|
||||
id: '787fed64-acb9-464a-82eb-afbd745b9614',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER', 'BLOCKEE_IS_YOURSELF', 'ALREADY_BLOCKING'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const blocker = await Users.findOneByOrFail({ id: user.id });
|
||||
|
||||
// 自分自身
|
||||
if (user.id === ps.userId) {
|
||||
throw new ApiError(meta.errors.blockeeIsYourself);
|
||||
}
|
||||
if (user.id === ps.userId) throw new ApiError('BLOCKEE_IS_YOURSELF');
|
||||
|
||||
// Get blockee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
blockeeId: blockee.id,
|
||||
});
|
||||
|
||||
if (exist != null) {
|
||||
throw new ApiError(meta.errors.alreadyBlocking);
|
||||
}
|
||||
if (exist != null) throw new ApiError('ALREADY_BLOCKING');
|
||||
|
||||
await create(blocker, blockee);
|
||||
|
||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:blocks',
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '8621d8bf-c358-4303-a066-5ea78610eb3f',
|
||||
},
|
||||
|
||||
blockeeIsYourself: {
|
||||
message: 'Blockee is yourself.',
|
||||
code: 'BLOCKEE_IS_YOURSELF',
|
||||
id: '06f6fac6-524b-473c-a354-e97a40ae6eac',
|
||||
},
|
||||
|
||||
notBlocking: {
|
||||
message: 'You are not blocking that user.',
|
||||
code: 'NOT_BLOCKING',
|
||||
id: '291b2efa-60c6-45c0-9f6a-045c8f9b02cd',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER', 'BLOCKEE_IS_YOURSELF', 'NOT_BLOCKING'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -54,16 +36,14 @@ export const paramDef = {
|
|||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const blocker = await Users.findOneByOrFail({ id: user.id });
|
||||
|
||||
// Check if the blockee is yourself
|
||||
if (user.id === ps.userId) {
|
||||
throw new ApiError(meta.errors.blockeeIsYourself);
|
||||
}
|
||||
if (user.id === ps.userId) throw new ApiError('BLOCKEE_IS_YOURSELF');
|
||||
|
||||
const blocker = await Users.findOneByOrFail({ id: user.id });
|
||||
|
||||
// Get blockee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
blockeeId: blockee.id,
|
||||
});
|
||||
|
||||
if (exist == null) {
|
||||
throw new ApiError(meta.errors.notBlocking);
|
||||
}
|
||||
if (exist == null) throw new ApiError('NOT_BLOCKING');
|
||||
|
||||
// Delete blocking
|
||||
await deleteBlocking(blocker, blockee);
|
||||
|
|
|
@ -17,13 +17,7 @@ export const meta = {
|
|||
ref: 'Channel',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -45,9 +39,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (banner == null) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
if (banner == null) throw new ApiError('NO_SUCH_FILE');
|
||||
}
|
||||
|
||||
const channel = await Channels.insert({
|
||||
|
|
|
@ -11,13 +11,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:channels',
|
||||
|
||||
errors: {
|
||||
noSuchChannel: {
|
||||
message: 'No such channel.',
|
||||
code: 'NO_SUCH_CHANNEL',
|
||||
id: 'c0031718-d573-4e85-928e-10039f1fbb68',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CHANNEL'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
id: ps.channelId,
|
||||
});
|
||||
|
||||
if (channel == null) {
|
||||
throw new ApiError(meta.errors.noSuchChannel);
|
||||
}
|
||||
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||
|
||||
await ChannelFollowings.insert({
|
||||
id: genId(),
|
||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
|||
ref: 'Channel',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchChannel: {
|
||||
message: 'No such channel.',
|
||||
code: 'NO_SUCH_CHANNEL',
|
||||
id: '6f6c314b-7486-4897-8966-c04a66a02923',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CHANNEL'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -36,9 +30,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
id: ps.channelId,
|
||||
});
|
||||
|
||||
if (channel == null) {
|
||||
throw new ApiError(meta.errors.noSuchChannel);
|
||||
}
|
||||
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||
|
||||
return await Channels.pack(channel, me);
|
||||
});
|
||||
|
|
|
@ -19,13 +19,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchChannel: {
|
||||
message: 'No such channel.',
|
||||
code: 'NO_SUCH_CHANNEL',
|
||||
id: '4d0eeeba-a02c-4c3c-9966-ef60d38d2e7f',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CHANNEL'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -47,9 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
id: ps.channelId,
|
||||
});
|
||||
|
||||
if (channel == null) {
|
||||
throw new ApiError(meta.errors.noSuchChannel);
|
||||
}
|
||||
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||
|
||||
//#region Construct query
|
||||
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:channels',
|
||||
|
||||
errors: {
|
||||
noSuchChannel: {
|
||||
message: 'No such channel.',
|
||||
code: 'NO_SUCH_CHANNEL',
|
||||
id: '19959ee9-0153-4c51-bbd9-a98c49dc59d6',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CHANNEL'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
id: ps.channelId,
|
||||
});
|
||||
|
||||
if (channel == null) {
|
||||
throw new ApiError(meta.errors.noSuchChannel);
|
||||
}
|
||||
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||
|
||||
await ChannelFollowings.delete({
|
||||
followerId: user.id,
|
||||
|
|
|
@ -15,25 +15,7 @@ export const meta = {
|
|||
ref: 'Channel',
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['ACCESS_DENIED', 'NO_SUCH_CHANNEL', 'NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -53,13 +35,9 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
id: ps.channelId,
|
||||
});
|
||||
|
||||
if (channel == null) {
|
||||
throw new ApiError(meta.errors.noSuchChannel);
|
||||
}
|
||||
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||
|
||||
if (channel.userId !== me.id) {
|
||||
throw new ApiError(meta.errors.accessDenied);
|
||||
}
|
||||
if (channel.userId !== me.id) throw new ApiError('ACCESS_DENIED', 'You are not the owner of this channel.');
|
||||
|
||||
// eslint:disable-next-line:no-unnecessary-initializer
|
||||
let banner = undefined;
|
||||
|
@ -69,9 +47,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
userId: me.id,
|
||||
});
|
||||
|
||||
if (banner == null) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
if (banner == null) throw new ApiError('NO_SUCH_FILE');
|
||||
} else if (ps.bannerId === null) {
|
||||
banner = null;
|
||||
}
|
||||
|
|
|
@ -11,25 +11,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['ALREADY_CLIPPED', 'NO_SUCH_CLIP', 'NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -48,12 +30,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (clip == null) {
|
||||
throw new ApiError(meta.errors.noSuchClip);
|
||||
}
|
||||
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -62,9 +42,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
clipId: clip.id,
|
||||
});
|
||||
|
||||
if (exist != null) {
|
||||
throw new ApiError(meta.errors.alreadyClipped);
|
||||
}
|
||||
if (exist != null) throw new ApiError('ALREADY_CLIPPED');
|
||||
|
||||
await ClipNotes.insert({
|
||||
id: genId(),
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchClip: {
|
||||
message: 'No such clip.',
|
||||
code: 'NO_SUCH_CLIP',
|
||||
id: '70ca08ba-6865-4630-b6fb-8494759aa754',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CLIP'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (clip == null) {
|
||||
throw new ApiError(meta.errors.noSuchClip);
|
||||
}
|
||||
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||
|
||||
await Clips.delete(clip.id);
|
||||
});
|
||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
|||
|
||||
kind: 'read:account',
|
||||
|
||||
errors: {
|
||||
noSuchClip: {
|
||||
message: 'No such clip.',
|
||||
code: 'NO_SUCH_CLIP',
|
||||
id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CLIP'],
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
|
@ -49,12 +43,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
id: ps.clipId,
|
||||
});
|
||||
|
||||
if (clip == null) {
|
||||
throw new ApiError(meta.errors.noSuchClip);
|
||||
}
|
||||
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||
|
||||
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)
|
||||
|
|
|
@ -10,26 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
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,
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CLIP', 'NO_SUCH_NOTE', 'NOT_CLIPPED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -48,12 +29,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (clip == null) {
|
||||
throw new ApiError(meta.errors.noSuchClip);
|
||||
}
|
||||
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -62,7 +41,5 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
clipId: clip.id,
|
||||
});
|
||||
|
||||
if (affected === 0) {
|
||||
throw new ApiError(meta.errors.notClipped);
|
||||
}
|
||||
if (affected === 0) throw new ApiError('NOT_CLIPPED');
|
||||
});
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
|
||||
kind: 'read:account',
|
||||
|
||||
errors: {
|
||||
noSuchClip: {
|
||||
message: 'No such clip.',
|
||||
code: 'NO_SUCH_CLIP',
|
||||
id: 'c3c5fe33-d62c-44d2-9ea5-d997703f5c20',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CLIP'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -39,12 +33,10 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
id: ps.clipId,
|
||||
});
|
||||
|
||||
if (clip == null) {
|
||||
throw new ApiError(meta.errors.noSuchClip);
|
||||
}
|
||||
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||
|
||||
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);
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchClip: {
|
||||
message: 'No such clip.',
|
||||
code: 'NO_SUCH_CLIP',
|
||||
id: 'b4d92d70-b216-46fa-9a3f-a8c811699257',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_CLIP'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -43,9 +37,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (clip == null) {
|
||||
throw new ApiError(meta.errors.noSuchClip);
|
||||
}
|
||||
if (clip == null) throw new ApiError('NO_SUCH_CLIP');
|
||||
|
||||
await Clips.update(clip.id, {
|
||||
name: ps.name,
|
||||
|
|
|
@ -21,13 +21,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'c118ece3-2e4b-4296-99d1-51756e32d232',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -46,9 +40,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (file == null) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||
|
||||
const notes = await Notes.createQueryBuilder('note')
|
||||
.where(':file = ANY(note.fileIds)', { file: file.id })
|
||||
|
|
|
@ -28,13 +28,7 @@ export const meta = {
|
|||
ref: 'DriveFile',
|
||||
},
|
||||
|
||||
errors: {
|
||||
invalidFileName: {
|
||||
message: 'Invalid file name.',
|
||||
code: 'INVALID_FILE_NAME',
|
||||
id: 'f449b209-0c60-4e51-84d5-29486263bfd4',
|
||||
},
|
||||
},
|
||||
errors: ['INTERNAL_ERROR', 'INVALID_FILE_NAME'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -60,7 +54,7 @@ export default define(meta, paramDef, async (ps, user, _, file, cleanup) => {
|
|||
} else if (name === 'blob') {
|
||||
name = null;
|
||||
} else if (!DriveFiles.validateFileName(name)) {
|
||||
throw new ApiError(meta.errors.invalidFileName);
|
||||
throw new ApiError('INVALID_FILE_NAME');
|
||||
}
|
||||
} else {
|
||||
name = null;
|
||||
|
@ -74,7 +68,7 @@ export default define(meta, paramDef, async (ps, user, _, file, cleanup) => {
|
|||
if (e instanceof Error || typeof e === 'string') {
|
||||
apiLogger.error(e);
|
||||
}
|
||||
throw new ApiError();
|
||||
throw new ApiError('INTERNAL_ERROR');
|
||||
} finally {
|
||||
cleanup!();
|
||||
}
|
||||
|
|
|
@ -13,19 +13,7 @@ export const meta = {
|
|||
|
||||
description: 'Delete an existing drive file.',
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: '908939ec-e52b-4458-b395-1025195cea58',
|
||||
},
|
||||
|
||||
accessDenied: {
|
||||
message: 'Access denied.',
|
||||
code: 'ACCESS_DENIED',
|
||||
id: '5eb8d909-2540-4970-90b8-dd6f86088121',
|
||||
},
|
||||
},
|
||||
errors: ['ACCESS_DENIED', 'NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -40,12 +28,10 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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 ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
|
||||
throw new ApiError(meta.errors.accessDenied);
|
||||
throw new ApiError('ACCESS_DENIED');
|
||||
}
|
||||
|
||||
// Delete
|
||||
|
|
|
@ -18,19 +18,7 @@ export const meta = {
|
|||
ref: 'DriveFile',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: '067bc436-2718-4795-b0fb-ecbe43949e31',
|
||||
},
|
||||
|
||||
accessDenied: {
|
||||
message: 'Access denied.',
|
||||
code: 'ACCESS_DENIED',
|
||||
id: '25b73c73-68b1-41d0-bad1-381cfdf6579f',
|
||||
},
|
||||
},
|
||||
errors: ['ACCESS_DENIED', 'NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -69,12 +57,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
});
|
||||
}
|
||||
|
||||
if (file == null) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||
|
||||
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, {
|
||||
|
|
|
@ -12,31 +12,7 @@ export const meta = {
|
|||
|
||||
description: 'Update the properties of a drive file.',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['ACCESS_DENIED', 'INVALID_FILE_NAME', 'NO_SUCH_FILE', 'NO_SUCH_FOLDER'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -61,17 +37,15 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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 ((!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 (!DriveFiles.validateFileName(file.name)) {
|
||||
throw new ApiError(meta.errors.invalidFileName);
|
||||
throw new ApiError('INVALID_FILE_NAME');
|
||||
}
|
||||
|
||||
if (ps.comment !== undefined) file.comment = ps.comment;
|
||||
|
@ -87,9 +61,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (folder == null) {
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||
|
||||
file.folderId = folder.id;
|
||||
}
|
||||
|
|
|
@ -11,13 +11,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:drive',
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: '53326628-a00d-40a6-a3cd-8975105c0f95',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_FOLDER'],
|
||||
|
||||
res: {
|
||||
type: 'object' as const,
|
||||
|
@ -46,9 +40,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (parent == null) {
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
if (parent == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||
}
|
||||
|
||||
// Create folder
|
||||
|
|
|
@ -10,19 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:drive',
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: '1069098f-c281-440f-b085-f9932edbe091',
|
||||
},
|
||||
|
||||
hasChildFilesOrFolders: {
|
||||
message: 'This folder has child files or folders.',
|
||||
code: 'HAS_CHILD_FILES_OR_FOLDERS',
|
||||
id: 'b0fc8a17-963c-405d-bfbc-859a487295e1',
|
||||
},
|
||||
},
|
||||
errors: ['HAS_CHILD_FILES_OR_FOLDERS', 'NO_SUCH_FOLDER'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -41,9 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (folder == null) {
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||
|
||||
const [childFoldersCount, childFilesCount] = await Promise.all([
|
||||
DriveFolders.countBy({ parentId: folder.id }),
|
||||
|
@ -51,7 +37,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
]);
|
||||
|
||||
if (childFoldersCount !== 0 || childFilesCount !== 0) {
|
||||
throw new ApiError(meta.errors.hasChildFilesOrFolders);
|
||||
throw new ApiError('HAS_CHILD_FILES_OR_FOLDERS');
|
||||
}
|
||||
|
||||
await DriveFolders.delete(folder.id);
|
||||
|
|
|
@ -15,13 +15,7 @@ export const meta = {
|
|||
ref: 'DriveFolder',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: 'd74ab9eb-bb09-4bba-bf24-fb58f761e1e9',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_FOLDER'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -40,9 +34,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (folder == null) {
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||
|
||||
return await DriveFolders.pack(folder, {
|
||||
detail: true,
|
||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:drive',
|
||||
|
||||
errors: {
|
||||
noSuchFolder: {
|
||||
message: 'No such folder.',
|
||||
code: 'NO_SUCH_FOLDER',
|
||||
id: 'f7974dac-2c0d-4a27-926e-23583b28e98e',
|
||||
},
|
||||
|
||||
noSuchParentFolder: {
|
||||
message: 'No such parent folder.',
|
||||
code: 'NO_SUCH_PARENT_FOLDER',
|
||||
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1',
|
||||
},
|
||||
|
||||
recursiveNesting: {
|
||||
message: 'It can not be structured like nesting folders recursively.',
|
||||
code: 'NO_SUCH_PARENT_FOLDER',
|
||||
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_FOLDER', 'NO_SUCH_PARENT_FOLDER', 'RECURSIVE_FOLDER'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -55,15 +37,13 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (folder == null) {
|
||||
throw new ApiError(meta.errors.noSuchFolder);
|
||||
}
|
||||
if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
|
||||
|
||||
if (ps.name) folder.name = ps.name;
|
||||
|
||||
if (ps.parentId !== undefined) {
|
||||
if (ps.parentId === folder.id) {
|
||||
throw new ApiError(meta.errors.recursiveNesting);
|
||||
throw new ApiError('RECURSIVE_FOLDER');
|
||||
} else if (ps.parentId === null) {
|
||||
folder.parentId = null;
|
||||
} else {
|
||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (parent == null) {
|
||||
throw new ApiError(meta.errors.noSuchParentFolder);
|
||||
}
|
||||
if (parent == null) throw new ApiError('NO_SUCH_PARENT_FOLDER');
|
||||
|
||||
// Check if the circular reference will occur
|
||||
async function checkCircle(folderId: string): Promise<boolean> {
|
||||
|
@ -95,7 +73,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
if (parent.parentId !== null) {
|
||||
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',
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5',
|
||||
},
|
||||
|
||||
followeeIsYourself: {
|
||||
message: 'Followee is yourself.',
|
||||
code: 'FOLLOWEE_IS_YOURSELF',
|
||||
id: '26fbe7bb-a331-4857-af17-205b426669a9',
|
||||
},
|
||||
|
||||
alreadyFollowing: {
|
||||
message: 'You are already following that user.',
|
||||
code: 'ALREADY_FOLLOWING',
|
||||
id: '35387507-38c7-4cb9-9197-300b93783fa0',
|
||||
},
|
||||
|
||||
blocking: {
|
||||
message: 'You are blocking that user.',
|
||||
code: 'BLOCKING',
|
||||
id: '4e2206ec-aa4f-4960-b865-6c23ac38e2d9',
|
||||
},
|
||||
|
||||
blocked: {
|
||||
message: 'You are blocked by that user.',
|
||||
code: 'BLOCKED',
|
||||
id: 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0',
|
||||
},
|
||||
},
|
||||
errors: ['ALREADY_FOLLOWING', 'BLOCKING', 'BLOCKED', 'FOLLOWEE_IS_YOURSELF', 'NO_SUCH_USER'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -70,13 +40,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const follower = user;
|
||||
|
||||
// 自分自身
|
||||
if (user.id === ps.userId) {
|
||||
throw new ApiError(meta.errors.followeeIsYourself);
|
||||
}
|
||||
if (user.id === ps.userId) throw new ApiError('FOLLOWEE_IS_YOURSELF');
|
||||
|
||||
// Get followee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -86,16 +54,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
followeeId: followee.id,
|
||||
});
|
||||
|
||||
if (exist != null) {
|
||||
throw new ApiError(meta.errors.alreadyFollowing);
|
||||
}
|
||||
if (exist != null) throw new ApiError('ALREADY_FOLLOWING');
|
||||
|
||||
try {
|
||||
await create(follower, followee);
|
||||
} catch (e) {
|
||||
if (e instanceof IdentifiableError) {
|
||||
if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking);
|
||||
if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked);
|
||||
if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError('BLOCKING');
|
||||
if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError('BLOCKED');
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:following',
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8',
|
||||
},
|
||||
|
||||
followeeIsYourself: {
|
||||
message: 'Followee is yourself.',
|
||||
code: 'FOLLOWEE_IS_YOURSELF',
|
||||
id: 'd9e400b9-36b0-4808-b1d8-79e707f1296c',
|
||||
},
|
||||
|
||||
notFollowing: {
|
||||
message: 'You are not following that user.',
|
||||
code: 'NOT_FOLLOWING',
|
||||
id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09',
|
||||
},
|
||||
},
|
||||
errors: ['FOLLOWEE_IS_YOURSELF', 'NO_SUCH_USER', 'NOT_FOLLOWING'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const follower = user;
|
||||
|
||||
// Check if the followee is yourself
|
||||
if (user.id === ps.userId) {
|
||||
throw new ApiError(meta.errors.followeeIsYourself);
|
||||
}
|
||||
if (user.id === ps.userId) throw new ApiError('FOLLOWEE_IS_YOURSELF');
|
||||
|
||||
// Get followee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
followeeId: followee.id,
|
||||
});
|
||||
|
||||
if (exist == null) {
|
||||
throw new ApiError(meta.errors.notFollowing);
|
||||
}
|
||||
if (exist == null) throw new ApiError('NOT_FOLLOWING');
|
||||
|
||||
await deleteFollowing(follower, followee);
|
||||
|
||||
|
|
|
@ -17,25 +17,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:following',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['FOLLOWER_IS_YOURSELF', 'NO_SUCH_USER', 'NOT_FOLLOWING'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const followee = user;
|
||||
|
||||
// Check if the follower is yourself
|
||||
if (user.id === ps.userId) {
|
||||
throw new ApiError(meta.errors.followerIsYourself);
|
||||
}
|
||||
if (user.id === ps.userId) throw new ApiError('FOLLOWER_IS_YOURSELF');
|
||||
|
||||
// Get follower
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
followeeId: followee.id,
|
||||
});
|
||||
|
||||
if (exist == null) {
|
||||
throw new ApiError(meta.errors.notFollowing);
|
||||
}
|
||||
if (exist == null) throw new ApiError('NOT_FOLLOWING');
|
||||
|
||||
await deleteFollowing(follower, followee);
|
||||
|
||||
|
|
|
@ -10,18 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:following',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER', 'NO_SUCH_FOLLOW_REQUEST'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -36,12 +25,12 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
// Fetch follower
|
||||
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;
|
||||
});
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -12,19 +12,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:following',
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: '4e68c551-fc4c-4e46-bb41-7d4a37bf9dab',
|
||||
},
|
||||
|
||||
followRequestNotFound: {
|
||||
message: 'Follow request not found.',
|
||||
code: 'FOLLOW_REQUEST_NOT_FOUND',
|
||||
id: '089b125b-d338-482a-9a09-e2622ac9f8d4',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER', 'NO_SUCH_FOLLOW_REQUEST'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -45,7 +33,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
// Fetch followee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -53,7 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
await cancelFollowRequest(followee, user);
|
||||
} catch (e) {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:following',
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: 'No such user.',
|
||||
code: 'NO_SUCH_USER',
|
||||
id: 'abc2ffa6-25b2-4380-ba99-321ff3a94555',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -31,7 +25,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
// Fetch follower
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -22,10 +22,6 @@ export const meta = {
|
|||
optional: false, nullable: false,
|
||||
ref: 'GalleryPost',
|
||||
},
|
||||
|
||||
errors: {
|
||||
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:gallery',
|
||||
|
||||
errors: {
|
||||
noSuchPost: {
|
||||
message: 'No such post.',
|
||||
code: 'NO_SUCH_POST',
|
||||
id: 'ae52f367-4bd7-4ecd-afc6-5672fff427f5',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_POST'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (post == null) {
|
||||
throw new ApiError(meta.errors.noSuchPost);
|
||||
}
|
||||
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||
|
||||
await GalleryPosts.delete(post.id);
|
||||
});
|
||||
|
|
|
@ -10,19 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:gallery-likes',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_POST', 'ALREADY_LIKED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -36,9 +24,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const post = await GalleryPosts.findOneBy({ id: ps.postId });
|
||||
if (post == null) {
|
||||
throw new ApiError(meta.errors.noSuchPost);
|
||||
}
|
||||
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||
|
||||
// if already liked
|
||||
const exist = await GalleryLikes.findOneBy({
|
||||
|
@ -46,9 +32,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (exist != null) {
|
||||
throw new ApiError(meta.errors.alreadyLiked);
|
||||
}
|
||||
if (exist != null) throw new ApiError('ALREADY_LIKED');
|
||||
|
||||
// Create like
|
||||
await GalleryLikes.insert({
|
||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
|||
|
||||
requireCredential: false,
|
||||
|
||||
errors: {
|
||||
noSuchPost: {
|
||||
message: 'No such post.',
|
||||
code: 'NO_SUCH_POST',
|
||||
id: '1137bf14-c5b0-4604-85bb-5b5371b1cd45',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_POST'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -36,9 +30,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
id: ps.postId,
|
||||
});
|
||||
|
||||
if (post == null) {
|
||||
throw new ApiError(meta.errors.noSuchPost);
|
||||
}
|
||||
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||
|
||||
return await GalleryPosts.pack(post, me);
|
||||
});
|
||||
|
|
|
@ -9,19 +9,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:gallery-likes',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_POST', 'NOT_LIKED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -35,18 +23,14 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const post = await GalleryPosts.findOneBy({ id: ps.postId });
|
||||
if (post == null) {
|
||||
throw new ApiError(meta.errors.noSuchPost);
|
||||
}
|
||||
if (post == null) throw new ApiError('NO_SUCH_POST');
|
||||
|
||||
const exist = await GalleryLikes.findOneBy({
|
||||
postId: post.id,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (exist == null) {
|
||||
throw new ApiError(meta.errors.notLiked);
|
||||
}
|
||||
if (exist == null) throw new ApiError('NOT_LIKED');
|
||||
|
||||
// Delete like
|
||||
await GalleryLikes.delete(exist.id);
|
||||
|
|
|
@ -20,10 +20,6 @@ export const meta = {
|
|||
optional: false, nullable: false,
|
||||
ref: 'GalleryPost',
|
||||
},
|
||||
|
||||
errors: {
|
||||
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
|
@ -14,13 +14,7 @@ export const meta = {
|
|||
ref: 'Hashtag',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchHashtag: {
|
||||
message: 'No such hashtag.',
|
||||
code: 'NO_SUCH_HASHTAG',
|
||||
id: '110ee688-193e-4a3a-9ecf-c167b2e6981e',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_HASHTAG'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -34,9 +28,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const hashtag = await Hashtags.findOneBy({ name: normalizeForSearch(ps.tag) });
|
||||
if (hashtag == null) {
|
||||
throw new ApiError(meta.errors.noSuchHashtag);
|
||||
}
|
||||
if (hashtag == null) throw new ApiError('NO_SUCH_HASHTAG');
|
||||
|
||||
return await Hashtags.pack(hashtag);
|
||||
});
|
||||
|
|
|
@ -13,31 +13,7 @@ export const meta = {
|
|||
max: 1,
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -52,10 +28,9 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||
|
||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
||||
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
|
||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
||||
if (file == null) throw new ApiError('EMPTY_FILE');
|
||||
if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
|
||||
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||
|
||||
createImportBlockingJob(user, file.id);
|
||||
});
|
||||
|
|
|
@ -12,31 +12,7 @@ export const meta = {
|
|||
max: 1,
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -51,10 +27,9 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||
|
||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
||||
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
|
||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
||||
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||
if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
|
||||
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||
|
||||
createImportFollowingJob(user, file.id);
|
||||
});
|
||||
|
|
|
@ -13,31 +13,7 @@ export const meta = {
|
|||
max: 1,
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -52,10 +28,9 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||
|
||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
||||
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
|
||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
||||
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||
if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
|
||||
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||
|
||||
createImportMutingJob(user, file.id);
|
||||
});
|
||||
|
|
|
@ -12,31 +12,7 @@ export const meta = {
|
|||
max: 1,
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -51,10 +27,9 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||
|
||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
||||
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
|
||||
if (file.size > 30000) throw new ApiError(meta.errors.tooBigFile);
|
||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
||||
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||
if (file.size > 30000) throw new ApiError('FILE_TOO_BIG');
|
||||
if (file.size === 0) throw new ApiError('EMPTY_FILE');
|
||||
|
||||
createImportUserListsJob(user, file.id);
|
||||
});
|
||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['ALREADY_PINNED', 'NO_SUCH_NOTE', 'PIN_LIMIT_EXCEEDED'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -48,9 +30,9 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
await addPinned(user, ps.noteId).catch(e => {
|
||||
if (e.id === '70c4e51f-5bea-449c-a030-53bee3cce202') throw new ApiError(meta.errors.noSuchNote);
|
||||
if (e.id === '15a018eb-58e5-4da1-93be-330fcc5e4e1a') throw new ApiError(meta.errors.pinLimitExceeded);
|
||||
if (e.id === '23f0cf4e-59a3-4276-a91d-61a5891c1514') throw new ApiError(meta.errors.alreadyPinned);
|
||||
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('PIN_LIMIT_EXCEEDED');
|
||||
if (e.id === '23f0cf4e-59a3-4276-a91d-61a5891c1514') throw new ApiError('ALREADY_PINNED');
|
||||
throw e;
|
||||
});
|
||||
|
||||
|
|
|
@ -11,13 +11,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchAnnouncement: {
|
||||
message: 'No such announcement.',
|
||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
||||
id: '184663db-df88-4bc2-8b52-fb85f0681939',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_ANNOUNCEMENT'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
// Check if announcement exists
|
||||
const announcement = await Announcements.findOneBy({ id: ps.announcementId });
|
||||
|
||||
if (announcement == null) {
|
||||
throw new ApiError(meta.errors.noSuchAnnouncement);
|
||||
}
|
||||
if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');
|
||||
|
||||
// Check if already read
|
||||
const read = await AnnouncementReads.findOneBy({
|
||||
|
@ -43,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (read != null) {
|
||||
return;
|
||||
}
|
||||
if (read != null) return;
|
||||
|
||||
// Create read
|
||||
await AnnouncementReads.insert({
|
||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
|||
|
||||
secure: true,
|
||||
|
||||
errors: {
|
||||
noSuchKey: {
|
||||
message: 'No such key.',
|
||||
code: 'NO_SUCH_KEY',
|
||||
id: '97a1e8e7-c0f7-47d2-957a-92e61256e01a',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_KEY'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
const item = await query.getOne();
|
||||
|
||||
if (item == null) {
|
||||
throw new ApiError(meta.errors.noSuchKey);
|
||||
}
|
||||
if (item == null) throw new ApiError('NO_SUCH_KEY');
|
||||
|
||||
return {
|
||||
updatedAt: item.updatedAt,
|
||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
|||
|
||||
secure: true,
|
||||
|
||||
errors: {
|
||||
noSuchKey: {
|
||||
message: 'No such key.',
|
||||
code: 'NO_SUCH_KEY',
|
||||
id: 'ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_KEY'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
const item = await query.getOne();
|
||||
|
||||
if (item == null) {
|
||||
throw new ApiError(meta.errors.noSuchKey);
|
||||
}
|
||||
if (item == null) throw new ApiError('NO_SUCH_KEY');
|
||||
|
||||
return item.value;
|
||||
});
|
||||
|
|
|
@ -7,13 +7,7 @@ export const meta = {
|
|||
|
||||
secure: true,
|
||||
|
||||
errors: {
|
||||
noSuchKey: {
|
||||
message: 'No such key.',
|
||||
code: 'NO_SUCH_KEY',
|
||||
id: '1fac4e8a-a6cd-4e39-a4a5-3a7e11f1b019',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_KEY'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
const item = await query.getOne();
|
||||
|
||||
if (item == null) {
|
||||
throw new ApiError(meta.errors.noSuchKey);
|
||||
}
|
||||
if (item == null) throw new ApiError('NO_SUCH_KEY');
|
||||
|
||||
await RegistryItems.remove(item);
|
||||
});
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: '454170ce-9d63-4a43-9da1-ea10afe81e21',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -36,7 +30,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -19,19 +19,9 @@ export const meta = {
|
|||
max: 3,
|
||||
},
|
||||
|
||||
errors: {
|
||||
incorrectPassword: {
|
||||
message: 'Incorrect password.',
|
||||
code: 'INCORRECT_PASSWORD',
|
||||
id: 'e54c1d7e-e7d6-4103-86b6-0a95069b4ad3',
|
||||
},
|
||||
|
||||
unavailable: {
|
||||
message: 'Unavailable email address.',
|
||||
code: 'UNAVAILABLE',
|
||||
id: 'a2defefb-f220-8849-0af6-17f816099323',
|
||||
},
|
||||
},
|
||||
// FIXME: refactor to remove both of these errors?
|
||||
// the password should not be passed as it is not compatible with using OAuth
|
||||
errors: ['ACCESS_DENIED', 'INTERNAL_ERROR'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -50,15 +40,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
// Compare password
|
||||
const same = await bcrypt.compare(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new ApiError(meta.errors.incorrectPassword);
|
||||
}
|
||||
if (!same) throw new ApiError('ACCESS_DENIED');
|
||||
|
||||
if (ps.email != null) {
|
||||
const available = await validateEmailForAccount(ps.email);
|
||||
if (!available) {
|
||||
throw new ApiError(meta.errors.unavailable);
|
||||
}
|
||||
if (!available) throw new ApiError('INTERNAL_ERROR');
|
||||
}
|
||||
|
||||
await UserProfiles.update(user.id, {
|
||||
|
|
|
@ -22,43 +22,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['INVALID_REGEXP', 'NO_SUCH_FILE', 'NO_SUCH_PAGE', 'NOT_AN_IMAGE'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@ -142,12 +106,12 @@ export default define(meta, paramDef, async (ps, _user, token) => {
|
|||
// validate regular expression syntax
|
||||
ps.mutedWords.filter(x => !Array.isArray(x)).forEach(x => {
|
||||
const regexp = x.match(/^\/(.+)\/(.*)$/);
|
||||
if (!regexp) throw new ApiError(meta.errors.invalidRegexp);
|
||||
if (!regexp) throw new ApiError('INVALID_REGEXP');
|
||||
|
||||
try {
|
||||
new RE2(regexp[1], regexp[2]);
|
||||
} 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) {
|
||||
const avatar = await DriveFiles.findOneBy({ id: ps.avatarId });
|
||||
|
||||
if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar);
|
||||
if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage);
|
||||
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('NOT_AN_IMAGE', 'Avatar file is not an image.');
|
||||
}
|
||||
|
||||
if (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.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage);
|
||||
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('BANNER_NOT_AN_IMAGE', 'Banner file is not an image.');
|
||||
}
|
||||
|
||||
if (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;
|
||||
} else if (ps.pinnedPageId === null) {
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchWebhook: {
|
||||
message: 'No such webhook.',
|
||||
code: 'NO_SUCH_WEBHOOK',
|
||||
id: 'bae73e5a-5522-4965-ae19-3a8688e71d82',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_WEBHOOK'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (webhook == null) {
|
||||
throw new ApiError(meta.errors.noSuchWebhook);
|
||||
}
|
||||
if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
|
||||
|
||||
await Webhooks.delete(webhook.id);
|
||||
|
||||
|
|
|
@ -9,13 +9,7 @@ export const meta = {
|
|||
|
||||
kind: 'read:account',
|
||||
|
||||
errors: {
|
||||
noSuchWebhook: {
|
||||
message: 'No such webhook.',
|
||||
code: 'NO_SUCH_WEBHOOK',
|
||||
id: '50f614d9-3047-4f7e-90d8-ad6b2d5fb098',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_WEBHOOK'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (webhook == null) {
|
||||
throw new ApiError(meta.errors.noSuchWebhook);
|
||||
}
|
||||
if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
|
||||
|
||||
return webhook;
|
||||
});
|
||||
|
|
|
@ -11,14 +11,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchWebhook: {
|
||||
message: 'No such webhook.',
|
||||
code: 'NO_SUCH_WEBHOOK',
|
||||
id: 'fb0fea69-da18-45b1-828d-bd4fd1612518',
|
||||
},
|
||||
},
|
||||
|
||||
errors: ['NO_SUCH_WEBHOOK'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -43,9 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (webhook == null) {
|
||||
throw new ApiError(meta.errors.noSuchWebhook);
|
||||
}
|
||||
if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
|
||||
|
||||
await Webhooks.update(webhook.id, {
|
||||
name: ps.name,
|
||||
|
|
|
@ -23,25 +23,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['ACCESS_DENIED', 'NO_SUCH_USER', 'NO_SUCH_GROUP'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -73,7 +55,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
if (ps.userId != null) {
|
||||
// Fetch recipient (user)
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -110,9 +92,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
// Fetch recipient (group)
|
||||
const recipientGroup = await UserGroups.findOneBy({ id: ps.groupId });
|
||||
|
||||
if (recipientGroup == null) {
|
||||
throw new ApiError(meta.errors.noSuchGroup);
|
||||
}
|
||||
if (recipientGroup == null) throw new ApiError('NO_SUCH_GROUP');
|
||||
|
||||
// check joined
|
||||
const joining = await UserGroupJoinings.findOneBy({
|
||||
|
@ -120,9 +100,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userGroupId: recipientGroup.id,
|
||||
});
|
||||
|
||||
if (joining == null) {
|
||||
throw new ApiError(meta.errors.groupAccessDenied);
|
||||
}
|
||||
if (joining == null) throw new ApiError('ACCESS_DENIED', 'You have to join a group to read messages in it.');
|
||||
|
||||
const query = makePaginationQuery(MessagingMessages.createQueryBuilder('message'), ps.sinceId, ps.untilId)
|
||||
.andWhere('message.groupId = :groupId', { groupId: recipientGroup.id });
|
||||
|
|
|
@ -19,51 +19,11 @@ export const meta = {
|
|||
ref: 'MessagingMessage',
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['ACCESS_DENIED', 'BLOCKED', 'NO_SUCH_FILE', 'NO_SUCH_USER', 'NO_SUCH_GROUP', 'RECIPIENT_IS_YOURSELF'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
text: { type: 'string', nullable: true, maxLength: 3000 },
|
||||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
anyOf: [
|
||||
{
|
||||
properties: {
|
||||
|
@ -137,13 +97,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
if (ps.userId != null) {
|
||||
// Myself
|
||||
if (ps.userId === user.id) {
|
||||
throw new ApiError(meta.errors.recipientIsYourself);
|
||||
}
|
||||
if (ps.userId === user.id) throw new ApiError('RECIPIENT_IS_YOURSELF');
|
||||
|
||||
// Fetch recipient (user)
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -152,16 +110,12 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
blockerId: recipientUser.id,
|
||||
blockeeId: user.id,
|
||||
});
|
||||
if (block) {
|
||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
||||
}
|
||||
if (block) throw new ApiError('BLOCKED');
|
||||
} else if (ps.groupId != null) {
|
||||
// Fetch recipient (group)
|
||||
recipientGroup = await UserGroups.findOneBy({ id: ps.groupId! });
|
||||
|
||||
if (recipientGroup == null) {
|
||||
throw new ApiError(meta.errors.noSuchGroup);
|
||||
}
|
||||
if (recipientGroup == null) throw new ApiError('NO_SUCH_GROUP');
|
||||
|
||||
// check joined
|
||||
const joining = await UserGroupJoinings.findOneBy({
|
||||
|
@ -169,9 +123,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userGroupId: recipientGroup.id,
|
||||
});
|
||||
|
||||
if (joining == null) {
|
||||
throw new ApiError(meta.errors.groupAccessDenied);
|
||||
}
|
||||
if (joining == null) throw new ApiError('ACCESS_DENIED', 'You have to join a group to send a message in it.');
|
||||
}
|
||||
|
||||
let file = null;
|
||||
|
@ -181,9 +133,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (file == null) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
}
|
||||
if (file == null) throw new ApiError('NO_SUCH_FILE');
|
||||
}
|
||||
|
||||
return await createMessage(user, recipientUser, recipientGroup, ps.text, file);
|
||||
|
|
|
@ -17,13 +17,7 @@ export const meta = {
|
|||
minInterval: SECOND,
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchMessage: {
|
||||
message: 'No such message.',
|
||||
code: 'NO_SUCH_MESSAGE',
|
||||
id: '54b5b326-7925-42cf-8019-130fda8b56af',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_MESSAGE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -41,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (message == null) {
|
||||
throw new ApiError(meta.errors.noSuchMessage);
|
||||
}
|
||||
if (message == null) throw new ApiError('NO_SUCH_MESSAGE');
|
||||
|
||||
await deleteMessage(message);
|
||||
});
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:messaging',
|
||||
|
||||
errors: {
|
||||
noSuchMessage: {
|
||||
message: 'No such message.',
|
||||
code: 'NO_SUCH_MESSAGE',
|
||||
id: '86d56a2f-a9c3-4afb-b13c-3e9bfef9aa14',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_MESSAGE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -31,18 +25,16 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const message = await MessagingMessages.findOneBy({ id: ps.messageId });
|
||||
|
||||
if (message == null) {
|
||||
throw new ApiError(meta.errors.noSuchMessage);
|
||||
}
|
||||
if (message == null) throw new ApiError('NO_SUCH_MESSAGE');
|
||||
|
||||
if (message.recipientId) {
|
||||
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;
|
||||
});
|
||||
} else if (message.groupId) {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,25 +13,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:mutes',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER', 'MUTEE_IS_YOURSELF', 'ALREADY_MUTING'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -52,13 +34,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const muter = user;
|
||||
|
||||
// 自分自身
|
||||
if (user.id === ps.userId) {
|
||||
throw new ApiError(meta.errors.muteeIsYourself);
|
||||
}
|
||||
if (user.id === ps.userId) throw new ApiError('MUTEE_IS_YOURSELF');
|
||||
|
||||
// Get mutee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -68,9 +48,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
muteeId: mutee.id,
|
||||
});
|
||||
|
||||
if (exist != null) {
|
||||
throw new ApiError(meta.errors.alreadyMuting);
|
||||
}
|
||||
if (exist != null) throw new ApiError('ALREADY_MUTING');
|
||||
|
||||
if (ps.expiresAt && ps.expiresAt <= Date.now()) {
|
||||
return;
|
||||
|
|
|
@ -11,25 +11,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:mutes',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_USER', 'MUTEE_IS_YOURSELF', 'NOT_MUTING'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -45,13 +27,11 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const muter = user;
|
||||
|
||||
// Check if the mutee is yourself
|
||||
if (user.id === ps.userId) {
|
||||
throw new ApiError(meta.errors.muteeIsYourself);
|
||||
}
|
||||
if (user.id === ps.userId) throw new ApiError('MUTEE_IS_YOURSELF');
|
||||
|
||||
// Get mutee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -61,9 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
muteeId: mutee.id,
|
||||
});
|
||||
|
||||
if (exist == null) {
|
||||
throw new ApiError(meta.errors.notMuting);
|
||||
}
|
||||
if (exist == null) throw new ApiError('NOT_MUTING');
|
||||
|
||||
// Delete mute
|
||||
await Mutings.delete({
|
||||
|
|
|
@ -19,13 +19,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: '47db1a1c-b0af-458d-8fb4-986e4efafe1e',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -39,7 +33,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, me) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -19,13 +19,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: 'e1035875-9551-45ec-afa8-1ded1fcb53c8',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -41,7 +35,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -37,55 +37,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE', 'PURE_RENOTE', 'EXPIRED_POLL', 'NO_SUCH_CHANNEL', 'BLOCKED', 'LESS_RESTRICTIVE_VISIBILITY'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -199,17 +151,15 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
if (ps.renoteId != null) {
|
||||
// Fetch renote to note
|
||||
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;
|
||||
});
|
||||
|
||||
if (isPureRenote(renote)) {
|
||||
throw new ApiError(meta.errors.cannotReRenote);
|
||||
}
|
||||
if (isPureRenote(renote)) throw new ApiError('PURE_RENOTE', 'Cannot renote a pure renote.');
|
||||
|
||||
// check that the visibility is not less restrictive
|
||||
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
|
||||
|
@ -218,9 +168,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
blockerId: renote.userId,
|
||||
blockeeId: user.id,
|
||||
});
|
||||
if (block) {
|
||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
||||
}
|
||||
if (block) throw new ApiError('BLOCKED', 'Blocked by author of note to be renoted.');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,17 +176,15 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
if (ps.replyId != null) {
|
||||
// Fetch reply
|
||||
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;
|
||||
});
|
||||
|
||||
if (isPureRenote(reply)) {
|
||||
throw new ApiError(meta.errors.cannotReplyToPureRenote);
|
||||
}
|
||||
if (isPureRenote(reply)) throw new ApiError('PURE_RENOTE', 'Cannot reply to a pure renote.');
|
||||
|
||||
// check that the visibility is not less restrictive
|
||||
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
|
||||
|
@ -247,16 +193,14 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
blockerId: reply.userId,
|
||||
blockeeId: user.id,
|
||||
});
|
||||
if (block) {
|
||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
||||
}
|
||||
if (block) throw new ApiError('BLOCKED', 'Blocked by author of replied to note.');
|
||||
}
|
||||
}
|
||||
|
||||
if (ps.poll) {
|
||||
if (typeof ps.poll.expiresAt === 'number') {
|
||||
if (ps.poll.expiresAt < Date.now()) {
|
||||
throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll);
|
||||
throw new ApiError('EXPIRED_POLL');
|
||||
}
|
||||
} else if (typeof ps.poll.expiredAfter === 'number') {
|
||||
ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
|
||||
|
@ -267,9 +211,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
if (ps.channelId != null) {
|
||||
channel = await Channels.findOneBy({ id: ps.channelId });
|
||||
|
||||
if (channel == null) {
|
||||
throw new ApiError(meta.errors.noSuchChannel);
|
||||
}
|
||||
if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
|
||||
}
|
||||
|
||||
// 投稿を作成
|
||||
|
|
|
@ -18,19 +18,7 @@ export const meta = {
|
|||
minInterval: SECOND,
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['ACCESS_DENIED', 'NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -44,12 +32,12 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
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',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE', 'ALREADY_FAVORITED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -38,7 +26,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
// Get favoritee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -48,9 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (exist != null) {
|
||||
throw new ApiError(meta.errors.alreadyFavorited);
|
||||
}
|
||||
if (exist != null) throw new ApiError('ALREADY_FAVORITED');
|
||||
|
||||
// Create favorite
|
||||
await NoteFavorites.insert({
|
||||
|
|
|
@ -10,19 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:favorites',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE', 'NOT_FAVORITED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -37,7 +25,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
// Get favoritee
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -47,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
userId: user.id,
|
||||
});
|
||||
|
||||
if (exist == null) {
|
||||
throw new ApiError(meta.errors.notFavorited);
|
||||
}
|
||||
if (exist == null) throw new ApiError('NOT_FAVORITED');
|
||||
|
||||
// Delete favorite
|
||||
await NoteFavorites.delete(exist.id);
|
||||
|
|
|
@ -23,13 +23,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
gtlDisabled: {
|
||||
message: 'Global timeline has been disabled.',
|
||||
code: 'GTL_DISABLED',
|
||||
id: '0332fc13-6ab2-4427-ae80-a9fadffd1a6b',
|
||||
},
|
||||
},
|
||||
errors: ['TIMELINE_DISABLED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -54,7 +48,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const m = await fetchMeta();
|
||||
if (m.disableGlobalTimeline) {
|
||||
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: {
|
||||
stlDisabled: {
|
||||
message: 'Hybrid timeline has been disabled.',
|
||||
code: 'STL_DISABLED',
|
||||
id: '620763f4-f621-4533-ab33-0577a1a3c342',
|
||||
},
|
||||
},
|
||||
errors: ['TIMELINE_DISABLED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -61,7 +55,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const m = await fetchMeta();
|
||||
if (m.disableLocalTimeline && (!user.isAdmin && !user.isModerator)) {
|
||||
throw new ApiError(meta.errors.stlDisabled);
|
||||
throw new ApiError('TIMELINE_DISABLED');
|
||||
}
|
||||
|
||||
//#region Construct query
|
||||
|
|
|
@ -26,13 +26,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
ltlDisabled: {
|
||||
message: 'Local timeline has been disabled.',
|
||||
code: 'LTL_DISABLED',
|
||||
id: '45a6eb02-7695-4393-b023-dd3be9aaaefd',
|
||||
},
|
||||
},
|
||||
errors: ['TIMELINE_DISABLED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -61,7 +55,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const m = await fetchMeta();
|
||||
if (m.disableLocalTimeline) {
|
||||
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',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE', 'INVALID_CHOICE', 'ALREADY_VOTED', 'EXPIRED_POLL', 'BLOCKED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
noteId: { type: 'string', format: 'misskey:id' },
|
||||
choice: { type: 'integer' },
|
||||
choice: { type: 'integer', minimum: 0 },
|
||||
},
|
||||
required: ['noteId', 'choice'],
|
||||
} as const;
|
||||
|
@ -73,12 +37,12 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
// Get votee
|
||||
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;
|
||||
});
|
||||
|
||||
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
|
||||
|
@ -87,19 +51,17 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
blockerId: note.userId,
|
||||
blockeeId: user.id,
|
||||
});
|
||||
if (block) {
|
||||
throw new ApiError(meta.errors.youHaveBeenBlocked);
|
||||
}
|
||||
if (block) throw new ApiError('BLOCKED');
|
||||
}
|
||||
|
||||
const poll = await Polls.findOneByOrFail({ noteId: note.id });
|
||||
|
||||
if (poll.expiresAt && poll.expiresAt < createdAt) {
|
||||
throw new ApiError(meta.errors.alreadyExpired);
|
||||
throw new ApiError('EXPIRED_POLL');
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -111,10 +73,10 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
if (exist.length) {
|
||||
if (poll.multiple) {
|
||||
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 {
|
||||
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: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: '263fff3d-d0e1-4af4-bea7-8408059b451a',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -53,7 +47,7 @@ export const paramDef = {
|
|||
export default define(meta, paramDef, async (ps, user) => {
|
||||
// check note visibility
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -10,25 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:reactions',
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE', 'ALREADY_REACTED', 'BLOCKED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -43,12 +25,12 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
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 === 'e70412a4-7197-4726-8e74-f3e0deb92aa7') throw new ApiError(meta.errors.youHaveBeenBlocked);
|
||||
if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') throw new ApiError('ALREADY_REACTED');
|
||||
if (e.id === 'e70412a4-7197-4726-8e74-f3e0deb92aa7') throw new ApiError('BLOCKED');
|
||||
throw e;
|
||||
});
|
||||
return;
|
||||
|
|
|
@ -17,19 +17,7 @@ export const meta = {
|
|||
minInterval: 3 * SECOND,
|
||||
},
|
||||
|
||||
errors: {
|
||||
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',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE', 'NOT_REACTED'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -43,11 +31,11 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
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;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,13 +22,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: '12908022-2e21-46cd-ba6a-3edaf6093f46',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -45,7 +39,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -22,9 +22,6 @@ export const meta = {
|
|||
ref: 'Note',
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
|
@ -14,13 +14,7 @@ export const meta = {
|
|||
ref: 'Note',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: '24fcbfc6-2e37-42b6-8388-c29b3861a08d',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -34,7 +28,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -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)
|
||||
detail: true,
|
||||
}).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;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,13 +13,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: '5ff67ada-ed3b-2e71-8e87-a1a421e177d2',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -41,7 +35,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -10,13 +10,7 @@ export const meta = {
|
|||
|
||||
kind: 'write:account',
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: 'bddd57ac-ceb3-b29d-4334-86ea5fae481a',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -30,7 +24,7 @@ export const paramDef = {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -55,13 +55,7 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: 'bea9b03f-36e0-49c5-a4db-627a029f8971',
|
||||
},
|
||||
},
|
||||
errors: ['NO_SUCH_NOTE'],
|
||||
} as const;
|
||||
|
||||
// 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
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue