From a7e6b766be6b30b37839beb13f31d96b141cc25a Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 2 Nov 2018 12:49:08 +0900 Subject: [PATCH] Resolve #2623 --- src/server/api/endpoints/app/create.ts | 50 ++++++------ src/server/api/endpoints/auth/accept.ts | 20 +++-- .../api/endpoints/auth/session/generate.ts | 27 +++---- src/server/api/endpoints/auth/session/show.ts | 21 +++-- .../api/endpoints/auth/session/userkey.ts | 37 ++++----- .../endpoints/drive/files/check_existence.ts | 7 +- src/server/api/endpoints/i/2fa/done.ts | 17 +++-- src/server/api/endpoints/i/2fa/register.ts | 17 +++-- src/server/api/endpoints/i/2fa/unregister.ts | 17 +++-- src/server/api/endpoints/i/authorized_apps.ts | 41 ++++++---- src/server/api/endpoints/i/change_password.ts | 27 ++++--- .../api/endpoints/i/regenerate_token.ts | 17 +++-- .../api/endpoints/i/update_client_setting.ts | 27 ++++--- src/server/api/endpoints/i/update_home.ts | 29 ++++--- .../api/endpoints/i/update_mobile_home.ts | 27 ++++--- src/server/api/endpoints/i/update_widget.ts | 39 ++++++---- src/server/api/endpoints/messaging/history.ts | 18 +++-- src/server/api/endpoints/my/apps.ts | 28 ++++--- .../endpoints/notes/polls/recommendation.ts | 32 +++++--- src/server/api/endpoints/notes/search.ts | 45 +++++++---- src/server/api/endpoints/notes/trend.ts | 76 ------------------- src/server/api/endpoints/sw/register.ts | 45 ++++++----- .../api/endpoints/username/available.ts | 21 +++-- src/server/api/endpoints/users.ts | 53 +++++++------ .../api/endpoints/users/lists/create.ts | 16 ++-- .../api/endpoints/users/recommendation.ts | 34 +++++---- 26 files changed, 434 insertions(+), 354 deletions(-) delete mode 100644 src/server/api/endpoints/notes/trend.ts diff --git a/src/server/api/endpoints/app/create.ts b/src/server/api/endpoints/app/create.ts index 19795f1728..40da5144f6 100644 --- a/src/server/api/endpoints/app/create.ts +++ b/src/server/api/endpoints/app/create.ts @@ -2,31 +2,35 @@ import rndstr from 'rndstr'; import $ from 'cafy'; import App, { pack } from '../../../../models/app'; import { ILocalUser } from '../../../../models/user'; +import getParams from '../../get-params'; export const meta = { - requireCredential: false + requireCredential: false, + + params: { + name: { + validator: $.str + }, + + description: { + validator: $.str + }, + + permission: { + validator: $.arr($.str).unique() + }, + + // TODO: Check it is valid url + callbackUrl: { + validator: $.str.optional.nullable, + default: null as any + }, + } }; -/** - * Create an app - */ export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'name' parameter - const [name, nameErr] = $.str.get(params.name); - if (nameErr) return rej('invalid name param'); - - // Get 'description' parameter - const [description, descriptionErr] = $.str.get(params.description); - if (descriptionErr) return rej('invalid description param'); - - // Get 'permission' parameter - const [permission, permissionErr] = $.arr($.str).unique().get(params.permission); - if (permissionErr) return rej('invalid permission param'); - - // Get 'callbackUrl' parameter - // TODO: Check it is valid url - const [callbackUrl = null, callbackUrlErr] = $.str.optional.nullable.get(params.callbackUrl); - if (callbackUrlErr) return rej('invalid callbackUrl param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Generate secret const secret = rndstr('a-zA-Z0-9', 32); @@ -36,9 +40,9 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res, createdAt: new Date(), userId: user && user._id, name: name, - description: description, - permission: permission, - callbackUrl: callbackUrl, + description: ps.description, + permission: ps.permission, + callbackUrl: ps.callbackUrl, secret: secret }); diff --git a/src/server/api/endpoints/auth/accept.ts b/src/server/api/endpoints/auth/accept.ts index fee68a20a6..ed1c2fa390 100644 --- a/src/server/api/endpoints/auth/accept.ts +++ b/src/server/api/endpoints/auth/accept.ts @@ -5,23 +5,27 @@ import App from '../../../../models/app'; import AuthSess from '../../../../models/auth-session'; import AccessToken from '../../../../models/access-token'; import { ILocalUser } from '../../../../models/user'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + token: { + validator: $.str + } + } }; -/** - * Accept - */ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'token' parameter - const [token, tokenErr] = $.str.get(params.token); - if (tokenErr) return rej('invalid token param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Fetch token const session = await AuthSess - .findOne({ token: token }); + .findOne({ token: ps.token }); if (session === null) { return rej('session not found'); diff --git a/src/server/api/endpoints/auth/session/generate.ts b/src/server/api/endpoints/auth/session/generate.ts index bd1face9e3..79eb34d96a 100644 --- a/src/server/api/endpoints/auth/session/generate.ts +++ b/src/server/api/endpoints/auth/session/generate.ts @@ -1,26 +1,27 @@ -/** - * Module dependencies - */ import * as uuid from 'uuid'; import $ from 'cafy'; import App from '../../../../../models/app'; import AuthSess from '../../../../../models/auth-session'; import config from '../../../../../config'; +import getParams from '../../../get-params'; + +export const meta = { + requireCredential: false, + + params: { + appSecret: { + validator: $.str + } + } +}; -/** - * Generate a session - * - * @param {any} params - * @return {Promise} - */ export default (params: any) => new Promise(async (res, rej) => { - // Get 'appSecret' parameter - const [appSecret, appSecretErr] = $.str.get(params.appSecret); - if (appSecretErr) return rej('invalid appSecret param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Lookup app const app = await App.findOne({ - secret: appSecret + secret: ps.appSecret }); if (app == null) { diff --git a/src/server/api/endpoints/auth/session/show.ts b/src/server/api/endpoints/auth/session/show.ts index f2cbfe388e..9e7f4f52d4 100644 --- a/src/server/api/endpoints/auth/session/show.ts +++ b/src/server/api/endpoints/auth/session/show.ts @@ -1,18 +1,25 @@ import $ from 'cafy'; import AuthSess, { pack } from '../../../../../models/auth-session'; import { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; + +export const meta = { + requireCredential: false, + + params: { + token: { + validator: $.str + } + } +}; -/** - * Show a session - */ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'token' parameter - const [token, tokenErr] = $.str.get(params.token); - if (tokenErr) return rej('invalid token param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Lookup session const session = await AuthSess.findOne({ - token: token + token: ps.token }); if (session == null) { diff --git a/src/server/api/endpoints/auth/session/userkey.ts b/src/server/api/endpoints/auth/session/userkey.ts index 97f28464a5..50edf12abc 100644 --- a/src/server/api/endpoints/auth/session/userkey.ts +++ b/src/server/api/endpoints/auth/session/userkey.ts @@ -1,40 +1,41 @@ -/** - * Module dependencies - */ import $ from 'cafy'; import App from '../../../../../models/app'; import AuthSess from '../../../../../models/auth-session'; import AccessToken from '../../../../../models/access-token'; import { pack } from '../../../../../models/user'; +import getParams from '../../../get-params'; + +export const meta = { + requireCredential: false, + + params: { + appSecret: { + validator: $.str + }, + + token: { + validator: $.str + } + } +}; -/** - * Generate a session - * - * @param {any} params - * @return {Promise} - */ export default (params: any) => new Promise(async (res, rej) => { - // Get 'appSecret' parameter - const [appSecret, appSecretErr] = $.str.get(params.appSecret); - if (appSecretErr) return rej('invalid appSecret param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Lookup app const app = await App.findOne({ - secret: appSecret + secret: ps.appSecret }); if (app == null) { return rej('app not found'); } - // Get 'token' parameter - const [token, tokenErr] = $.str.get(params.token); - if (tokenErr) return rej('invalid token param'); - // Fetch token const session = await AuthSess .findOne({ - token: token, + token: ps.token, appId: app._id }); diff --git a/src/server/api/endpoints/drive/files/check_existence.ts b/src/server/api/endpoints/drive/files/check_existence.ts index 407c7d5530..a5bdad5fb9 100644 --- a/src/server/api/endpoints/drive/files/check_existence.ts +++ b/src/server/api/endpoints/drive/files/check_existence.ts @@ -1,6 +1,7 @@ import $ from 'cafy'; import DriveFile, { pack } from '../../../../../models/drive-file'; import { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; export const meta = { desc: { @@ -23,11 +24,11 @@ export const meta = { }; export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - const [md5, md5Err] = $.str.get(params.md5); - if (md5Err) return rej('invalid md5 param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); const file = await DriveFile.findOne({ - md5: md5, + md5: ps.md5, 'metadata.userId': user._id, 'metadata.deletedAt': { $exists: false } }); diff --git a/src/server/api/endpoints/i/2fa/done.ts b/src/server/api/endpoints/i/2fa/done.ts index 6d38ca1de1..40b45a3d0b 100644 --- a/src/server/api/endpoints/i/2fa/done.ts +++ b/src/server/api/endpoints/i/2fa/done.ts @@ -1,18 +1,25 @@ import $ from 'cafy'; import * as speakeasy from 'speakeasy'; import User, { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + token: { + validator: $.str + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'token' parameter - const [token, tokenErr] = $.str.get(params.token); - if (tokenErr) return rej('invalid token param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); - const _token = token.replace(/\s/g, ''); + const _token = ps.token.replace(/\s/g, ''); if (user.twoFactorTempSecret == null) { return rej('二段階認証の設定が開始されていません'); diff --git a/src/server/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts index 0466a4f366..4d6b05b787 100644 --- a/src/server/api/endpoints/i/2fa/register.ts +++ b/src/server/api/endpoints/i/2fa/register.ts @@ -4,19 +4,26 @@ import * as speakeasy from 'speakeasy'; import * as QRCode from 'qrcode'; import User, { ILocalUser } from '../../../../../models/user'; import config from '../../../../../config'; +import getParams from '../../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + password: { + validator: $.str + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'password' parameter - const [password, passwordErr] = $.str.get(params.password); - if (passwordErr) return rej('invalid password param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Compare password - const same = await bcrypt.compare(password, user.password); + const same = await bcrypt.compare(ps.password, user.password); if (!same) { return rej('incorrect password'); diff --git a/src/server/api/endpoints/i/2fa/unregister.ts b/src/server/api/endpoints/i/2fa/unregister.ts index accf3ea0f2..e3a1bd43de 100644 --- a/src/server/api/endpoints/i/2fa/unregister.ts +++ b/src/server/api/endpoints/i/2fa/unregister.ts @@ -1,19 +1,26 @@ import $ from 'cafy'; import * as bcrypt from 'bcryptjs'; import User, { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + password: { + validator: $.str + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'password' parameter - const [password, passwordErr] = $.str.get(params.password); - if (passwordErr) return rej('invalid password param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Compare password - const same = await bcrypt.compare(password, user.password); + const same = await bcrypt.compare(ps.password, user.password); if (!same) { return rej('incorrect password'); diff --git a/src/server/api/endpoints/i/authorized_apps.ts b/src/server/api/endpoints/i/authorized_apps.ts index 9c15670d17..09bcd2dcb6 100644 --- a/src/server/api/endpoints/i/authorized_apps.ts +++ b/src/server/api/endpoints/i/authorized_apps.ts @@ -2,38 +2,47 @@ import $ from 'cafy'; import AccessToken from '../../../../models/access-token'; import { pack } from '../../../../models/app'; import { ILocalUser } from '../../../../models/user'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + limit: { + validator: $.num.optional.range(1, 100), + default: 10, + }, + + offset: { + validator: $.num.optional.min(0), + default: 0, + }, + + sort: { + validator: $.str.optional.or('desc|asc'), + default: 'desc', + } + } }; export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); - if (offsetErr) return rej('invalid offset param'); - - // Get 'sort' parameter - const [sort = 'desc', sortError] = $.str.optional.or('desc asc').get(params.sort); - if (sortError) return rej('invalid sort param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Get tokens const tokens = await AccessToken .find({ userId: user._id }, { - limit: limit, - skip: offset, + limit: ps.limit, + skip: ps.offset, sort: { - _id: sort == 'asc' ? 1 : -1 + _id: ps.sort == 'asc' ? 1 : -1 } }); - // Serialize res(await Promise.all(tokens.map(token => pack(token.appId, user, { detail: true })))); diff --git a/src/server/api/endpoints/i/change_password.ts b/src/server/api/endpoints/i/change_password.ts index dc0f060c08..818637e224 100644 --- a/src/server/api/endpoints/i/change_password.ts +++ b/src/server/api/endpoints/i/change_password.ts @@ -1,23 +1,30 @@ import $ from 'cafy'; import * as bcrypt from 'bcryptjs'; import User, { ILocalUser } from '../../../../models/user'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + currentPassword: { + validator: $.str + }, + + newPassword: { + validator: $.str + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'currentPasword' parameter - const [currentPassword, currentPasswordErr] = $.str.get(params.currentPasword); - if (currentPasswordErr) return rej('invalid currentPasword param'); - - // Get 'newPassword' parameter - const [newPassword, newPasswordErr] = $.str.get(params.newPassword); - if (newPasswordErr) return rej('invalid newPassword param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Compare password - const same = await bcrypt.compare(currentPassword, user.password); + const same = await bcrypt.compare(ps.currentPassword, user.password); if (!same) { return rej('incorrect password'); @@ -25,7 +32,7 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res, // Generate hash of password const salt = await bcrypt.genSalt(8); - const hash = await bcrypt.hash(newPassword, salt); + const hash = await bcrypt.hash(ps.newPassword, salt); await User.update(user._id, { $set: { diff --git a/src/server/api/endpoints/i/regenerate_token.ts b/src/server/api/endpoints/i/regenerate_token.ts index 2d85f06cfa..81997362fc 100644 --- a/src/server/api/endpoints/i/regenerate_token.ts +++ b/src/server/api/endpoints/i/regenerate_token.ts @@ -3,19 +3,26 @@ import * as bcrypt from 'bcryptjs'; import User, { ILocalUser } from '../../../../models/user'; import { publishMainStream } from '../../../../stream'; import generateUserToken from '../../common/generate-native-user-token'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + password: { + validator: $.str + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'password' parameter - const [password, passwordErr] = $.str.get(params.password); - if (passwordErr) return rej('invalid password param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Compare password - const same = await bcrypt.compare(password, user.password); + const same = await bcrypt.compare(ps.password, user.password); if (!same) { return rej('incorrect password'); diff --git a/src/server/api/endpoints/i/update_client_setting.ts b/src/server/api/endpoints/i/update_client_setting.ts index 2c05299dff..a1631b1d95 100644 --- a/src/server/api/endpoints/i/update_client_setting.ts +++ b/src/server/api/endpoints/i/update_client_setting.ts @@ -1,23 +1,30 @@ import $ from 'cafy'; import User, { ILocalUser } from '../../../../models/user'; import { publishMainStream } from '../../../../stream'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + name: { + validator: $.str + }, + + value: { + validator: $.any.nullable + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'name' parameter - const [name, nameErr] = $.str.get(params.name); - if (nameErr) return rej('invalid name param'); - - // Get 'value' parameter - const [value, valueErr] = $.any.nullable.get(params.value); - if (valueErr) return rej('invalid value param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); const x: any = {}; - x[`clientSettings.${name}`] = value; + x[`clientSettings.${name}`] = ps.value; await User.update(user._id, { $set: x @@ -28,6 +35,6 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res, // Publish event publishMainStream(user._id, 'clientSettingUpdated', { key: name, - value + value: ps.value }); }); diff --git a/src/server/api/endpoints/i/update_home.ts b/src/server/api/endpoints/i/update_home.ts index 27afc9fe5a..eadd0290ab 100644 --- a/src/server/api/endpoints/i/update_home.ts +++ b/src/server/api/endpoints/i/update_home.ts @@ -1,29 +1,36 @@ import $ from 'cafy'; import User, { ILocalUser } from '../../../../models/user'; import { publishMainStream } from '../../../../stream'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + home: { + validator: $.arr($.obj({ + name: $.str, + id: $.str, + place: $.str, + data: $.obj() + }).strict()) + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'home' parameter - const [home, homeErr] = $.arr($.obj({ - name: $.str, - id: $.str, - place: $.str, - data: $.obj() - }).strict()).get(params.home); - if (homeErr) return rej('invalid home param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); await User.update(user._id, { $set: { - 'clientSettings.home': home + 'clientSettings.home': ps.home } }); res(); - publishMainStream(user._id, 'homeUpdated', home); + publishMainStream(user._id, 'homeUpdated', ps.home); }); diff --git a/src/server/api/endpoints/i/update_mobile_home.ts b/src/server/api/endpoints/i/update_mobile_home.ts index 1d4df389e4..c886574f23 100644 --- a/src/server/api/endpoints/i/update_mobile_home.ts +++ b/src/server/api/endpoints/i/update_mobile_home.ts @@ -1,28 +1,35 @@ import $ from 'cafy'; import User, { ILocalUser } from '../../../../models/user'; import { publishMainStream } from '../../../../stream'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + home: { + validator: $.arr($.obj({ + name: $.str, + id: $.str, + data: $.obj() + }).strict()) + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'home' parameter - const [home, homeErr] = $.arr($.obj({ - name: $.str, - id: $.str, - data: $.obj() - }).strict()).get(params.home); - if (homeErr) return rej('invalid home param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); await User.update(user._id, { $set: { - 'clientSettings.mobileHome': home + 'clientSettings.mobileHome': ps.home } }); res(); - publishMainStream(user._id, 'mobileHomeUpdated', home); + publishMainStream(user._id, 'mobileHomeUpdated', ps.home); }); diff --git a/src/server/api/endpoints/i/update_widget.ts b/src/server/api/endpoints/i/update_widget.ts index 92499493eb..947a29074c 100644 --- a/src/server/api/endpoints/i/update_widget.ts +++ b/src/server/api/endpoints/i/update_widget.ts @@ -1,31 +1,38 @@ import $ from 'cafy'; import User, { ILocalUser } from '../../../../models/user'; import { publishMainStream } from '../../../../stream'; +import getParams from '../../get-params'; export const meta = { requireCredential: true, - secure: true + + secure: true, + + params: { + id: { + validator: $.str + }, + + data: { + validator: $.obj() + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'id' parameter - const [id, idErr] = $.str.get(params.id); - if (idErr) return rej('invalid id param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); - // Get 'data' parameter - const [data, dataErr] = $.obj().get(params.data); - if (dataErr) return rej('invalid data param'); - - if (id == null && data == null) return rej('you need to set id and data params if home param unset'); + if (ps.id == null && ps.data == null) return rej('you need to set id and data params if home param unset'); let widget; //#region Desktop home if (widget == null && user.clientSettings.home) { const desktopHome = user.clientSettings.home; - widget = desktopHome.find((w: any) => w.id == id); + widget = desktopHome.find((w: any) => w.id == ps.id); if (widget) { - widget.data = data; + widget.data = ps.data; await User.update(user._id, { $set: { @@ -39,9 +46,9 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res, //#region Mobile home if (widget == null && user.clientSettings.mobileHome) { const mobileHome = user.clientSettings.mobileHome; - widget = mobileHome.find((w: any) => w.id == id); + widget = mobileHome.find((w: any) => w.id == ps.id); if (widget) { - widget.data = data; + widget.data = ps.data; await User.update(user._id, { $set: { @@ -57,11 +64,11 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res, const deck = user.clientSettings.deck; deck.columns.filter((c: any) => c.type == 'widgets').forEach((c: any) => { c.widgets.forEach((w: any) => { - if (w.id == id) widget = w; + if (w.id == ps.id) widget = w; }); }); if (widget) { - widget.data = data; + widget.data = ps.data; await User.update(user._id, { $set: { @@ -74,7 +81,7 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res, if (widget) { publishMainStream(user._id, 'widgetUpdated', { - id, data + id: ps.id, data: ps.data }); res(); diff --git a/src/server/api/endpoints/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts index 1dd08cd13c..078af21f27 100644 --- a/src/server/api/endpoints/messaging/history.ts +++ b/src/server/api/endpoints/messaging/history.ts @@ -3,6 +3,7 @@ import History from '../../../../models/messaging-history'; import Mute from '../../../../models/mute'; import { pack } from '../../../../models/messaging-message'; import { ILocalUser } from '../../../../models/user'; +import getParams from '../../get-params'; export const meta = { desc: { @@ -12,13 +13,19 @@ export const meta = { requireCredential: true, - kind: 'messaging-read' + kind: 'messaging-read', + + params: { + limit: { + validator: $.num.optional.range(1, 100), + default: 10 + } + } }; export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); - if (limitErr) return rej('invalid limit param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); const mute = await Mute.find({ muterId: user._id, @@ -33,12 +40,11 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) = $nin: mute.map(m => m.muteeId) } }, { - limit: limit, + limit: ps.limit, sort: { updatedAt: -1 } }); - // Serialize res(await Promise.all(history.map(h => pack(h.messageId, user)))); }); diff --git a/src/server/api/endpoints/my/apps.ts b/src/server/api/endpoints/my/apps.ts index 30c08aa09c..0b051f600c 100644 --- a/src/server/api/endpoints/my/apps.ts +++ b/src/server/api/endpoints/my/apps.ts @@ -1,6 +1,7 @@ import $ from 'cafy'; import App, { pack } from '../../../../models/app'; import { ILocalUser } from '../../../../models/user'; +import getParams from '../../get-params'; export const meta = { desc: { @@ -8,17 +9,24 @@ export const meta = { 'en-US': 'Get my apps' }, - requireCredential: true + requireCredential: true, + + params: { + limit: { + validator: $.num.optional.range(1, 100), + default: 10 + }, + + offset: { + validator: $.num.optional.min(0), + default: 0 + } + } }; export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); - if (offsetErr) return rej('invalid offset param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); const query = { userId: user._id @@ -27,8 +35,8 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) = // Execute query const apps = await App .find(query, { - limit: limit, - skip: offset, + limit: ps.limit, + skip: ps.offset, sort: { _id: -1 } diff --git a/src/server/api/endpoints/notes/polls/recommendation.ts b/src/server/api/endpoints/notes/polls/recommendation.ts index 9af223c010..34250a32f9 100644 --- a/src/server/api/endpoints/notes/polls/recommendation.ts +++ b/src/server/api/endpoints/notes/polls/recommendation.ts @@ -2,6 +2,7 @@ import $ from 'cafy'; import Vote from '../../../../../models/poll-vote'; import Note, { pack } from '../../../../../models/note'; import { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; export const meta = { desc: { @@ -10,16 +11,23 @@ export const meta = { }, requireCredential: true, + + params: { + limit: { + validator: $.num.optional.range(1, 100), + default: 10 + }, + + offset: { + validator: $.num.optional.min(0), + default: 0 + } + } }; export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); - if (offsetErr) return rej('invalid offset param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Get votes const votes = await Vote.find({ @@ -46,14 +54,14 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) = $ne: null } }, { - limit: limit, - skip: offset, + limit: ps.limit, + skip: ps.offset, sort: { _id: -1 } }); - // Serialize - res(await Promise.all(notes.map(async note => - await pack(note, user, { detail: true })))); + res(await Promise.all(notes.map(note => pack(note, user, { + detail: true + })))); }); diff --git a/src/server/api/endpoints/notes/search.ts b/src/server/api/endpoints/notes/search.ts index 2755a70483..63a87c0f56 100644 --- a/src/server/api/endpoints/notes/search.ts +++ b/src/server/api/endpoints/notes/search.ts @@ -4,19 +4,36 @@ import Note from '../../../../models/note'; import { ILocalUser } from '../../../../models/user'; import { packMany } from '../../../../models/note'; import es from '../../../../db/elasticsearch'; +import getParams from '../../get-params'; + +export const meta = { + desc: { + 'ja-JP': '投稿を検索します。', + 'en-US': 'Search notes.' + }, + + requireCredential: false, + + params: { + query: { + validator: $.str + }, + + limit: { + validator: $.num.optional.range(1, 100), + default: 10 + }, + + offset: { + validator: $.num.optional.min(0), + default: 0 + } + } +}; export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { - // Get 'query' parameter - const [query, queryError] = $.str.get(params.query); - if (queryError) return rej('invalid query param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); - if (offsetErr) return rej('invalid offset param'); - - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 30).get(params.limit); - if (limitErr) return rej('invalid limit param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); if (es == null) return rej('searching not available'); @@ -24,12 +41,12 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => index: 'misskey', type: 'note', body: { - size: limit, - from: offset, + size: ps.limit, + from: ps.offset, query: { simple_query_string: { fields: ['text'], - query: query, + query: ps.query, default_operator: 'and' } }, diff --git a/src/server/api/endpoints/notes/trend.ts b/src/server/api/endpoints/notes/trend.ts deleted file mode 100644 index 9f55ed3243..0000000000 --- a/src/server/api/endpoints/notes/trend.ts +++ /dev/null @@ -1,76 +0,0 @@ -const ms = require('ms'); -import $ from 'cafy'; -import Note, { pack } from '../../../../models/note'; -import { ILocalUser } from '../../../../models/user'; - -export const meta = { - desc: { - 'ja-JP': '人気の投稿の一覧を取得します。', - 'en-US': 'Get trend notes.' - }, - - requireCredential: true -}; - -export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); - if (offsetErr) return rej('invalid offset param'); - - // Get 'reply' parameter - const [reply, replyErr] = $.bool.optional.get(params.reply); - if (replyErr) return rej('invalid reply param'); - - // Get 'renote' parameter - const [renote, renoteErr] = $.bool.optional.get(params.renote); - if (renoteErr) return rej('invalid renote param'); - - // Get 'media' parameter - const [media, mediaErr] = $.bool.optional.get(params.media); - if (mediaErr) return rej('invalid media param'); - - // Get 'poll' parameter - const [poll, pollErr] = $.bool.optional.get(params.poll); - if (pollErr) return rej('invalid poll param'); - - const query = { - _id: { $gte: new Date(Date.now() - ms('1days')) }, - renoteCount: { $gt: 0 }, - '_user.host': null - } as any; - - if (reply != undefined) { - query.replyId = reply ? { $exists: true, $ne: null } : null; - } - - if (renote != undefined) { - query.renoteId = renote ? { $exists: true, $ne: null } : null; - } - - if (media != undefined) { - query.fileIds = media ? { $exists: true, $ne: null } : null; - } - - if (poll != undefined) { - query.poll = poll ? { $exists: true, $ne: null } : null; - } - - // Issue query - const notes = await Note - .find(query, { - limit: limit, - skip: offset, - sort: { - renoteCount: -1, - _id: -1 - } - }); - - // Serialize - res(await Promise.all(notes.map(async note => - await pack(note, user, { detail: true })))); -}); diff --git a/src/server/api/endpoints/sw/register.ts b/src/server/api/endpoints/sw/register.ts index 503fc94654..69337bd8c0 100644 --- a/src/server/api/endpoints/sw/register.ts +++ b/src/server/api/endpoints/sw/register.ts @@ -2,33 +2,36 @@ import $ from 'cafy'; import Subscription from '../../../../models/sw-subscription'; import { ILocalUser } from '../../../../models/user'; import config from '../../../../config'; +import getParams from '../../get-params'; export const meta = { - requireCredential: true + requireCredential: true, + + params: { + endpoint: { + validator: $.str + }, + + auth: { + validator: $.str + }, + + publickey: { + validator: $.str + } + } }; -/** - * subscribe service worker - */ export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'endpoint' parameter - const [endpoint, endpointErr] = $.str.get(params.endpoint); - if (endpointErr) return rej('invalid endpoint param'); - - // Get 'auth' parameter - const [auth, authErr] = $.str.get(params.auth); - if (authErr) return rej('invalid auth param'); - - // Get 'publickey' parameter - const [publickey, publickeyErr] = $.str.get(params.publickey); - if (publickeyErr) return rej('invalid publickey param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // if already subscribed const exist = await Subscription.findOne({ userId: user._id, - endpoint: endpoint, - auth: auth, - publickey: publickey, + endpoint: ps.endpoint, + auth: ps.auth, + publickey: ps.publickey, deletedAt: { $exists: false } }); @@ -41,9 +44,9 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res, await Subscription.insert({ userId: user._id, - endpoint: endpoint, - auth: auth, - publickey: publickey + endpoint: ps.endpoint, + auth: ps.auth, + publickey: ps.publickey }); res({ diff --git a/src/server/api/endpoints/username/available.ts b/src/server/api/endpoints/username/available.ts index ff12b797ed..b61be84c3b 100644 --- a/src/server/api/endpoints/username/available.ts +++ b/src/server/api/endpoints/username/available.ts @@ -1,20 +1,27 @@ import $ from 'cafy'; import User from '../../../../models/user'; import { validateUsername } from '../../../../models/user'; +import getParams from '../../get-params'; + +export const meta = { + requireCredential: false, + + params: { + username: { + validator: $.str.pipe(validateUsername) + } + } +}; -/** - * Check available username - */ export default async (params: any) => new Promise(async (res, rej) => { - // Get 'username' parameter - const [username, usernameError] = $.str.pipe(validateUsername).get(params.username); - if (usernameError) return rej('invalid username param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Get exist const exist = await User .count({ host: null, - usernameLower: username.toLowerCase() + usernameLower: ps.username.toLowerCase() }, { limit: 1 }); diff --git a/src/server/api/endpoints/users.ts b/src/server/api/endpoints/users.ts index d7e85d3cbe..81751504e7 100644 --- a/src/server/api/endpoints/users.ts +++ b/src/server/api/endpoints/users.ts @@ -1,30 +1,38 @@ import $ from 'cafy'; import User, { pack, ILocalUser } from '../../../models/user'; +import getParams from '../get-params'; + +export const meta = { + requireCredential: false, + + params: { + limit: { + validator: $.num.optional.range(1, 100), + default: 10 + }, + + offset: { + validator: $.num.optional.min(0), + default: 0 + }, + + sort: { + validator: $.str.optional.or('+follower|-follower'), + } + } +}; -/** - * Lists all users - */ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); - if (limitErr) return rej('invalid limit param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); - // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); - if (offsetErr) return rej('invalid offset param'); - - // Get 'sort' parameter - const [sort, sortError] = $.str.optional.or('+follower|-follower').get(params.sort); - if (sortError) return rej('invalid sort param'); - - // Construct query let _sort; - if (sort) { - if (sort == '+follower') { + if (ps.sort) { + if (ps.sort == '+follower') { _sort = { followersCount: -1 }; - } else if (sort == '-follower') { + } else if (ps.sort == '-follower') { _sort = { followersCount: 1 }; @@ -35,17 +43,14 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => }; } - // Issue query const users = await User .find({ host: null }, { - limit: limit, + limit: ps.limit, sort: _sort, - skip: offset + skip: ps.offset }); - // Serialize - res(await Promise.all(users.map(async user => - await pack(user, me)))); + res(await Promise.all(users.map(user => pack(user, me)))); }); diff --git a/src/server/api/endpoints/users/lists/create.ts b/src/server/api/endpoints/users/lists/create.ts index ac4f957a0d..c14bb64daa 100644 --- a/src/server/api/endpoints/users/lists/create.ts +++ b/src/server/api/endpoints/users/lists/create.ts @@ -1,6 +1,7 @@ import $ from 'cafy'; import UserList, { pack } from '../../../../../models/user-list'; import { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; export const meta = { desc: { @@ -10,19 +11,24 @@ export const meta = { requireCredential: true, - kind: 'account-write' + kind: 'account-write', + + params: { + title: { + validator: $.str.range(1, 100) + } + } }; export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'title' parameter - const [title, titleErr] = $.str.range(1, 100).get(params.title); - if (titleErr) return rej('invalid title param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // insert const userList = await UserList.insert({ createdAt: new Date(), userId: user._id, - title: title, + title: ps.title, userIds: [] }); diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts index df85343f0f..47c809ee4c 100644 --- a/src/server/api/endpoints/users/recommendation.ts +++ b/src/server/api/endpoints/users/recommendation.ts @@ -5,6 +5,7 @@ import { getFriendIds } from '../../common/get-friends'; import Mute from '../../../../models/mute'; import * as request from 'request'; import config from '../../../../config'; +import getParams from '../../get-params'; export const meta = { desc: { @@ -13,10 +14,25 @@ export const meta = { requireCredential: true, - kind: 'account-read' + kind: 'account-read', + + params: { + limit: { + validator: $.num.optional.range(1, 100), + default: 10 + }, + + offset: { + validator: $.num.optional.min(0), + default: 0 + } + } }; export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); + if (config.user_recommendation && config.user_recommendation.external) { const userName = me.username; const hostName = config.hostname; @@ -45,14 +61,6 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => } }); } else { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); - if (offsetErr) return rej('invalid offset param'); - // ID list of the user itself and other users who the user follows const followingIds = await getFriendIds(me._id); @@ -72,15 +80,13 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => }, host: null }, { - limit: limit, - skip: offset, + limit: ps.limit, + skip: ps.offset, sort: { followersCount: -1 } }); - // Serialize - res(await Promise.all(users.map(async user => - await pack(user, me, { detail: true })))); + res(await Promise.all(users.map(user => pack(user, me, { detail: true })))); } });