From 9c2bad300a3604b9506a4bb431436148ef8e5442 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sat, 15 Jun 2019 00:07:41 +0900
Subject: [PATCH] Resolve #365

---
 src/models/repositories/messaging-message.ts  |  2 +-
 src/models/repositories/user.ts               | 31 +++++--------------
 src/remote/activitypub/models/person.ts       |  8 +++--
 src/server/api/endpoints/i/update.ts          |  8 ++---
 .../endpoints/messaging/messages/create.ts    |  2 +-
 .../api/endpoints/username/available.ts       |  2 +-
 src/server/api/endpoints/users/search.ts      |  2 +-
 src/server/api/private/signup.ts              |  4 +--
 8 files changed, 23 insertions(+), 36 deletions(-)

diff --git a/src/models/repositories/messaging-message.ts b/src/models/repositories/messaging-message.ts
index 6db2f4fa7..7f0b2047a 100644
--- a/src/models/repositories/messaging-message.ts
+++ b/src/models/repositories/messaging-message.ts
@@ -8,7 +8,7 @@ export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSch
 
 @EntityRepository(MessagingMessage)
 export class MessagingMessageRepository extends Repository<MessagingMessage> {
-	public isValidText(text: string): boolean {
+	public validateText(text: string): boolean {
 		return text.trim().length <= 1000 && text.trim() != '';
 	}
 
diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts
index d3cd75b17..bd48f04ea 100644
--- a/src/models/repositories/user.ts
+++ b/src/models/repositories/user.ts
@@ -1,3 +1,4 @@
+import $ from 'cafy';
 import { EntityRepository, Repository, In } from 'typeorm';
 import { User, ILocalUser, IRemoteUser } from '../entities/user';
 import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserGroupJoinings } from '..';
@@ -231,29 +232,13 @@ export class UserRepository extends Repository<User> {
 	}
 
 	//#region Validators
-	public validateUsername(username: string, remote = false): boolean {
-		return typeof username == 'string' && (remote ? /^\w([\w-]*\w)?$/ : /^\w{1,20}$/).test(username);
-	}
-
-	public validatePassword(password: string): boolean {
-		return typeof password == 'string' && password != '';
-	}
-
-	public isValidName(name?: string): boolean {
-		return name === null || (typeof name == 'string' && name.length < 50 && name.trim() != '');
-	}
-
-	public isValidDescription(description: string): boolean {
-		return typeof description == 'string' && description.length < 500 && description.trim() != '';
-	}
-
-	public isValidLocation(location: string): boolean {
-		return typeof location == 'string' && location.length < 50 && location.trim() != '';
-	}
-
-	public isValidBirthday(birthday: string): boolean {
-		return typeof birthday == 'string' && /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.test(birthday);
-	}
+	public validateLocalUsername = $.str.match(/^\w{1,20}$/);
+	public validateRemoteUsername = $.str.match(/^\w([\w-]*\w)?$/);
+	public validatePassword = $.str.min(1);
+	public validateName = $.str.min(1).max(50);
+	public validateDescription = $.str.min(1).max(500);
+	public validateLocation = $.str.min(1).max(50);
+	public validateBirthday = $.str.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/);
 	//#endregion
 }
 
diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts
index 654d36403..dcd64e0cd 100644
--- a/src/remote/activitypub/models/person.ts
+++ b/src/remote/activitypub/models/person.ts
@@ -53,12 +53,14 @@ function validatePerson(x: any, uri: string) {
 		return new Error('invalid person: inbox is not a string');
 	}
 
-	if (!Users.validateUsername(x.preferredUsername, true)) {
+	if (!Users.validateRemoteUsername.ok(x.preferredUsername)) {
 		return new Error('invalid person: invalid username');
 	}
 
-	if (!Users.isValidName(x.name == '' ? null : x.name)) {
-		return new Error('invalid person: invalid name');
+	if (x.name != null && x.name != '') {
+		if (!Users.validateName.ok(x.name)) {
+			return new Error('invalid person: invalid name');
+		}
 	}
 
 	if (typeof x.id !== 'string') {
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index 2951072cf..10521d12d 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -29,14 +29,14 @@ export const meta = {
 
 	params: {
 		name: {
-			validator: $.optional.nullable.str.pipe(Users.isValidName),
+			validator: $.optional.nullable.use(Users.validateName),
 			desc: {
 				'ja-JP': '名前(ハンドルネームやニックネーム)'
 			}
 		},
 
 		description: {
-			validator: $.optional.nullable.str.pipe(Users.isValidDescription),
+			validator: $.optional.nullable.use(Users.validateDescription),
 			desc: {
 				'ja-JP': 'アカウントの説明や自己紹介'
 			}
@@ -50,14 +50,14 @@ export const meta = {
 		},
 
 		location: {
-			validator: $.optional.nullable.str.pipe(Users.isValidLocation),
+			validator: $.optional.nullable.use(Users.validateLocation),
 			desc: {
 				'ja-JP': '住んでいる地域、所在'
 			}
 		},
 
 		birthday: {
-			validator: $.optional.nullable.str.pipe(Users.isValidBirthday),
+			validator: $.optional.nullable.use(Users.validateBirthday),
 			desc: {
 				'ja-JP': '誕生日 (YYYY-MM-DD形式)'
 			}
diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts
index f5d7cf2b3..feffc9a0c 100644
--- a/src/server/api/endpoints/messaging/messages/create.ts
+++ b/src/server/api/endpoints/messaging/messages/create.ts
@@ -44,7 +44,7 @@ export const meta = {
 		},
 
 		text: {
-			validator: $.optional.str.pipe(MessagingMessages.isValidText)
+			validator: $.optional.str.pipe(MessagingMessages.validateText)
 		},
 
 		fileId: {
diff --git a/src/server/api/endpoints/username/available.ts b/src/server/api/endpoints/username/available.ts
index 42ab17665..724bb3a0c 100644
--- a/src/server/api/endpoints/username/available.ts
+++ b/src/server/api/endpoints/username/available.ts
@@ -9,7 +9,7 @@ export const meta = {
 
 	params: {
 		username: {
-			validator: $.str.pipe(Users.validateUsername)
+			validator: $.use(Users.validateLocalUsername)
 		}
 	}
 };
diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts
index 2809465fd..5c413defb 100644
--- a/src/server/api/endpoints/users/search.ts
+++ b/src/server/api/endpoints/users/search.ts
@@ -66,7 +66,7 @@ export const meta = {
 };
 
 export default define(meta, async (ps, me) => {
-	const isUsername = Users.validateUsername(ps.query.replace('@', ''), !ps.localOnly);
+	const isUsername = ps.localOnly ? Users.validateLocalUsername.ok(ps.query.replace('@', '')) : Users.validateRemoteUsername.ok(ps.query.replace('@', ''));
 
 	let users: User[] = [];
 
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index c75f8fb29..ca197a661 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -58,13 +58,13 @@ export default async (ctx: Koa.BaseContext) => {
 	}
 
 	// Validate username
-	if (!Users.validateUsername(username)) {
+	if (!Users.validateLocalUsername.ok(username)) {
 		ctx.status = 400;
 		return;
 	}
 
 	// Validate password
-	if (!Users.validatePassword(password)) {
+	if (!Users.validatePassword.ok(password)) {
 		ctx.status = 400;
 		return;
 	}