nameId廃止 & アプリ作成時にシークレットを返すように
This commit is contained in:
parent
d60c3c4ee3
commit
bb7b335491
@ -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…
Reference in New Issue
Block a user