nameId廃止 & アプリ作成時にシークレットを返すように
This commit is contained in:
		
							parent
							
								
									d60c3c4ee3
								
							
						
					
					
						commit
						bb7b335491
					
				
					 6 changed files with 7 additions and 103 deletions
				
			
		| 
						 | 
					@ -7,7 +7,7 @@
 | 
				
			||||||
	<div class="app">
 | 
						<div class="app">
 | 
				
			||||||
		<section>
 | 
							<section>
 | 
				
			||||||
			<h2>{{ app.name }}</h2>
 | 
								<h2>{{ app.name }}</h2>
 | 
				
			||||||
			<p class="nid">{{ app.nameId }}</p>
 | 
								<p class="id">{{ app.id }}</p>
 | 
				
			||||||
			<p class="description">{{ app.description }}</p>
 | 
								<p class="description">{{ app.description }}</p>
 | 
				
			||||||
		</section>
 | 
							</section>
 | 
				
			||||||
		<section>
 | 
							<section>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,16 +5,6 @@
 | 
				
			||||||
			<b-form-group label="アプリケーション名" description="あなたのアプリの名称。">
 | 
								<b-form-group label="アプリケーション名" description="あなたのアプリの名称。">
 | 
				
			||||||
				<b-form-input v-model="name" type="text" placeholder="ex) Misskey for iOS" autocomplete="off" required/>
 | 
									<b-form-input v-model="name" type="text" placeholder="ex) Misskey for iOS" autocomplete="off" required/>
 | 
				
			||||||
			</b-form-group>
 | 
								</b-form-group>
 | 
				
			||||||
			<b-form-group label="ID" description="あなたのアプリのID。">
 | 
					 | 
				
			||||||
				<b-input v-model="nid" type="text" pattern="^[a-zA-Z0-9_]{1,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required/>
 | 
					 | 
				
			||||||
				<p class="info" v-if="nidState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%確認しています...</p>
 | 
					 | 
				
			||||||
				<p class="info" v-if="nidState == 'ok'" style="color:#3CB7B5">%fa:fw check%利用できます</p>
 | 
					 | 
				
			||||||
				<p class="info" v-if="nidState == 'unavailable'" style="color:#FF1161">%fa:fw exclamation-triangle%既に利用されています</p>
 | 
					 | 
				
			||||||
				<p class="info" v-if="nidState == 'error'" style="color:#FF1161">%fa:fw exclamation-triangle%通信エラー</p>
 | 
					 | 
				
			||||||
				<p class="info" v-if="nidState == 'invalid-format'" style="color:#FF1161">%fa:fw exclamation-triangle%a~z、A~Z、0~9、_が使えます</p>
 | 
					 | 
				
			||||||
				<p class="info" v-if="nidState == 'min-range'" style="color:#FF1161">%fa:fw exclamation-triangle%1文字以上でお願いします!</p>
 | 
					 | 
				
			||||||
				<p class="info" v-if="nidState == 'max-range'" style="color:#FF1161">%fa:fw exclamation-triangle%30文字以内でお願いします</p>
 | 
					 | 
				
			||||||
			</b-form-group>
 | 
					 | 
				
			||||||
			<b-form-group label="アプリの概要" description="あなたのアプリの簡単な説明や紹介。">
 | 
								<b-form-group label="アプリの概要" description="あなたのアプリの簡単な説明や紹介。">
 | 
				
			||||||
				<b-textarea v-model="description" placeholder="ex) Misskey iOSクライアント。" autocomplete="off" required></b-textarea>
 | 
									<b-textarea v-model="description" placeholder="ex) Misskey iOSクライアント。" autocomplete="off" required></b-textarea>
 | 
				
			||||||
			</b-form-group>
 | 
								</b-form-group>
 | 
				
			||||||
