forked from FoundKeyGang/FoundKey
良い感じに
This commit is contained in:
parent
1e4a86da8e
commit
1744316656
8 changed files with 76 additions and 50 deletions
|
@ -1,12 +1,12 @@
|
|||
import * as Koa from 'koa';
|
||||
|
||||
import Endpoint from './endpoint';
|
||||
import { IEndpoint } from './endpoints';
|
||||
import authenticate from './authenticate';
|
||||
import call from './call';
|
||||
import { IUser } from '../../models/user';
|
||||
import { IApp } from '../../models/app';
|
||||
|
||||
export default async (endpoint: Endpoint, ctx: Koa.Context) => {
|
||||
export default async (endpoint: IEndpoint, ctx: Koa.Context) => {
|
||||
const body = ctx.is('multipart/form-data') ? (ctx.req as any).body : ctx.request.body;
|
||||
|
||||
const reply = (x?: any, y?: any) => {
|
||||
|
@ -37,7 +37,7 @@ export default async (endpoint: Endpoint, ctx: Koa.Context) => {
|
|||
|
||||
// API invoking
|
||||
try {
|
||||
res = await call(endpoint, user, app, body, (ctx.req as any).file);
|
||||
res = await call(endpoint.name, user, app, body, (ctx.req as any).file);
|
||||
} catch (e) {
|
||||
reply(400, e);
|
||||
return;
|
||||
|
|
|
@ -1,35 +1,12 @@
|
|||
import * as path from 'path';
|
||||
import * as glob from 'glob';
|
||||
|
||||
import Endpoint from './endpoint';
|
||||
import limitter from './limitter';
|
||||
import { IUser } from '../../models/user';
|
||||
import { IApp } from '../../models/app';
|
||||
import endpoints from './endpoints';
|
||||
|
||||
const files = glob.sync('**/*.js', {
|
||||
cwd: path.resolve(__dirname + '/endpoints/')
|
||||
});
|
||||
|
||||
const endpoints: Array<{
|
||||
exec: any,
|
||||
meta: Endpoint
|
||||
}> = files.map(f => {
|
||||
const ep = require('./endpoints/' + f);
|
||||
|
||||
ep.meta = ep.meta || {};
|
||||
ep.meta.name = f.replace('.js', '');
|
||||
|
||||
return {
|
||||
exec: ep.default,
|
||||
meta: ep.meta
|
||||
};
|
||||
});
|
||||
|
||||
export default (endpoint: string | Endpoint, user: IUser, app: IApp, data: any, file?: any) => new Promise<any>(async (ok, rej) => {
|
||||
export default (endpoint: string, user: IUser, app: IApp, data: any, file?: any) => new Promise<any>(async (ok, rej) => {
|
||||
const isSecure = user != null && app == null;
|
||||
|
||||
const epName = typeof endpoint === 'string' ? endpoint : endpoint.name;
|
||||
const ep = endpoints.find(e => e.meta.name === epName);
|
||||
const ep = endpoints.find(e => e.name === endpoint);
|
||||
|
||||
if (ep.meta.secure && !isSecure) {
|
||||
return rej('ACCESS_DENIED');
|
||||
|
@ -51,7 +28,7 @@ export default (endpoint: string | Endpoint, user: IUser, app: IApp, data: any,
|
|||
|
||||
if (ep.meta.requireCredential && ep.meta.limit) {
|
||||
try {
|
||||
await limitter(ep.meta, user); // Rate limit
|
||||
await limitter(ep, user); // Rate limit
|
||||
} catch (e) {
|
||||
// drop request if limit exceeded
|
||||
return rej('RATE_LIMIT_EXCEEDED');
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
export default interface IEndpoint {
|
||||
/**
|
||||
* エンドポイント名
|
||||
*/
|
||||
name: string;
|
||||
import * as path from 'path';
|
||||
import * as glob from 'glob';
|
||||
|
||||
export interface IEndpointMeta {
|
||||
/**
|
||||
* このエンドポイントにリクエストするのにユーザー情報が必須か否か
|
||||
* 省略した場合は false として解釈されます。
|
||||
|
@ -58,3 +56,25 @@ export default interface IEndpoint {
|
|||
*/
|
||||
kind?: string;
|
||||
}
|
||||
|
||||
export interface IEndpoint {
|
||||
name: string;
|
||||
exec: any;
|
||||
meta: IEndpointMeta;
|
||||
}
|
||||
|
||||
const files = glob.sync('**/*.js', {
|
||||
cwd: path.resolve(__dirname + '/endpoints/')
|
||||
});
|
||||
|
||||
const endpoints: IEndpoint[] = files.map(f => {
|
||||
const ep = require('./endpoints/' + f);
|
||||
|
||||
return {
|
||||
name: f.replace('.js', ''),
|
||||
exec: ep.default,
|
||||
meta: ep.meta || {}
|
||||
};
|
||||
});
|
||||
|
||||
export default endpoints;
|
|
@ -1,8 +1,36 @@
|
|||
import * as fs from 'fs';
|
||||
const ms = require('ms');
|
||||
import $ from 'cafy'; import ID from '../../../../../misc/cafy-id';
|
||||
import { validateFileName, pack } from '../../../../../models/drive-file';
|
||||
import create from '../../../../../services/drive/add-file';
|
||||
import { ILocalUser } from '../../../../../models/user';
|
||||
import getParams from '../../../get-params';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
ja: 'ドライブにファイルをアップロードします。'
|
||||
},
|
||||
|
||||
requireCredential: true,
|
||||
|
||||
limit: {
|
||||
duration: ms('1hour'),
|
||||
max: 100
|
||||
},
|
||||
|
||||
withFile: true,
|
||||
|
||||
kind: 'drive-write',
|
||||
|
||||
params: {
|
||||
folderId: $.type(ID).optional.nullable.note({
|
||||
default: null,
|
||||
desc: {
|
||||
ja: 'フォルダID'
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a file
|
||||
|
@ -27,17 +55,19 @@ export default async (file: any, params: any, user: ILocalUser): Promise<any> =>
|
|||
name = null;
|
||||
}
|
||||
|
||||
// Get 'folderId' parameter
|
||||
const [folderId = null, folderIdErr] = $.type(ID).optional.nullable.get(params.folderId);
|
||||
if (folderIdErr) throw 'invalid folderId param';
|
||||
|
||||
function cleanup() {
|
||||
fs.unlink(file.path, () => {});
|
||||
}
|
||||
|
||||
const [ps, psErr] = getParams(meta, params);
|
||||
if (psErr) {
|
||||
cleanup();
|
||||
throw psErr;
|
||||
}
|
||||
|
||||
try {
|
||||
// Create file
|
||||
const driveFile = await create(user, file.path, name, null, folderId);
|
||||
const driveFile = await create(user, file.path, name, null, ps.folderId);
|
||||
|
||||
cleanup();
|
||||
|
||||
|
|
|
@ -8,8 +8,6 @@ import { IApp } from '../../../../models/app';
|
|||
import getParams from '../../get-params';
|
||||
|
||||
export const meta = {
|
||||
name: 'notes/create',
|
||||
|
||||
desc: {
|
||||
ja: '投稿します。'
|
||||
},
|
||||
|
|
|
@ -35,7 +35,7 @@ const router = new Router();
|
|||
/**
|
||||
* Register endpoint handlers
|
||||
*/
|
||||
endpoints.forEach(endpoint => endpoint.withFile
|
||||
endpoints.forEach(endpoint => endpoint.meta.withFile
|
||||
? router.post(`/${endpoint.name}`, upload.single('file'), handler.bind(null, endpoint))
|
||||
: router.post(`/${endpoint.name}`, handler.bind(null, endpoint))
|
||||
);
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import * as Limiter from 'ratelimiter';
|
||||
import * as debug from 'debug';
|
||||
import limiterDB from '../../db/redis';
|
||||
import Endpoint from './endpoint';
|
||||
import { IEndpoint } from './endpoints';
|
||||
import getAcct from '../../misc/acct/render';
|
||||
import { IUser } from '../../models/user';
|
||||
|
||||
const log = debug('misskey:limitter');
|
||||
|
||||
export default (endpoint: Endpoint, user: IUser) => new Promise((ok, reject) => {
|
||||
const limitation = endpoint.limit;
|
||||
export default (endpoint: IEndpoint, user: IUser) => new Promise((ok, reject) => {
|
||||
const limitation = endpoint.meta.limit;
|
||||
|
||||
const key = limitation.hasOwnProperty('key')
|
||||
? limitation.key
|
||||
|
|
|
@ -168,14 +168,15 @@ router.get('/assets/*', async ctx => {
|
|||
|
||||
router.get('/*/api/endpoints/*', async ctx => {
|
||||
const lang = ctx.params[0];
|
||||
const ep = require('../../../built/server/api/endpoints/' + ctx.params[1]).meta;
|
||||
const name = ctx.params[1];
|
||||
const ep = require('../../../built/server/api/endpoints/' + name).meta || {};
|
||||
|
||||
const vars = {
|
||||
title: ep.name,
|
||||
endpoint: ep.name,
|
||||
title: name,
|
||||
endpoint: name,
|
||||
url: {
|
||||
host: config.api_url,
|
||||
path: ep.name
|
||||
path: name
|
||||
},
|
||||
desc: ep.desc,
|
||||
// @ts-ignore
|
||||
|
|
Loading…
Reference in a new issue