summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2019-07-22 10:15:00 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2019-07-22 10:15:00 +0900
commit85008303f5c292dc0f288e4db5b5a1fbd56879eb (patch)
treeaef4c2cf97c7be45f70a8c39846f0b5cd31cb41a /src
parentUpdate dependencies :rocket: (diff)
downloadsharkey-85008303f5c292dc0f288e4db5b5a1fbd56879eb.tar.gz
sharkey-85008303f5c292dc0f288e4db5b5a1fbd56879eb.tar.bz2
sharkey-85008303f5c292dc0f288e4db5b5a1fbd56879eb.zip
Prevent username reusing
Diffstat (limited to 'src')
-rw-r--r--src/db/postgre.ts2
-rw-r--r--src/models/entities/used-username.ts20
-rw-r--r--src/models/index.ts2
-rw-r--r--src/server/api/endpoints/username/available.ts6
-rw-r--r--src/server/api/private/signup.ts14
5 files changed, 41 insertions, 3 deletions
diff --git a/src/db/postgre.ts b/src/db/postgre.ts
index 16cfbd2b2f..00476b8774 100644
--- a/src/db/postgre.ts
+++ b/src/db/postgre.ts
@@ -48,6 +48,7 @@ import { AttestationChallenge } from '../models/entities/attestation-challenge';
import { Page } from '../models/entities/page';
import { PageLike } from '../models/entities/page-like';
import { ModerationLog } from '../models/entities/moderation-log';
+import { UsedUsername } from '../models/entities/used-username';
const sqlLogger = dbLogger.createSubLogger('sql', 'white', false);
@@ -100,6 +101,7 @@ export const entities = [
UserGroupInvite,
UserNotePining,
UserSecurityKey,
+ UsedUsername,
AttestationChallenge,
Following,
FollowRequest,
diff --git a/src/models/entities/used-username.ts b/src/models/entities/used-username.ts
new file mode 100644
index 0000000000..eb90bef6ca
--- /dev/null
+++ b/src/models/entities/used-username.ts
@@ -0,0 +1,20 @@
+import { PrimaryColumn, Entity, Column } from 'typeorm';
+
+@Entity()
+export class UsedUsername {
+ @PrimaryColumn('varchar', {
+ length: 128,
+ })
+ public username: string;
+
+ @Column('timestamp with time zone')
+ public createdAt: Date;
+
+ constructor(data: Partial<UsedUsername>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
diff --git a/src/models/index.ts b/src/models/index.ts
index 388bdc8f6f..fc40ebfb23 100644
--- a/src/models/index.ts
+++ b/src/models/index.ts
@@ -43,6 +43,7 @@ import { HashtagRepository } from './repositories/hashtag';
import { PageRepository } from './repositories/page';
import { PageLikeRepository } from './repositories/page-like';
import { ModerationLogRepository } from './repositories/moderation-logs';
+import { UsedUsername } from './entities/used-username';
export const Apps = getCustomRepository(AppRepository);
export const Notes = getCustomRepository(NoteRepository);
@@ -64,6 +65,7 @@ export const UserGroups = getCustomRepository(UserGroupRepository);
export const UserGroupJoinings = getRepository(UserGroupJoining);
export const UserGroupInvites = getCustomRepository(UserGroupInviteRepository);
export const UserNotePinings = getRepository(UserNotePining);
+export const UsedUsernames = getRepository(UsedUsername);
export const Followings = getCustomRepository(FollowingRepository);
export const FollowRequests = getCustomRepository(FollowRequestRepository);
export const Instances = getRepository(Instance);
diff --git a/src/server/api/endpoints/username/available.ts b/src/server/api/endpoints/username/available.ts
index 724bb3a0c3..f393d6ed0d 100644
--- a/src/server/api/endpoints/username/available.ts
+++ b/src/server/api/endpoints/username/available.ts
@@ -1,6 +1,6 @@
import $ from 'cafy';
import define from '../../define';
-import { Users } from '../../../../models';
+import { Users, UsedUsernames } from '../../../../models';
export const meta = {
tags: ['users'],
@@ -21,7 +21,9 @@ export default define(meta, async (ps) => {
usernameLower: ps.username.toLowerCase()
});
+ const exist2 = await UsedUsernames.count({ username: ps.username.toLowerCase() });
+
return {
- available: exist === 0
+ available: exist === 0 && exist2 === 0
};
});
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index 026fe7485b..c1f06fd339 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -5,7 +5,7 @@ import generateUserToken from '../common/generate-native-user-token';
import config from '../../../config';
import { fetchMeta } from '../../../misc/fetch-meta';
import * as recaptcha from 'recaptcha-promise';
-import { Users, Signins, RegistrationTickets } from '../../../models';
+import { Users, Signins, RegistrationTickets, UsedUsernames } from '../../../models';
import { genId } from '../../../misc/gen-id';
import { usersChart } from '../../../services/chart';
import { User } from '../../../models/entities/user';
@@ -13,6 +13,7 @@ import { UserKeypair } from '../../../models/entities/user-keypair';
import { toPunyNullable } from '../../../misc/convert-host';
import { UserProfile } from '../../../models/entities/user-profile';
import { getConnection } from 'typeorm';
+import { UsedUsername } from '../../../models/entities/used-username';
export default async (ctx: Koa.BaseContext) => {
const body = ctx.request.body as any;
@@ -78,11 +79,18 @@ export default async (ctx: Koa.BaseContext) => {
// Generate secret
const secret = generateUserToken();
+ // Check username duplication
if (await Users.findOne({ usernameLower: username.toLowerCase(), host: null })) {
ctx.status = 400;
return;
}
+ // Check deleted username duplication
+ if (await UsedUsernames.findOne({ username: username.toLowerCase() })) {
+ ctx.status = 400;
+ return;
+ }
+
const keyPair = await new Promise<string[]>((s, j) =>
generateKeyPair('rsa', {
modulusLength: 4096,
@@ -133,6 +141,10 @@ export default async (ctx: Koa.BaseContext) => {
autoWatch: false,
password: hash,
}));
+
+ await transactionalEntityManager.save(new UsedUsername({
+ username: username.toLowerCase(),
+ }));
});
usersChart.update(account, true);