From cd9bce307218c864608a0e60cb5f74262bf10d0c Mon Sep 17 00:00:00 2001 From: Hazel K Date: Mon, 7 Oct 2024 14:58:39 -0400 Subject: [PATCH] prevent login and password reset for system accounts --- locales/en-US.yml | 2 ++ locales/index.d.ts | 8 ++++++++ locales/ja-JP.yml | 2 ++ .../backend/src/server/api/SigninApiService.ts | 7 +++++++ .../server/api/endpoints/admin/reset-password.ts | 5 +++++ packages/frontend/src/components/MkSignin.vue | 5 +++++ packages/frontend/src/pages/admin-user.vue | 2 +- .../src/scripts/show-system-account-dialog.ts | 15 +++++++++++++++ 8 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 packages/frontend/src/scripts/show-system-account-dialog.ts diff --git a/locales/en-US.yml b/locales/en-US.yml index 9160d12382..8163ca525b 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -638,6 +638,8 @@ userSuspended: "This user has been suspended." userSilenced: "This user is being silenced." yourAccountSuspendedTitle: "This account is suspended" yourAccountSuspendedDescription: "This account has been suspended due to breaking the server's terms of services or similar. Contact the administrator if you would like to know a more detailed reason. Please do not create a new account." +systemAccountTitle: "This is a system account" +systemAccountDescription: "This account is created and managed automatically by the system, and cannot be logged into." tokenRevoked: "Invalid token" tokenRevokedDescription: "This token has expired. Please log in again." accountDeleted: "Account deleted" diff --git a/locales/index.d.ts b/locales/index.d.ts index d8f914767f..fcd64071af 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -2568,6 +2568,14 @@ export interface Locale extends ILocale { * このアカウントは、サーバーの利用規約に違反したなどの理由により、凍結されています。詳細については管理者までお問い合わせください。新しいアカウントを作らないでください。 */ "yourAccountSuspendedDescription": string; + /** + * This is a system account + */ + "systemAccountTitle": string; + /** + * This account is created and managed automatically by the system, and cannot be logged into. + */ + "systemAccountDescription": string; /** * トークンが無効です */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 3e168f5087..7e39515c5c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -638,6 +638,8 @@ userSuspended: "このユーザーは凍結されています。" userSilenced: "このユーザーはサイレンスされています。" yourAccountSuspendedTitle: "アカウントが凍結されています" yourAccountSuspendedDescription: "このアカウントは、サーバーの利用規約に違反したなどの理由により、凍結されています。詳細については管理者までお問い合わせください。新しいアカウントを作らないでください。" +systemAccountTitle: "This is a system account" +systemAccountDescription: "This account is created and managed automatically by the system, and cannot be logged into." tokenRevoked: "トークンが無効です" tokenRevokedDescription: "ログイントークンが失効しています。ログインし直してください。" accountDeleted: "アカウントは削除されています" diff --git a/packages/backend/src/server/api/SigninApiService.ts b/packages/backend/src/server/api/SigninApiService.ts index 6fbcacbc11..d212e3de79 100644 --- a/packages/backend/src/server/api/SigninApiService.ts +++ b/packages/backend/src/server/api/SigninApiService.ts @@ -26,6 +26,7 @@ import { RateLimiterService } from './RateLimiterService.js'; import { SigninService } from './SigninService.js'; import type { AuthenticationResponseJSON } from '@simplewebauthn/types'; import type { FastifyReply, FastifyRequest } from 'fastify'; +import { isSystemAccount } from '@/misc/is-system-account.js'; @Injectable() export class SigninApiService { @@ -125,6 +126,12 @@ export class SigninApiService { }); } + if (isSystemAccount(user)) { + return error(403, { + id: 's8dhsj9s-a93j-493j-ja9k-kas9sj20aml2', + }); + } + const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); if (!user.approved && instance.approvalRequiredForSignup) { diff --git a/packages/backend/src/server/api/endpoints/admin/reset-password.ts b/packages/backend/src/server/api/endpoints/admin/reset-password.ts index 828dbae712..e4bb545f5d 100644 --- a/packages/backend/src/server/api/endpoints/admin/reset-password.ts +++ b/packages/backend/src/server/api/endpoints/admin/reset-password.ts @@ -11,6 +11,7 @@ import type { UsersRepository, UserProfilesRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { secureRndstr } from '@/misc/secure-rndstr.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { isSystemAccount } from '@/misc/is-system-account.js'; export const meta = { tags: ['admin'], @@ -63,6 +64,10 @@ export default class extends Endpoint { // eslint- throw new Error('cannot reset password of root'); } + if (isSystemAccount(user)) { + throw new Error('cannot reset password of system account'); + } + const passwd = secureRndstr(8); // Generate hash of password diff --git a/packages/frontend/src/components/MkSignin.vue b/packages/frontend/src/components/MkSignin.vue index 42fa2bf4a7..9813774da3 100644 --- a/packages/frontend/src/components/MkSignin.vue +++ b/packages/frontend/src/components/MkSignin.vue @@ -77,6 +77,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js'; import { query, extractDomain } from '@/scripts/url.js'; import { login } from '@/account.js'; import { i18n } from '@/i18n.js'; +import { showSystemAccountDialog } from '@/scripts/show-system-account-dialog.js'; const signing = ref(false); const user = ref(null); @@ -204,6 +205,10 @@ function loginFailed(err: any): void { showSuspendedDialog(); break; } + case 's8dhsj9s-a93j-493j-ja9k-kas9sj20aml2': { + showSystemAccountDialog(); + break; + } case '22d05606-fbcf-421a-a2db-b32610dcfd1b': { os.alert({ type: 'error', diff --git a/packages/frontend/src/pages/admin-user.vue b/packages/frontend/src/pages/admin-user.vue index 6b663f9128..16a2a7524b 100644 --- a/packages/frontend/src/pages/admin-user.vue +++ b/packages/frontend/src/pages/admin-user.vue @@ -83,7 +83,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.markAsNSFW }}
- {{ i18n.ts.resetPassword }} + {{ i18n.ts.resetPassword }}
diff --git a/packages/frontend/src/scripts/show-system-account-dialog.ts b/packages/frontend/src/scripts/show-system-account-dialog.ts new file mode 100644 index 0000000000..3c28d901fc --- /dev/null +++ b/packages/frontend/src/scripts/show-system-account-dialog.ts @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import * as os from '@/os.js'; +import { i18n } from '@/i18n.js'; + +export function showSystemAccountDialog(): Promise { + return os.alert({ + type: 'error', + title: i18n.ts.systemAccountTitle, + text: i18n.ts.systemAccountDescription, + }); +}