This commit is contained in:
syuilo 2018-03-28 13:05:30 +09:00
parent 0c4bbe6327
commit 9ac196d115
9 changed files with 88 additions and 8 deletions

View file

@ -147,7 +147,7 @@ common:
available: "利用できます" available: "利用できます"
unavailable: "既に利用されています" unavailable: "既に利用されています"
error: "通信エラー" error: "通信エラー"
invalid-format: "a~z、A~Z、0~9、-(ハイフン)が使えます" invalid-format: "a~z、A~Z、0~9、_が使えます"
too-short: "3文字以上でお願いします" too-short: "3文字以上でお願いします"
too-long: "20文字以内でお願いします" too-long: "20文字以内でお願いします"
password: "パスワード" password: "パスワード"

View file

@ -67,7 +67,7 @@ export default class BotCore extends EventEmitter {
return await this.context.q(query); return await this.context.q(query);
} }
if (/^@[a-zA-Z0-9-]+$/.test(query)) { if (/^@[a-zA-Z0-9_]+$/.test(query)) {
return await this.showUserCommand(query); return await this.showUserCommand(query);
} }

View file

@ -1,7 +1,7 @@
<template> <template>
<form class="mk-signin" :class="{ signing }" @submit.prevent="onSubmit"> <form class="mk-signin" :class="{ signing }" @submit.prevent="onSubmit">
<label class="user-name"> <label class="user-name">
<input v-model="username" type="text" pattern="^[a-zA-Z0-9-]+$" placeholder="%i18n:common.tags.mk-signin.username%" autofocus required @change="onUsernameChange"/>%fa:at% <input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" placeholder="%i18n:common.tags.mk-signin.username%" autofocus required @change="onUsernameChange"/>%fa:at%
</label> </label>
<label class="password"> <label class="password">
<input v-model="password" type="password" placeholder="%i18n:common.tags.mk-signin.password%" required/>%fa:lock% <input v-model="password" type="password" placeholder="%i18n:common.tags.mk-signin.password%" required/>%fa:lock%

View file

@ -2,7 +2,7 @@
<form class="mk-signup" @submit.prevent="onSubmit" autocomplete="off"> <form class="mk-signup" @submit.prevent="onSubmit" autocomplete="off">
<label class="username"> <label class="username">
<p class="caption">%fa:at%%i18n:common.tags.mk-signup.username%</p> <p class="caption">%fa:at%%i18n:common.tags.mk-signup.username%</p>
<input v-model="username" type="text" pattern="^[a-zA-Z0-9-]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required @input="onChangeUsername"/> <input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required @input="onChangeUsername"/>
<p class="profile-page-url-preview" v-if="shouldShowProfileUrl">{{ `${url}/@${username}` }}</p> <p class="profile-page-url-preview" v-if="shouldShowProfileUrl">{{ `${url}/@${username}` }}</p>
<p class="info" v-if="usernameState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%%i18n:common.tags.mk-signup.checking%</p> <p class="info" v-if="usernameState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%%i18n:common.tags.mk-signup.checking%</p>
<p class="info" v-if="usernameState == 'ok'" style="color:#3CB7B5">%fa:check .fw%%i18n:common.tags.mk-signup.available%</p> <p class="info" v-if="usernameState == 'ok'" style="color:#3CB7B5">%fa:check .fw%%i18n:common.tags.mk-signup.available%</p>

View file

