2FA有効時、パスワードをチェックしてからトークンを確認するように

This commit is contained in:
まっちゃとーにゅ 2023-10-11 11:26:04 +09:00
parent 511ff69900
commit 70abe21589
No known key found for this signature in database
GPG key ID: 143DE582A97FE052
8 changed files with 57 additions and 62 deletions

View file

@ -61,10 +61,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (profile.twoFactorEnabled) { if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) { if (token == null) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
@ -74,14 +79,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} catch (e) { } catch (e) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
} } else {
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (!profile.twoFactorEnabled) {
throw new ApiError(meta.errors.twoFactorNotEnabled); throw new ApiError(meta.errors.twoFactorNotEnabled);
} }

View file

@ -58,7 +58,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private userAuthService: UserAuthService, private userAuthService: UserAuthService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOne({ const profile = await this.userProfilesRepository.findOne({
where: { where: {
userId: me.id, userId: me.id,
@ -70,7 +69,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
throw new ApiError(meta.errors.userNotFound); throw new ApiError(meta.errors.userNotFound);
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (profile.twoFactorEnabled) { if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) { if (token == null) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
@ -80,14 +85,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} catch (e) { } catch (e) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
} } else {
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (!profile.twoFactorEnabled) {
throw new ApiError(meta.errors.twoFactorNotEnabled); throw new ApiError(meta.errors.twoFactorNotEnabled);
} }

View file

@ -49,10 +49,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private userAuthService: UserAuthService, private userAuthService: UserAuthService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (profile.twoFactorEnabled) { if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) { if (token == null) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
@ -64,11 +69,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
// Generate user's secret key // Generate user's secret key
const secret = new OTPAuth.Secret(); const secret = new OTPAuth.Secret();

View file

@ -51,10 +51,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (profile.twoFactorEnabled) { if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) { if (token == null) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
@ -66,11 +71,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
// Make sure we only delete the user's own creds // Make sure we only delete the user's own creds
await this.userSecurityKeysRepository.delete({ await this.userSecurityKeysRepository.delete({
userId: me.id, userId: me.id,

View file

@ -47,10 +47,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (profile.twoFactorEnabled) { if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) { if (token == null) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
@ -62,11 +67,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? '');
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
await this.userProfilesRepository.update(me.id, { await this.userProfilesRepository.update(me.id, {
twoFactorSecret: null, twoFactorSecret: null,
twoFactorBackupSecret: null, twoFactorBackupSecret: null,

View file

@ -35,10 +35,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private userAuthService: UserAuthService, private userAuthService: UserAuthService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
const passwordMatched = await bcrypt.compare(ps.currentPassword, profile.password!);
if (!passwordMatched) {
throw new Error('incorrect password');
}
if (profile.twoFactorEnabled) { if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) { if (token == null) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
@ -50,12 +55,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.currentPassword, profile.password!);
if (!passwordMatched) {
throw new Error('incorrect password');
}
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const salt = await bcrypt.genSalt(8);
const hash = await bcrypt.hash(ps.newPassword, salt); const hash = await bcrypt.hash(ps.newPassword, salt);

View file

@ -40,21 +40,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private deleteAccountService: DeleteAccountService, private deleteAccountService: DeleteAccountService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
if (profile.twoFactorEnabled) {
if (token == null) {
throw new Error('authentication failed');
}
try {
await this.userAuthService.twoFactorAuthenticate(profile, token);
} catch (e) {
throw new Error('authentication failed');
}
}
const userDetailed = await this.usersRepository.findOneByOrFail({ id: me.id }); const userDetailed = await this.usersRepository.findOneByOrFail({ id: me.id });
if (userDetailed.isDeleted) { if (userDetailed.isDeleted) {
return; return;
@ -65,6 +52,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new Error('incorrect password'); throw new Error('incorrect password');
} }
if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) {
throw new Error('authentication failed');
}
try {
await this.userAuthService.twoFactorAuthenticate(profile, token);
} catch (e) {
throw new Error('authentication failed');
}
}
await this.deleteAccountService.deleteAccount(me); await this.deleteAccountService.deleteAccount(me);
}); });
} }

View file

@ -68,10 +68,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const token = ps.token;
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
const passwordMatched = await bcrypt.compare(ps.password, profile.password!);
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (profile.twoFactorEnabled) { if (profile.twoFactorEnabled) {
const token = ps.token;
if (token == null) { if (token == null) {
throw new Error('authentication failed'); throw new Error('authentication failed');
} }
@ -83,11 +88,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password!);
if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword);
}
if (ps.email != null) { if (ps.email != null) {
const res = await this.emailService.validateEmailForAccount(ps.email); const res = await this.emailService.validateEmailForAccount(ps.email);
if (!res.available) { if (!res.available) {