summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/users
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/api/endpoints/users')
-rw-r--r--src/server/api/endpoints/users/search.ts161
-rw-r--r--src/server/api/endpoints/users/search_by_username.ts70
2 files changed, 142 insertions, 89 deletions
diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts
index d443d35b47..eda3f95728 100644
--- a/src/server/api/endpoints/users/search.ts
+++ b/src/server/api/endpoints/users/search.ts
@@ -1,33 +1,156 @@
import $ from 'cafy';
-import User, { pack, ILocalUser } from '../../../../models/user';
const escapeRegexp = require('escape-regexp');
+import User, { pack, ILocalUser, validateUsername, IUser } from '../../../../models/user';
+import getParams from '../../get-params';
+
+export const meta = {
+ desc: {
+ ja: 'ユーザーを検索します。'
+ },
+
+ requireCredential: false,
+
+ params: {
+ query: $.str.note({
+ desc: {
+ ja: 'クエリ'
+ }
+ }),
+
+ offset: $.num.optional.min(0).note({
+ default: 0,
+ desc: {
+ ja: 'オフセット'
+ }
+ }),
+
+ limit: $.num.optional.range(1, 100).note({
+ default: 10,
+ desc: {
+ ja: '取得する数'
+ }
+ }),
+
+ localOnly: $.bool.optional.note({
+ default: false,
+ desc: {
+ ja: 'ローカルユーザーのみ検索対象にするか否か'
+ }
+ }),
+ },
+};
/**
* Search a user
*/
export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
- // Get 'query' parameter
- const [query, queryError] = $.str.pipe(x => x != '').get(params.query);
- if (queryError) return rej('invalid query param');
+ const [ps, psErr] = getParams(meta, params);
+ if (psErr) return rej(psErr);
+
+ const isUsername = validateUsername(ps.query.replace('@', ''));
+
+ let users: IUser[] = [];
+
+ if (isUsername) {
+ users = await User
+ .find({
+ host: null,
+ usernameLower: new RegExp('^' + escapeRegexp(ps.query.replace('@', '').toLowerCase()))
+ }, {
+ limit: ps.limit,
+ skip: ps.offset
+ });
+
+ if (users.length < ps.limit && !ps.localOnly) {
+ const otherUsers = await User
+ .find({
+ host: { $ne: null },
+ usernameLower: new RegExp('^' + escapeRegexp(ps.query.replace('@', '').toLowerCase()))
+ }, {
+ limit: ps.limit - users.length
+ });
+
+ users = users.concat(otherUsers);
+ }
- // Get 'max' parameter
- const [max = 10, maxErr] = $.num.optional.range(1, 30).get(params.max);
- if (maxErr) return rej('invalid max param');
+ if (users.length < ps.limit) {
+ const otherUsers = await User
+ .find({
+ _id: { $nin: users.map(u => u._id) },
+ host: null,
+ usernameLower: new RegExp(escapeRegexp(ps.query.replace('@', '').toLowerCase()))
+ }, {
+ limit: ps.limit - users.length
+ });
- const escapedQuery = escapeRegexp(query);
+ users = users.concat(otherUsers);
+ }
- // Search users
- const users = await User
- .find({
- host: null,
- $or: [{
- usernameLower: new RegExp(escapedQuery.replace('@', '').toLowerCase())
+ if (users.length < ps.limit && !ps.localOnly) {
+ const otherUsers = await User
+ .find({
+ _id: { $nin: users.map(u => u._id) },
+ host: { $ne: null },
+ usernameLower: new RegExp(escapeRegexp(ps.query.replace('@', '').toLowerCase()))
+ }, {
+ limit: ps.limit - users.length
+ });
+
+ users = users.concat(otherUsers);
+ }
+ }
+
+ if (users.length < ps.limit) {
+ const otherUsers = await User
+ .find({
+ _id: { $nin: users.map(u => u._id) },
+ host: null,
+ name: new RegExp('^' + escapeRegexp(ps.query.toLowerCase()))
+ }, {
+ limit: ps.limit - users.length
+ });
+
+ users = users.concat(otherUsers);
+ }
+
+ if (users.length < ps.limit && !ps.localOnly) {
+ const otherUsers = await User
+ .find({
+ _id: { $nin: users.map(u => u._id) },
+ host: { $ne: null },
+ name: new RegExp('^' + escapeRegexp(ps.query.toLowerCase()))
+ }, {
+ limit: ps.limit - users.length
+ });
+
+ users = users.concat(otherUsers);
+ }
+
+ if (users.length < ps.limit) {
+ const otherUsers = await User
+ .find({
+ _id: { $nin: users.map(u => u._id) },
+ host: null,
+ name: new RegExp(escapeRegexp(ps.query.toLowerCase()))
+ }, {
+ limit: ps.limit - users.length
+ });
+
+ users = users.concat(otherUsers);
+ }
+
+ if (users.length < ps.limit && !ps.localOnly) {
+ const otherUsers = await User
+ .find({
+ _id: { $nin: users.map(u => u._id) },
+ host: { $ne: null },
+ name: new RegExp(escapeRegexp(ps.query.toLowerCase()))
}, {
- name: new RegExp(escapedQuery)
- }]
- }, {
- limit: max
- });
+ limit: ps.limit - users.length
+ });
+
+ users = users.concat(otherUsers);
+ }
// Serialize
res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
diff --git a/src/server/api/endpoints/users/search_by_username.ts b/src/server/api/endpoints/users/search_by_username.ts
deleted file mode 100644
index bfab378389..0000000000
--- a/src/server/api/endpoints/users/search_by_username.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import $ from 'cafy';
-import User, { pack, ILocalUser } from '../../../../models/user';
-const escapeRegexp = require('escape-regexp');
-
-/**
- * Search a user by username
- */
-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, 100).get(params.limit);
- if (limitErr) return rej('invalid limit param');
-
- let users = await User
- .find({
- host: null,
- usernameLower: new RegExp('^' + escapeRegexp(query.toLowerCase()))
- }, {
- limit: limit,
- skip: offset
- });
-
- if (users.length < limit) {
- const otherUsers = await User
- .find({
- host: { $ne: null },
- usernameLower: new RegExp('^' + escapeRegexp(query.toLowerCase()))
- }, {
- limit: limit - users.length
- });
-
- users = users.concat(otherUsers);
- }
-
- if (users.length < limit) {
- const otherUsers = await User
- .find({
- _id: { $nin: users.map(u => u._id) },
- host: null,
- usernameLower: new RegExp(escapeRegexp(query.toLowerCase()))
- }, {
- limit: limit - users.length
- });
-
- users = users.concat(otherUsers);
- }
-
- if (users.length < limit) {
- const otherUsers = await User
- .find({
- _id: { $nin: users.map(u => u._id) },
- host: { $ne: null },
- usernameLower: new RegExp(escapeRegexp(query.toLowerCase()))
- }, {
- limit: limit - users.length
- });
-
- users = users.concat(otherUsers);
- }
-
- // Serialize
- res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
-});