Sharkey/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts
tamaina 980bf1306e
🎨 2FA設定のデザイン向上 / セキュリティキーの名前を変更できるように (#9985)
* wip

* fix

* wip

* wip

* ✌️

* rename key

* 🎨

* update CHANGELOG.md

* パスワードレスログインの判断はサーバーで

* 日本語

* 日本語

* 日本語

* 日本語

* ✌️

* fix

* refactor

* トークン→確認コード

* fix password-less / qr click

* use otpauth

* 日本語

* autocomplete

* パスワードレス設定は外に出す

* 🎨

* 🎨

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-02-20 16:40:24 +09:00

80 lines
2.2 KiB
TypeScript

import bcrypt from 'bcryptjs';
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UserProfilesRepository, UserSecurityKeysRepository } from '@/models/index.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
requireCredential: true,
secure: true,
} as const;
export const paramDef = {
type: 'object',
properties: {
password: { type: 'string' },
credentialId: { type: 'string' },
},
required: ['password', 'credentialId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userSecurityKeysRepository)
private userSecurityKeysRepository: UserSecurityKeysRepository,
@Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository,
private userEntityService: UserEntityService,
private globalEventService: GlobalEventService,
) {
super(meta, paramDef, async (ps, me) => {
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
// Compare password
const same = await bcrypt.compare(ps.password, profile.password!);
if (!same) {
throw new Error('incorrect password');
}
// Make sure we only delete the user's own creds
await this.userSecurityKeysRepository.delete({
userId: me.id,
id: ps.credentialId,
});
// 使われているキーがなくなったらパスワードレスログインをやめる
const keyCount = await this.userSecurityKeysRepository.count({
where: {
userId: me.id,
},
select: {
id: true,
name: true,
lastUsed: true,
},
});
if (keyCount === 0) {
await this.userProfilesRepository.update(me.id, {
usePasswordLessLogin: false,
});
}
// Publish meUpdated event
this.globalEventService.publishMainStream(me.id, 'meUpdated', await this.userEntityService.pack(me.id, me, {
detail: true,
includeSecrets: true,
}));
return {};
});
}
}