1
0
forked from mirror/misskey
This commit is contained in:
syuilo 2018-11-02 12:49:08 +09:00
parent befc35a3ac
commit a7e6b766be
No known key found for this signature in database
GPG Key ID: BDC4C49D06AB9D69
26 changed files with 434 additions and 354 deletions

View File

@ -2,31 +2,35 @@ import rndstr from 'rndstr';
import $ from 'cafy'; import $ from 'cafy';
import App, { pack } from '../../../../models/app'; import App, { pack } from '../../../../models/app';
import { ILocalUser } from '../../../../models/user'; import { ILocalUser } from '../../../../models/user';
import getParams from '../../get-params';
export const meta = { 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) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'name' parameter const [ps, psErr] = getParams(meta, params);
const [name, nameErr] = $.str.get(params.name); if (psErr) return rej(psErr);
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');
// Generate secret // Generate secret
const secret = rndstr('a-zA-Z0-9', 32); 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(), createdAt: new Date(),
userId: user && user._id, userId: user && user._id,
name: name, name: name,
description: description, description: ps.description,
permission: permission, permission: ps.permission,
callbackUrl: callbackUrl, callbackUrl: ps.callbackUrl,
secret: secret secret: secret
}); });

View File

@ -5,23 +5,27 @@ import App from '../../../../models/app';
import AuthSess from '../../../../models/auth-session'; import AuthSess from '../../../../models/auth-session';
import AccessToken from '../../../../models/access-token'; import AccessToken from '../../../../models/access-token';
import { ILocalUser } from '../../../../models/user'; import { ILocalUser } from '../../../../models/user';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true
secure: true,
params: {
token: {
validator: $.str
}
}
}; };
/**
* Accept
*/
export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'token' parameter const [ps, psErr] = getParams(meta, params);
const [token, tokenErr] = $.str.get(params.token); if (psErr) return rej(psErr);
if (tokenErr) return rej('invalid token param');
// Fetch token // Fetch token
const session = await AuthSess const session = await AuthSess
.findOne({ token: token }); .findOne({ token: ps.token });
if (session === null) { if (session === null) {
return rej('session not found'); return rej('session not found');

View File

@ -1,26 +1,27 @@
/**
* Module dependencies
*/
import * as uuid from 'uuid'; import * as uuid from 'uuid';
import $ from 'cafy'; import $ from 'cafy';
import App from '../../../../../models/app'; import App from '../../../../../models/app';
import AuthSess from '../../../../../models/auth-session'; import AuthSess from '../../../../../models/auth-session';
import config from '../../../../../config'; 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<any>}
*/
export default (params: any) => new Promise(async (res, rej) => { export default (params: any) => new Promise(async (res, rej) => {
// Get 'appSecret' parameter const [ps, psErr] = getParams(meta, params);
const [appSecret, appSecretErr] = $.str.get(params.appSecret); if (psErr) return rej(psErr);
if (appSecretErr) return rej('invalid appSecret param');
// Lookup app // Lookup app
const app = await App.findOne({ const app = await App.findOne({
secret: appSecret secret: ps.appSecret
}); });
if (app == null) { if (app == null) {

View File

@ -1,18 +1,25 @@
import $ from 'cafy'; import $ from 'cafy';
import AuthSess, { pack } from '../../../../../models/auth-session'; import AuthSess, { pack } from '../../../../../models/auth-session';
import { ILocalUser } from '../../../../../models/user'; 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) => { export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'token' parameter const [ps, psErr] = getParams(meta, params);
const [token, tokenErr] = $.str.get(params.token); if (psErr) return rej(psErr);
if (tokenErr) return rej('invalid token param');
// Lookup session // Lookup session
const session = await AuthSess.findOne({ const session = await AuthSess.findOne({
token: token token: ps.token
}); });
if (session == null) { if (session == null) {

View File

@ -1,40 +1,41 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import $ from 'cafy';
import App from '../../../../../models/app'; import App from '../../../../../models/app';
import AuthSess from '../../../../../models/auth-session'; import AuthSess from '../../../../../models/auth-session';
import AccessToken from '../../../../../models/access-token'; import AccessToken from '../../../../../models/access-token';
import { pack } from '../../../../../models/user'; 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<any>}
*/
export default (params: any) => new Promise(async (res, rej) => { export default (params: any) => new Promise(async (res, rej) => {
// Get 'appSecret' parameter const [ps, psErr] = getParams(meta, params);
const [appSecret, appSecretErr] = $.str.get(params.appSecret); if (psErr) return rej(psErr);
if (appSecretErr) return rej('invalid appSecret param');
// Lookup app // Lookup app
const app = await App.findOne({ const app = await App.findOne({
secret: appSecret secret: ps.appSecret
}); });
if (app == null) { if (app == null) {
return rej('app not found'); return rej('app not found');
} }
// Get 'token' parameter
const [token, tokenErr] = $.str.get(params.token);
if (tokenErr) return rej('invalid token param');
// Fetch token // Fetch token
const session = await AuthSess const session = await AuthSess
.findOne({ .findOne({
token: token, token: ps.token,
appId: app._id appId: app._id
}); });

View File

@ -1,6 +1,7 @@
import $ from 'cafy'; import $ from 'cafy';
import DriveFile, { pack } from '../../../../../models/drive-file'; import DriveFile, { pack } from '../../../../../models/drive-file';
import { ILocalUser } from '../../../../../models/user'; import { ILocalUser } from '../../../../../models/user';
import getParams from '../../../get-params';
export const meta = { export const meta = {
desc: { desc: {
@ -23,11 +24,11 @@ export const meta = {
}; };
export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const [md5, md5Err] = $.str.get(params.md5); const [ps, psErr] = getParams(meta, params);
if (md5Err) return rej('invalid md5 param'); if (psErr) return rej(psErr);
const file = await DriveFile.findOne({ const file = await DriveFile.findOne({
md5: md5, md5: ps.md5,
'metadata.userId': user._id, 'metadata.userId': user._id,
'metadata.deletedAt': { $exists: false } 'metadata.deletedAt': { $exists: false }
}); });

View File

@ -1,18 +1,25 @@
import $ from 'cafy'; import $ from 'cafy';
import * as speakeasy from 'speakeasy'; import * as speakeasy from 'speakeasy';
import User, { ILocalUser } from '../../../../../models/user'; import User, { ILocalUser } from '../../../../../models/user';
import getParams from '../../../get-params';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true
secure: true,
params: {
token: {
validator: $.str
}
}
}; };
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'token' parameter const [ps, psErr] = getParams(meta, params);
const [token, tokenErr] = $.str.get(params.token); if (psErr) return rej(psErr);
if (tokenErr) return rej('invalid token param');
const _token = token.replace(/\s/g, ''); const _token = ps.token.replace(/\s/g, '');
if (user.twoFactorTempSecret == null) { if (user.twoFactorTempSecret == null) {
return rej('二段階認証の設定が開始されていません'); return rej('二段階認証の設定が開始されていません');

View File

@ -4,19 +4,26 @@ import * as speakeasy from 'speakeasy';
import * as QRCode from 'qrcode'; import * as QRCode from 'qrcode';
import User, { ILocalUser } from '../../../../../models/user'; import User, { ILocalUser } from '../../../../../models/user';
import config from '../../../../../config'; import config from '../../../../../config';
import getParams from '../../../get-params';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true
secure: true,
params: {
password: {
validator: $.str
}
}
}; };
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'password' parameter const [ps, psErr] = getParams(meta, params);
const [password, passwordErr] = $.str.get(params.password); if (psErr) return rej(psErr);
if (passwordErr) return rej('invalid password param');
// Compare password // Compare password
const same = await bcrypt.compare(password, user.password); const same = await bcrypt.compare(ps.password, user.password);
if (!same) { if (!same) {
return rej('incorrect password'); return rej('incorrect password');

View File

@ -1,19 +1,26 @@
import $ from 'cafy'; import $ from 'cafy';
import * as bcrypt from 'bcryptjs'; import * as bcrypt from 'bcryptjs';
import User, { ILocalUser } from '../../../../../models/user'; import User, { ILocalUser } from '../../../../../models/user';
import getParams from '../../../get-params';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true
secure: true,
params: {
password: {
validator: $.str
}
}
}; };
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'password' parameter const [ps, psErr] = getParams(meta, params);
const [password, passwordErr] = $.str.get(params.password); if (psErr) return rej(psErr);
if (passwordErr) return rej('invalid password param');
// Compare password // Compare password
const same = await bcrypt.compare(password, user.password); const same = await bcrypt.compare(ps.password, user.password);
if (!same) { if (!same) {
return rej('incorrect password'); return rej('incorrect password');

View File

@ -2,38 +2,47 @@ import $ from 'cafy';
import AccessToken from '../../../../models/access-token'; import AccessToken from '../../../../models/access-token';
import { pack } from '../../../../models/app'; import { pack } from '../../../../models/app';
import { ILocalUser } from '../../../../models/user'; import { ILocalUser } from '../../../../models/user';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, 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) => { export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter const [ps, psErr] = getParams(meta, params);
const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (psErr) return rej(psErr);
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');
// Get tokens // Get tokens
const tokens = await AccessToken const tokens = await AccessToken
.find({ .find({
userId: user._id userId: user._id
}, { }, {
limit: limit, limit: ps.limit,
skip: offset, skip: ps.offset,
sort: { sort: {
_id: sort == 'asc' ? 1 : -1 _id: ps.sort == 'asc' ? 1 : -1
} }
}); });
// Serialize
res(await Promise.all(tokens.map(token => pack(token.appId, user, { res(await Promise.all(tokens.map(token => pack(token.appId, user, {
detail: true detail: true
})))); }))));

View File

@ -1,23 +1,30 @@
import $ from 'cafy'; import $ from 'cafy';
import * as bcrypt from 'bcryptjs'; import * as bcrypt from 'bcryptjs';
import User, { ILocalUser } from '../../../../models/user'; import User, { ILocalUser } from '../../../../models/user';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, 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) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'currentPasword' parameter const [ps, psErr] = getParams(meta, params);
const [currentPassword, currentPasswordErr] = $.str.get(params.currentPasword); if (psErr) return rej(psErr);
if (currentPasswordErr) return rej('invalid currentPasword param');
// Get 'newPassword' parameter
const [newPassword, newPasswordErr] = $.str.get(params.newPassword);
if (newPasswordErr) return rej('invalid newPassword param');
// Compare password // Compare password
const same = await bcrypt.compare(currentPassword, user.password); const same = await bcrypt.compare(ps.currentPassword, user.password);
if (!same) { if (!same) {
return rej('incorrect password'); return rej('incorrect password');
@ -25,7 +32,7 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); 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, { await User.update(user._id, {
$set: { $set: {

View File

@ -3,19 +3,26 @@ import * as bcrypt from 'bcryptjs';
import User, { ILocalUser } from '../../../../models/user'; import User, { ILocalUser } from '../../../../models/user';
import { publishMainStream } from '../../../../stream'; import { publishMainStream } from '../../../../stream';
import generateUserToken from '../../common/generate-native-user-token'; import generateUserToken from '../../common/generate-native-user-token';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true
secure: true,
params: {
password: {
validator: $.str
}
}
}; };
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'password' parameter const [ps, psErr] = getParams(meta, params);
const [password, passwordErr] = $.str.get(params.password); if (psErr) return rej(psErr);
if (passwordErr) return rej('invalid password param');
// Compare password // Compare password
const same = await bcrypt.compare(password, user.password); const same = await bcrypt.compare(ps.password, user.password);
if (!same) { if (!same) {
return rej('incorrect password'); return rej('incorrect password');

View File

@ -1,23 +1,30 @@
import $ from 'cafy'; import $ from 'cafy';
import User, { ILocalUser } from '../../../../models/user'; import User, { ILocalUser } from '../../../../models/user';
import { publishMainStream } from '../../../../stream'; import { publishMainStream } from '../../../../stream';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, 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) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'name' parameter const [ps, psErr] = getParams(meta, params);
const [name, nameErr] = $.str.get(params.name); if (psErr) return rej(psErr);
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 x: any = {}; const x: any = {};
x[`clientSettings.${name}`] = value; x[`clientSettings.${name}`] = ps.value;
await User.update(user._id, { await User.update(user._id, {
$set: x $set: x
@ -28,6 +35,6 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
// Publish event // Publish event
publishMainStream(user._id, 'clientSettingUpdated', { publishMainStream(user._id, 'clientSettingUpdated', {
key: name, key: name,
value value: ps.value
}); });
}); });

View File

@ -1,29 +1,36 @@
import $ from 'cafy'; import $ from 'cafy';
import User, { ILocalUser } from '../../../../models/user'; import User, { ILocalUser } from '../../../../models/user';
import { publishMainStream } from '../../../../stream'; import { publishMainStream } from '../../../../stream';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true
};
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { secure: true,
// Get 'home' parameter
const [home, homeErr] = $.arr($.obj({ params: {
home: {
validator: $.arr($.obj({
name: $.str, name: $.str,
id: $.str, id: $.str,
place: $.str, place: $.str,
data: $.obj() data: $.obj()
}).strict()).get(params.home); }).strict())
if (homeErr) return rej('invalid home param'); }
}
};
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const [ps, psErr] = getParams(meta, params);
if (psErr) return rej(psErr);
await User.update(user._id, { await User.update(user._id, {
$set: { $set: {
'clientSettings.home': home 'clientSettings.home': ps.home
} }
}); });
res(); res();
publishMainStream(user._id, 'homeUpdated', home); publishMainStream(user._id, 'homeUpdated', ps.home);
}); });

View File

@ -1,28 +1,35 @@
import $ from 'cafy'; import $ from 'cafy';
import User, { ILocalUser } from '../../../../models/user'; import User, { ILocalUser } from '../../../../models/user';
import { publishMainStream } from '../../../../stream'; import { publishMainStream } from '../../../../stream';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true
};
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => { secure: true,
// Get 'home' parameter
const [home, homeErr] = $.arr($.obj({ params: {
home: {
validator: $.arr($.obj({
name: $.str, name: $.str,
id: $.str, id: $.str,
data: $.obj() data: $.obj()
}).strict()).get(params.home); }).strict())
if (homeErr) return rej('invalid home param'); }
}
};
export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const [ps, psErr] = getParams(meta, params);
if (psErr) return rej(psErr);
await User.update(user._id, { await User.update(user._id, {
$set: { $set: {
'clientSettings.mobileHome': home 'clientSettings.mobileHome': ps.home
} }
}); });
res(); res();
publishMainStream(user._id, 'mobileHomeUpdated', home); publishMainStream(user._id, 'mobileHomeUpdated', ps.home);
}); });

View File

@ -1,31 +1,38 @@
import $ from 'cafy'; import $ from 'cafy';
import User, { ILocalUser } from '../../../../models/user'; import User, { ILocalUser } from '../../../../models/user';
import { publishMainStream } from '../../../../stream'; import { publishMainStream } from '../../../../stream';
import getParams from '../../get-params';
export const meta = { export const meta = {
requireCredential: true, 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) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'id' parameter const [ps, psErr] = getParams(meta, params);
const [id, idErr] = $.str.get(params.id); if (psErr) return rej(psErr);
if (idErr) return rej('invalid id param');
// Get 'data' parameter if (ps.id == null && ps.data == null) return rej('you need to set id and data params if home param unset');
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');
let widget; let widget;
//#region Desktop home //#region Desktop home
if (widget == null && user.clientSettings.home) { if (widget == null && user.clientSettings.home) {
const desktopHome = 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) { if (widget) {
widget.data = data; widget.data = ps.data;
await User.update(user._id, { await User.update(user._id, {
$set: { $set: {
@ -39,9 +46,9 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
//#region Mobile home //#region Mobile home
if (widget == null && user.clientSettings.mobileHome) { if (widget == null && user.clientSettings.mobileHome) {
const mobileHome = 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) { if (widget) {
widget.data = data; widget.data = ps.data;
await User.update(user._id, { await User.update(user._id, {
$set: { $set: {
@ -57,11 +64,11 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
const deck = user.clientSettings.deck; const deck = user.clientSettings.deck;
deck.columns.filter((c: any) => c.type == 'widgets').forEach((c: any) => { deck.columns.filter((c: any) => c.type == 'widgets').forEach((c: any) => {
c.widgets.forEach((w: any) => { c.widgets.forEach((w: any) => {
if (w.id == id) widget = w; if (w.id == ps.id) widget = w;
}); });
}); });
if (widget) { if (widget) {
widget.data = data; widget.data = ps.data;
await User.update(user._id, { await User.update(user._id, {
$set: { $set: {
@ -74,7 +81,7 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
if (widget) { if (widget) {
publishMainStream(user._id, 'widgetUpdated', { publishMainStream(user._id, 'widgetUpdated', {
id, data id: ps.id, data: ps.data
}); });
res(); res();

View File

@ -3,6 +3,7 @@ import History from '../../../../models/messaging-history';
import Mute from '../../../../models/mute'; import Mute from '../../../../models/mute';
import { pack } from '../../../../models/messaging-message'; import { pack } from '../../../../models/messaging-message';
import { ILocalUser } from '../../../../models/user'; import { ILocalUser } from '../../../../models/user';
import getParams from '../../get-params';
export const meta = { export const meta = {
desc: { desc: {
@ -12,13 +13,19 @@ export const meta = {
requireCredential: true, 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) => { export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter const [ps, psErr] = getParams(meta, params);
const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (psErr) return rej(psErr);
if (limitErr) return rej('invalid limit param');
const mute = await Mute.find({ const mute = await Mute.find({
muterId: user._id, muterId: user._id,
@ -33,12 +40,11 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
$nin: mute.map(m => m.muteeId) $nin: mute.map(m => m.muteeId)
} }
}, { }, {
limit: limit, limit: ps.limit,
sort: { sort: {
updatedAt: -1 updatedAt: -1
} }
}); });
// Serialize
res(await Promise.all(history.map(h => pack(h.messageId, user)))); res(await Promise.all(history.map(h => pack(h.messageId, user))));
}); });

View File

@ -1,6 +1,7 @@
import $ from 'cafy'; import $ from 'cafy';
import App, { pack } from '../../../../models/app'; import App, { pack } from '../../../../models/app';
import { ILocalUser } from '../../../../models/user'; import { ILocalUser } from '../../../../models/user';
import getParams from '../../get-params';
export const meta = { export const meta = {
desc: { desc: {
@ -8,17 +9,24 @@ export const meta = {
'en-US': 'Get my apps' '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) => { export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter const [ps, psErr] = getParams(meta, params);
const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (psErr) return rej(psErr);
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 query = { const query = {
userId: user._id userId: user._id
@ -27,8 +35,8 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
// Execute query // Execute query
const apps = await App const apps = await App
.find(query, { .find(query, {
limit: limit, limit: ps.limit,
skip: offset, skip: ps.offset,
sort: { sort: {
_id: -1 _id: -1
} }

View File

@ -2,6 +2,7 @@ import $ from 'cafy';
import Vote from '../../../../../models/poll-vote'; import Vote from '../../../../../models/poll-vote';
import Note, { pack } from '../../../../../models/note'; import Note, { pack } from '../../../../../models/note';
import { ILocalUser } from '../../../../../models/user'; import { ILocalUser } from '../../../../../models/user';
import getParams from '../../../get-params';
export const meta = { export const meta = {
desc: { desc: {
@ -10,16 +11,23 @@ export const meta = {
}, },
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) => { export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter const [ps, psErr] = getParams(meta, params);
const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (psErr) return rej(psErr);
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 votes // Get votes
const votes = await Vote.find({ const votes = await Vote.find({
@ -46,14 +54,14 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
$ne: null $ne: null
} }
}, { }, {
limit: limit, limit: ps.limit,
skip: offset, skip: ps.offset,
sort: { sort: {
_id: -1 _id: -1
} }
}); });
// Serialize res(await Promise.all(notes.map(note => pack(note, user, {
res(await Promise.all(notes.map(async note => detail: true
await pack(note, user, { detail: true })))); }))));
}); });

View File

@ -4,19 +4,36 @@ import Note from '../../../../models/note';
import { ILocalUser } from '../../../../models/user'; import { ILocalUser } from '../../../../models/user';
import { packMany } from '../../../../models/note'; import { packMany } from '../../../../models/note';
import es from '../../../../db/elasticsearch'; 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) => { export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
// Get 'query' parameter const [ps, psErr] = getParams(meta, params);
const [query, queryError] = $.str.get(params.query); if (psErr) return rej(psErr);
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');
if (es == null) return rej('searching not available'); 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', index: 'misskey',
type: 'note', type: 'note',
body: { body: {
size: limit, size: ps.limit,
from: offset, from: ps.offset,
query: { query: {
simple_query_string: { simple_query_string: {
fields: ['text'], fields: ['text'],
query: query, query: ps.query,
default_operator: 'and' default_operator: 'and'
} }
}, },

View File

@ -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 }))));
});

View File

@ -2,33 +2,36 @@ import $ from 'cafy';
import Subscription from '../../../../models/sw-subscription'; import Subscription from '../../../../models/sw-subscription';
import { ILocalUser } from '../../../../models/user'; import { ILocalUser } from '../../../../models/user';
import config from '../../../../config'; import config from '../../../../config';
import getParams from '../../get-params';
export const meta = { 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) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'endpoint' parameter const [ps, psErr] = getParams(meta, params);
const [endpoint, endpointErr] = $.str.get(params.endpoint); if (psErr) return rej(psErr);
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');
// if already subscribed // if already subscribed
const exist = await Subscription.findOne({ const exist = await Subscription.findOne({
userId: user._id, userId: user._id,
endpoint: endpoint, endpoint: ps.endpoint,
auth: auth, auth: ps.auth,
publickey: publickey, publickey: ps.publickey,
deletedAt: { $exists: false } deletedAt: { $exists: false }
}); });
@ -41,9 +44,9 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
await Subscription.insert({ await Subscription.insert({
userId: user._id, userId: user._id,
endpoint: endpoint, endpoint: ps.endpoint,
auth: auth, auth: ps.auth,
publickey: publickey publickey: ps.publickey
}); });
res({ res({

View File

@ -1,20 +1,27 @@
import $ from 'cafy'; import $ from 'cafy';
import User from '../../../../models/user'; import User from '../../../../models/user';
import { validateUsername } 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) => { export default async (params: any) => new Promise(async (res, rej) => {
// Get 'username' parameter const [ps, psErr] = getParams(meta, params);
const [username, usernameError] = $.str.pipe(validateUsername).get(params.username); if (psErr) return rej(psErr);
if (usernameError) return rej('invalid username param');
// Get exist // Get exist
const exist = await User const exist = await User
.count({ .count({
host: null, host: null,
usernameLower: username.toLowerCase() usernameLower: ps.username.toLowerCase()
}, { }, {
limit: 1 limit: 1
}); });

View File

@ -1,30 +1,38 @@
import $ from 'cafy'; import $ from 'cafy';
import User, { pack, ILocalUser } from '../../../models/user'; 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) => { export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter const [ps, psErr] = getParams(meta, params);
const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (psErr) return rej(psErr);
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, sortError] = $.str.optional.or('+follower|-follower').get(params.sort);
if (sortError) return rej('invalid sort param');
// Construct query
let _sort; let _sort;
if (sort) { if (ps.sort) {
if (sort == '+follower') { if (ps.sort == '+follower') {
_sort = { _sort = {
followersCount: -1 followersCount: -1
}; };
} else if (sort == '-follower') { } else if (ps.sort == '-follower') {
_sort = { _sort = {
followersCount: 1 followersCount: 1
}; };
@ -35,17 +43,14 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
}; };
} }
// Issue query
const users = await User const users = await User
.find({ .find({
host: null host: null
}, { }, {
limit: limit, limit: ps.limit,
sort: _sort, sort: _sort,
skip: offset skip: ps.offset
}); });
// Serialize res(await Promise.all(users.map(user => pack(user, me))));
res(await Promise.all(users.map(async user =>
await pack(user, me))));
}); });

View File

@ -1,6 +1,7 @@
import $ from 'cafy'; import $ from 'cafy';
import UserList, { pack } from '../../../../../models/user-list'; import UserList, { pack } from '../../../../../models/user-list';
import { ILocalUser } from '../../../../../models/user'; import { ILocalUser } from '../../../../../models/user';
import getParams from '../../../get-params';
export const meta = { export const meta = {
desc: { desc: {
@ -10,19 +11,24 @@ export const meta = {
requireCredential: true, 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) => { export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'title' parameter const [ps, psErr] = getParams(meta, params);
const [title, titleErr] = $.str.range(1, 100).get(params.title); if (psErr) return rej(psErr);
if (titleErr) return rej('invalid title param');
// insert // insert
const userList = await UserList.insert({ const userList = await UserList.insert({
createdAt: new Date(), createdAt: new Date(),
userId: user._id, userId: user._id,
title: title, title: ps.title,
userIds: [] userIds: []
}); });

View File

@ -5,6 +5,7 @@ import { getFriendIds } from '../../common/get-friends';
import Mute from '../../../../models/mute'; import Mute from '../../../../models/mute';
import * as request from 'request'; import * as request from 'request';
import config from '../../../../config'; import config from '../../../../config';
import getParams from '../../get-params';
export const meta = { export const meta = {
desc: { desc: {
@ -13,10 +14,25 @@ export const meta = {
requireCredential: true, 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) => { 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) { if (config.user_recommendation && config.user_recommendation.external) {
const userName = me.username; const userName = me.username;
const hostName = config.hostname; const hostName = config.hostname;
@ -45,14 +61,6 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
} }
}); });
} else { } 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 // ID list of the user itself and other users who the user follows
const followingIds = await getFriendIds(me._id); const followingIds = await getFriendIds(me._id);
@ -72,15 +80,13 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
}, },
host: null host: null
}, { }, {
limit: limit, limit: ps.limit,
skip: offset, skip: ps.offset,
sort: { sort: {
followersCount: -1 followersCount: -1
} }
}); });
// Serialize res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
res(await Promise.all(users.map(async user =>
await pack(user, me, { detail: true }))));
} }
}); });