@ -77,7 +77,7 @@ class Autocomplete {
if (mentionIndex != -1 && mentionIndex > emojiIndex) { if (mentionIndex != -1 && mentionIndex > emojiIndex) {
const username = text.substr(mentionIndex + 1); const username = text.substr(mentionIndex + 1);
if (username != '' && username.match(/^[a-zA-Z0-9-]+$/)) { if (username != '' && username.match(/^[a-zA-Z0-9_]+$/)) {
this.open('user', username); this.open('user', username);
opened = true; opened = true;
} }

View file

@ -6,12 +6,12 @@
<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-form-group label="ID" description="あなたのアプリのID。">
<b-input v-model="nid" type="text" pattern="^[a-zA-Z0-9-]{3,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required/> <b-input v-model="nid" type="text" pattern="^[a-zA-Z0-9_]{3,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 == '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 == '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 == '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 == '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~zA~Z0~9-(ハイフン)が使えます</p> <p class="info" v-if="nidState == 'invalid-format'" style="color:#FF1161">%fa:fw exclamation-triangle%a~zA~Z0~9_が使えます</p>
<p class="info" v-if="nidState == 'min-range'" style="color:#FF1161">%fa:fw exclamation-triangle%3文字以上でお願いします</p> <p class="info" v-if="nidState == 'min-range'" style="color:#FF1161">%fa:fw exclamation-triangle%3文字以上でお願いします</p>
<p class="info" v-if="nidState == 'max-range'" style="color:#FF1161">%fa:fw exclamation-triangle%30文字以内でお願いします</p> <p class="info" v-if="nidState == 'max-range'" style="color:#FF1161">%fa:fw exclamation-triangle%30文字以内でお願いします</p>
</b-form-group> </b-form-group>

View file

@ -6,7 +6,7 @@
<p>%fa:lock% ログイン</p> <p>%fa:lock% ログイン</p>
<div> <div>
<form @submit.prevent="onSubmit"> <form @submit.prevent="onSubmit">
<input v-model="username" type="text" pattern="^[a-zA-Z0-9-]+$" placeholder="ユーザー名" autofocus required @change="onUsernameChange"/> <input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" placeholder="ユーザー名" autofocus required @change="onUsernameChange"/>
<input v-model="password" type="password" placeholder="パスワード" required/> <input v-model="password" type="password" placeholder="パスワード" required/>
<input v-if="user && user.account.two_factor_enabled" v-model="token" type="number" placeholder="トークン" required/> <input v-if="user && user.account.two_factor_enabled" v-model="token" type="number" placeholder="トークン" required/>
<button type="submit" :disabled="signing">{{ signing ? 'ログインしています' : 'ログイン' }}</button> <button type="submit" :disabled="signing">{{ signing ? 'ログインしています' : 'ログイン' }}</button>

View file

@ -0,0 +1,40 @@
// for Node.js interpret
const { default: App } = require('../../built/api/models/app');
const { generate } = require('../../built/crypto_key');
const { default: zip } = require('@prezzemolo/zip')
const migrate = async (app) => {
const result = await User.update(app._id, {
$set: {
'name_id': app.name_id.replace(/\-/g, '_'),
'name_id_lower': app.name_id_lower.replace(/\-/g, '_')
}
});
return result.ok === 1;
}
async function main() {
const count = await App.count({});
const dop = Number.parseInt(process.argv[2]) || 5
const idop = ((count - (count % dop)) / dop) + 1
return zip(
1,
async (time) => {
console.log(`${time} / ${idop}`)
const doc = await App.find({}, {
limit: dop, skip: time * dop
})
return Promise.all(doc.map(migrate))
},
idop
).then(a => {
const rv = []
a.forEach(e => rv.push(...e))
return rv
})
}
main().then(console.dir).catch(console.error)

View file

@ -0,0 +1,40 @@
// for Node.js interpret
const { default: User } = require('../../built/api/models/user');
const { generate } = require('../../built/crypto_key');
const { default: zip } = require('@prezzemolo/zip')
const migrate = async (user) => {
const result = await User.update(user._id, {
$set: {
'username': user.username.replace(/\-/g, '_'),
'username_lower': user.username_lower.replace(/\-/g, '_')
}
});
return result.ok === 1;
}
async function main() {
const count = await User.count({});
const dop = Number.parseInt(process.argv[2]) || 5
const idop = ((count - (count % dop)) / dop) + 1
return zip(
1,
async (time) => {
console.log(`${time} / ${idop}`)
const doc = await User.find({}, {
limit: dop, skip: time * dop
})
return Promise.all(doc.map(migrate))
},
idop
).then(a => {
const rv = []
a.forEach(e => rv.push(...e))
return rv
})
}
main().then(console.dir).catch(console.error)