| 
						 | 
					@ -50,47 +40,16 @@ export default Vue.extend({
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			name: '',
 | 
								name: '',
 | 
				
			||||||
			nid: '',
 | 
					 | 
				
			||||||
			description: '',
 | 
								description: '',
 | 
				
			||||||
			cb: '',
 | 
								cb: '',
 | 
				
			||||||
			nidState: null,
 | 
								nidState: null,
 | 
				
			||||||
			permission: []
 | 
								permission: []
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	watch: {
 | 
					 | 
				
			||||||
		nid() {
 | 
					 | 
				
			||||||
			if (this.nid == null || this.nid == '') {
 | 
					 | 
				
			||||||
				this.nidState = null;
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			const err =
 | 
					 | 
				
			||||||
				!this.nid.match(/^[a-zA-Z0-9_]+$/) ? 'invalid-format' :
 | 
					 | 
				
			||||||
				this.nid.length < 1                 ? 'min-range' :
 | 
					 | 
				
			||||||
				this.nid.length > 30                ? 'max-range' :
 | 
					 | 
				
			||||||
				null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (err) {
 | 
					 | 
				
			||||||
				this.nidState = err;
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.nidState = 'wait';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			(this as any).api('app/name_id/available', {
 | 
					 | 
				
			||||||
				nameId: this.nid
 | 
					 | 
				
			||||||
			}).then(result => {
 | 
					 | 
				
			||||||
				this.nidState = result.available ? 'ok' : 'unavailable';
 | 
					 | 
				
			||||||
			}).catch(err => {
 | 
					 | 
				
			||||||
				this.nidState = 'error';
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		onSubmit() {
 | 
							onSubmit() {
 | 
				
			||||||
			(this as any).api('app/create', {
 | 
								(this as any).api('app/create', {
 | 
				
			||||||
				name: this.name,
 | 
									name: this.name,
 | 
				
			||||||
				nameId: this.nid,
 | 
					 | 
				
			||||||
				description: this.description,
 | 
									description: this.description,
 | 
				
			||||||
				callbackUrl: this.cb,
 | 
									callbackUrl: this.cb,
 | 
				
			||||||
				permission: this.permission
 | 
									permission: this.permission
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,8 +5,6 @@ import db from '../db/mongodb';
 | 
				
			||||||
import config from '../config';
 | 
					import config from '../config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const App = db.get<IApp>('apps');
 | 
					const App = db.get<IApp>('apps');
 | 
				
			||||||
App.createIndex('nameId');
 | 
					 | 
				
			||||||
App.createIndex('nameIdLower');
 | 
					 | 
				
			||||||
App.createIndex('secret');
 | 
					App.createIndex('secret');
 | 
				
			||||||
export default App;
 | 
					export default App;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,17 +14,11 @@ export type IApp = {
 | 
				
			||||||
	userId: mongo.ObjectID | null;
 | 
						userId: mongo.ObjectID | null;
 | 
				
			||||||
	secret: string;
 | 
						secret: string;
 | 
				
			||||||
	name: string;
 | 
						name: string;
 | 
				
			||||||
	nameId: string;
 | 
					 | 
				
			||||||
	nameIdLower: string;
 | 
					 | 
				
			||||||
	description: string;
 | 
						description: string;
 | 
				
			||||||
	permission: string[];
 | 
						permission: string[];
 | 
				
			||||||
	callbackUrl: string;
 | 
						callbackUrl: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function isValidNameId(nameId: string): boolean {
 | 
					 | 
				
			||||||
	return typeof nameId == 'string' && /^[a-zA-Z0-9_]{1,30}$/.test(nameId);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Pack an app for API response
 | 
					 * Pack an app for API response
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -76,8 +68,6 @@ export const pack = (
 | 
				
			||||||
	_app.id = _app._id;
 | 
						_app.id = _app._id;
 | 
				
			||||||
	delete _app._id;
 | 
						delete _app._id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	delete _app.nameIdLower;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Visible by only owner
 | 
						// Visible by only owner
 | 
				
			||||||
	if (!opts.includeSecret) {
 | 
						if (!opts.includeSecret) {
 | 
				
			||||||
		delete _app.secret;
 | 
							delete _app.secret;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import rndstr from 'rndstr';
 | 
					import rndstr from 'rndstr';
 | 
				
			||||||
import $ from 'cafy';
 | 
					import $ from 'cafy';
 | 
				
			||||||
import App, { isValidNameId, pack } from '../../../../models/app';
 | 
					import App, { pack } from '../../../../models/app';
 | 
				
			||||||
import { ILocalUser } from '../../../../models/user';
 | 
					import { ILocalUser } from '../../../../models/user';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const meta = {
 | 
					export const meta = {
 | 
				
			||||||
| 
						 | 
					@ -11,10 +11,6 @@ export const meta = {
 | 
				
			||||||
 * Create an app
 | 
					 * 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 'nameId' parameter
 | 
					 | 
				
			||||||
	const [nameId, nameIdErr] = $.str.pipe(isValidNameId).get(params.nameId);
 | 
					 | 
				
			||||||
	if (nameIdErr) return rej('invalid nameId param');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get 'name' parameter
 | 
						// Get 'name' parameter
 | 
				
			||||||
	const [name, nameErr] = $.str.get(params.name);
 | 
						const [name, nameErr] = $.str.get(params.name);
 | 
				
			||||||
	if (nameErr) return rej('invalid name param');
 | 
						if (nameErr) return rej('invalid name param');
 | 
				
			||||||
| 
						 | 
					@ -40,8 +36,6 @@ 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,
 | 
				
			||||||
		nameId: nameId,
 | 
					 | 
				
			||||||
		nameIdLower: nameId.toLowerCase(),
 | 
					 | 
				
			||||||
		description: description,
 | 
							description: description,
 | 
				
			||||||
		permission: permission,
 | 
							permission: permission,
 | 
				
			||||||
		callbackUrl: callbackUrl,
 | 
							callbackUrl: callbackUrl,
 | 
				
			||||||
| 
						 | 
					@ -49,5 +43,7 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Response
 | 
						// Response
 | 
				
			||||||
	res(await pack(app));
 | 
						res(await pack(app, null, {
 | 
				
			||||||
 | 
							includeSecret: true
 | 
				
			||||||
 | 
						}));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Module dependencies
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
import $ from 'cafy';
 | 
					 | 
				
			||||||
import App from '../../../../../models/app';
 | 
					 | 
				
			||||||
import { isValidNameId } from '../../../../../models/app';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Check available nameId of app
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @param {any} params
 | 
					 | 
				
			||||||
 * @return {Promise<any>}
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export default async (params: any) => new Promise(async (res, rej) => {
 | 
					 | 
				
			||||||
	// Get 'nameId' parameter
 | 
					 | 
				
			||||||
	const [nameId, nameIdErr] = $.str.pipe(isValidNameId).get(params.nameId);
 | 
					 | 
				
			||||||
	if (nameIdErr) return rej('invalid nameId param');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get exist
 | 
					 | 
				
			||||||
	const exist = await App
 | 
					 | 
				
			||||||
		.count({
 | 
					 | 
				
			||||||
			nameIdLower: nameId.toLowerCase()
 | 
					 | 
				
			||||||
		}, {
 | 
					 | 
				
			||||||
			limit: 1
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Reply
 | 
					 | 
				
			||||||
	res({
 | 
					 | 
				
			||||||
		available: exist === 0
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -9,21 +9,11 @@ export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (
 | 
				
			||||||
	const isSecure = user != null && app == null;
 | 
						const isSecure = user != null && app == null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get 'appId' parameter
 | 
						// Get 'appId' parameter
 | 
				
			||||||
	const [appId, appIdErr] = $.type(ID).optional.get(params.appId);
 | 
						const [appId, appIdErr] = $.type(ID).get(params.appId);
 | 
				
			||||||
	if (appIdErr) return rej('invalid appId param');
 | 
						if (appIdErr) return rej('invalid appId param');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get 'nameId' parameter
 | 
					 | 
				
			||||||
	const [nameId, nameIdErr] = $.str.optional.get(params.nameId);
 | 
					 | 
				
			||||||
	if (nameIdErr) return rej('invalid nameId param');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (appId === undefined && nameId === undefined) {
 | 
					 | 
				
			||||||
		return rej('appId or nameId is required');
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Lookup app
 | 
						// Lookup app
 | 
				
			||||||
	const ap = appId !== undefined
 | 
						const ap = await App.findOne({ _id: appId });
 | 
				
			||||||
		? await App.findOne({ _id: appId })
 | 
					 | 
				
			||||||
		: await App.findOne({ nameIdLower: nameId.toLowerCase() });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ap === null) {
 | 
						if (ap === null) {
 | 
				
			||||||
		return rej('app not found');
 | 
							return rej('app not found');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue