From f11bdf36b9c75a3e10850e46ef045cf9675ab7f7 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 3 Mar 2017 19:48:00 +0900 Subject: wip --- src/api/endpoints/app/create.js | 128 ----------------------------- src/api/endpoints/app/create.ts | 114 +++++++++++++++++++++++++ src/api/endpoints/app/name_id/available.js | 69 ---------------- src/api/endpoints/app/name_id/available.ts | 64 +++++++++++++++ src/api/endpoints/app/show.js | 81 ------------------ src/api/endpoints/app/show.ts | 77 +++++++++++++++++ src/api/models/app.ts | 4 + src/api/serializers/app.ts | 4 +- 8 files changed, 261 insertions(+), 280 deletions(-) delete mode 100644 src/api/endpoints/app/create.js create mode 100644 src/api/endpoints/app/create.ts delete mode 100644 src/api/endpoints/app/name_id/available.js create mode 100644 src/api/endpoints/app/name_id/available.ts delete mode 100644 src/api/endpoints/app/show.js create mode 100644 src/api/endpoints/app/show.ts (limited to 'src') diff --git a/src/api/endpoints/app/create.js b/src/api/endpoints/app/create.js deleted file mode 100644 index 8b85da7ffa..0000000000 --- a/src/api/endpoints/app/create.js +++ /dev/null @@ -1,128 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import rndstr from 'rndstr'; -import App from '../../models/app'; -import serialize from '../../serializers/app'; - -/** - * @swagger - * /app/create: - * post: - * summary: Create an application - * parameters: - * - $ref: "#/parameters/AccessToken" - * - - * name: name_id - * description: Application unique name - * in: formData - * required: true - * type: string - * - - * name: name - * description: Application name - * in: formData - * required: true - * type: string - * - - * name: description - * description: Application description - * in: formData - * required: true - * type: string - * - - * name: permission - * description: Permissions that application has - * in: formData - * required: true - * type: array - * items: - * type: string - * collectionFormat: csv - * - - * name: callback_url - * description: URL called back after authentication - * in: formData - * required: false - * type: string - * - * responses: - * 200: - * description: Created application's information - * schema: - * $ref: "#/definitions/Application" - * - * default: - * description: Failed - * schema: - * $ref: "#/definitions/Error" - */ - -/** - * Create an app - * - * @param {any} params - * @param {any} user - * @return {Promise} - */ -module.exports = async (params, user) => - new Promise(async (res, rej) => -{ - // Get 'name_id' parameter - const nameId = params.name_id; - if (nameId == null) { - return rej('name_id is required'); - } else if (typeof nameId != 'string') { - return rej('name_id must be a string'); - } - - // Validate name_id - if (!/^[a-zA-Z0-9\-]{3,30}$/.test(nameId)) { - return rej('invalid name_id'); - } - - // Get 'name' parameter - const name = params.name; - if (name == null || name == '') { - return rej('name is required'); - } - - // Get 'description' parameter - const description = params.description; - if (description == null || description == '') { - return rej('description is required'); - } - - // Get 'permission' parameter - const permission = params.permission; - if (permission == null || permission == '') { - return rej('permission is required'); - } - - // Get 'callback_url' parameter - let callback = params.callback_url; - if (callback === '') { - callback = null; - } - - // Generate secret - const secret = rndstr('a-zA-Z0-9', 32); - - // Create account - const app = await App.insert({ - created_at: new Date(), - user_id: user._id, - name: name, - name_id: nameId, - name_id_lower: nameId.toLowerCase(), - description: description, - permission: permission.split(','), - callback_url: callback, - secret: secret - }); - - // Response - res(await serialize(app)); -}); diff --git a/src/api/endpoints/app/create.ts b/src/api/endpoints/app/create.ts new file mode 100644 index 0000000000..adbb205f62 --- /dev/null +++ b/src/api/endpoints/app/create.ts @@ -0,0 +1,114 @@ +'use strict'; + +/** + * Module dependencies + */ +import rndstr from 'rndstr'; +import it from '../../it'; +import App from '../../models/app'; +import { isValidNameId } from '../../models/app'; +import serialize from '../../serializers/app'; + +/** + * @swagger + * /app/create: + * post: + * summary: Create an application + * parameters: + * - $ref: "#/parameters/AccessToken" + * - + * name: name_id + * description: Application unique name + * in: formData + * required: true + * type: string + * - + * name: name + * description: Application name + * in: formData + * required: true + * type: string + * - + * name: description + * description: Application description + * in: formData + * required: true + * type: string + * - + * name: permission + * description: Permissions that application has + * in: formData + * required: true + * type: array + * items: + * type: string + * collectionFormat: csv + * - + * name: callback_url + * description: URL called back after authentication + * in: formData + * required: false + * type: string + * + * responses: + * 200: + * description: Created application's information + * schema: + * $ref: "#/definitions/Application" + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + +/** + * Create an app + * + * @param {any} params + * @param {any} user + * @return {Promise} + */ +module.exports = async (params, user) => + new Promise(async (res, rej) => +{ + // Get 'name_id' parameter + const [nameId, nameIdErr] = it(params.name_id).expect.string().required().validate(isValidNameId).qed(); + if (nameIdErr) return rej('invalid name_id param'); + + // Get 'name' parameter + const [name, nameErr] = it(params.name).expect.string().required().qed(); + if (nameErr) return rej('invalid name param'); + + // Get 'description' parameter + const [description, descriptionErr] = it(params.description).expect.string().required().qed(); + if (descriptionErr) return rej('invalid description param'); + + // Get 'permission' parameter + const [permission, permissionErr] = it(params.permission).expect.array().unique().allString().required().qed(); + if (permissionErr) return rej('invalid permission param'); + + // Get 'callback_url' parameter + // TODO: Check it is valid url + const [callbackUrl, callbackUrlErr] = it(params.callback_url).expect.nullable.string().default(null).qed(); + if (callbackUrlErr) return rej('invalid callback_url param'); + + // Generate secret + const secret = rndstr('a-zA-Z0-9', 32); + + // Create account + const app = await App.insert({ + created_at: new Date(), + user_id: user._id, + name: name, + name_id: nameId, + name_id_lower: nameId.toLowerCase(), + description: description, + permission: permission, + callback_url: callbackUrl, + secret: secret + }); + + // Response + res(await serialize(app)); +}); diff --git a/src/api/endpoints/app/name_id/available.js b/src/api/endpoints/app/name_id/available.js deleted file mode 100644 index 159d4fff4e..0000000000 --- a/src/api/endpoints/app/name_id/available.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import App from '../../../models/app'; - -/** - * @swagger - * /app/name_id/available: - * post: - * summary: Check available name_id on creation an application - * parameters: - * - - * name: name_id - * description: Application unique name - * in: formData - * required: true - * type: string - * - * responses: - * 200: - * description: Success - * schema: - * type: object - * properties: - * available: - * description: Whether name_id is available - * type: boolean - * - * default: - * description: Failed - * schema: - * $ref: "#/definitions/Error" - */ - -/** - * Check available name_id of app - * - * @param {any} params - * @return {Promise} - */ -module.exports = async (params) => - new Promise(async (res, rej) => -{ - // Get 'name_id' parameter - const nameId = params.name_id; - if (nameId == null || nameId == '') { - return rej('name_id is required'); - } - - // Validate name_id - if (!/^[a-zA-Z0-9\-]{3,30}$/.test(nameId)) { - return rej('invalid name_id'); - } - - // Get exist - const exist = await App - .count({ - name_id_lower: nameId.toLowerCase() - }, { - limit: 1 - }); - - // Reply - res({ - available: exist === 0 - }); -}); diff --git a/src/api/endpoints/app/name_id/available.ts b/src/api/endpoints/app/name_id/available.ts new file mode 100644 index 0000000000..6af18ae83c --- /dev/null +++ b/src/api/endpoints/app/name_id/available.ts @@ -0,0 +1,64 @@ +'use strict'; + +/** + * Module dependencies + */ +import it from '../../../it'; +import App from '../../../models/app'; +import { isValidNameId } from '../../../models/app'; + +/** + * @swagger + * /app/name_id/available: + * post: + * summary: Check available name_id on creation an application + * parameters: + * - + * name: name_id + * description: Application unique name + * in: formData + * required: true + * type: string + * + * responses: + * 200: + * description: Success + * schema: + * type: object + * properties: + * available: + * description: Whether name_id is available + * type: boolean + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + +/** + * Check available name_id of app + * + * @param {any} params + * @return {Promise} + */ +module.exports = async (params) => + new Promise(async (res, rej) => +{ + // Get 'name_id' parameter + const [nameId, nameIdErr] = it(params.name_id).expect.string().required().validate(isValidNameId).qed(); + if (nameIdErr) return rej('invalid name_id param'); + + // Get exist + const exist = await App + .count({ + name_id_lower: nameId.toLowerCase() + }, { + limit: 1 + }); + + // Reply + res({ + available: exist === 0 + }); +}); diff --git a/src/api/endpoints/app/show.js b/src/api/endpoints/app/show.js deleted file mode 100644 index ab5f6f4562..0000000000 --- a/src/api/endpoints/app/show.js +++ /dev/null @@ -1,81 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import * as mongo from 'mongodb'; -import App from '../../models/app'; -import serialize from '../../serializers/app'; - -/** - * @swagger - * /app/show: - * post: - * summary: Show an application's information - * description: Require app_id or name_id - * parameters: - * - - * name: app_id - * description: Application ID - * in: formData - * type: string - * - - * name: name_id - * description: Application unique name - * in: formData - * type: string - * - * responses: - * 200: - * description: Success - * schema: - * $ref: "#/definitions/Application" - * - * default: - * description: Failed - * schema: - * $ref: "#/definitions/Error" - */ - -/** - * Show an app - * - * @param {any} params - * @param {any} user - * @param {any} _ - * @param {any} isSecure - * @return {Promise} - */ -module.exports = (params, user, _, isSecure) => - new Promise(async (res, rej) => -{ - // Get 'app_id' parameter - let appId = params.app_id; - if (appId == null || appId == '') { - appId = null; - } - - // Get 'name_id' parameter - let nameId = params.name_id; - if (nameId == null || nameId == '') { - nameId = null; - } - - if (appId === null && nameId === null) { - return rej('app_id or name_id is required'); - } - - // Lookup app - const app = appId !== null - ? await App.findOne({ _id: new mongo.ObjectID(appId) }) - : await App.findOne({ name_id_lower: nameId.toLowerCase() }); - - if (app === null) { - return rej('app not found'); - } - - // Send response - res(await serialize(app, user, { - includeSecret: isSecure && app.user_id.equals(user._id) - })); -}); diff --git a/src/api/endpoints/app/show.ts b/src/api/endpoints/app/show.ts new file mode 100644 index 0000000000..cfb03bb9e5 --- /dev/null +++ b/src/api/endpoints/app/show.ts @@ -0,0 +1,77 @@ +'use strict'; + +/** + * Module dependencies + */ +import it from '../../it'; +import App from '../../models/app'; +import serialize from '../../serializers/app'; + +/** + * @swagger + * /app/show: + * post: + * summary: Show an application's information + * description: Require app_id or name_id + * parameters: + * - + * name: app_id + * description: Application ID + * in: formData + * type: string + * - + * name: name_id + * description: Application unique name + * in: formData + * type: string + * + * responses: + * 200: + * description: Success + * schema: + * $ref: "#/definitions/Application" + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + +/** + * Show an app + * + * @param {any} params + * @param {any} user + * @param {any} _ + * @param {any} isSecure + * @return {Promise} + */ +module.exports = (params, user, _, isSecure) => + new Promise(async (res, rej) => +{ + // Get 'app_id' parameter + const [appId, appIdErr] = it(params.app_id, 'id'); + if (appIdErr) return rej('invalid app_id param'); + + // Get 'name_id' parameter + const [nameId, nameIdErr] = it(params.name_id, 'string'); + if (nameIdErr) return rej('invalid name_id param'); + + if (appId === null && nameId === null) { + return rej('app_id or name_id is required'); + } + + // Lookup app + const app = appId !== null + ? await App.findOne({ _id: appId }) + : await App.findOne({ name_id_lower: nameId.toLowerCase() }); + + if (app === null) { + return rej('app not found'); + } + + // Send response + res(await serialize(app, user, { + includeSecret: isSecure && app.user_id.equals(user._id) + })); +}); diff --git a/src/api/models/app.ts b/src/api/models/app.ts index a947d88e4c..bf5dc80c2c 100644 --- a/src/api/models/app.ts +++ b/src/api/models/app.ts @@ -7,3 +7,7 @@ const collection = db.get('apps'); (collection as any).index('secret'); // fuck type definition export default collection as any; // fuck type definition + +export function isValidNameId(nameId: string): boolean { + return typeof nameId == 'string' && /^[a-zA-Z0-9\-]{3,30}$/.test(nameId); +} diff --git a/src/api/serializers/app.ts b/src/api/serializers/app.ts index 9a02c5637a..fdeef338d9 100644 --- a/src/api/serializers/app.ts +++ b/src/api/serializers/app.ts @@ -21,8 +21,8 @@ export default ( app: any, me?: any, options?: { - includeSecret: boolean, - includeProfileImageIds: boolean + includeSecret?: boolean, + includeProfileImageIds?: boolean } ) => new Promise(async (resolve, reject) => { const opts = options || { -- cgit v1.2.3-freya