From 9813e2d197fc40d761c662b5b89f79f0a21f176e Mon Sep 17 00:00:00 2001 From: jaina heartles Date: Mon, 23 Sep 2024 19:12:30 -0400 Subject: [PATCH] return stub user from users/show to unauthorized clients --- CHANGELOG.md | 1 + .../src/core/entities/UserEntityService.ts | 27 +++++++++++++++++-- .../src/server/api/endpoints/users/show.ts | 10 +++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f4954baa7..b078168a50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 2024.9.1 (eGirlskey) - Impersonate `misskey` upstream in nodeinfo to fix issues with client apps +- Fix two-factor-auth login with `secureApiMode: true` by returning a stub user to unauthorized clients. ## 2024.9.0 (eGirlskey) - First official eGirlskey release not a part of Sharkey diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 752716cfc9..69c754dec4 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -401,7 +401,7 @@ export class UserEntityService implements OnModuleInit { return `${this.config.url}/users/${userId}`; } - public async pack( + public async pack( src: MiUser['id'] | MiUser, me?: { id: MiUser['id']; } | null | undefined, options?: { @@ -510,7 +510,30 @@ export class UserEntityService implements OnModuleInit { const checkHost = user.host == null ? this.config.host : user.host; const notificationsInfo = isMe && isDetailed ? await this.getNotificationsInfo(user.id) : null; - const packed = { + const packed = opts.schema === 'UserLogin' ? { + id: user.id, + name: user.username, + username: user.username, + host: user.host, + avatarUrl: this.getIdenticonUrl(user), + noindex: user.noindex, + instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? { + name: instance.name, + softwareName: instance.softwareName, + softwareVersion: instance.softwareVersion, + iconUrl: instance.iconUrl, + faviconUrl: instance.faviconUrl, + themeColor: instance.themeColor, + } : undefined) : undefined, + + ...(isDetailed ? { + twoFactorEnabled: profile!.twoFactorEnabled, + usePasswordLessLogin: profile!.usePasswordLessLogin, + securityKeys: profile!.twoFactorEnabled + ? this.userSecurityKeysRepository.countBy({ userId: user.id }).then(result => result >= 1) + : false, + } : {}), + } : { id: user.id, name: user.name, username: user.username, diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index 3411cbef6b..795054dabe 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -16,12 +16,13 @@ import { RoleService } from '@/core/RoleService.js'; import { ApiError } from '../../error.js'; import { ApiLoggerService } from '../../ApiLoggerService.js'; import type { FindOptionsWhere } from 'typeorm'; +import type { Config } from '@/config.js'; export const meta = { tags: ['users'], requireCredential: false, - requireCredentialSecureMode: true, + requireCredentialSecureMode: false, // Handle secure mode below description: 'Show the properties of a user.', @@ -83,6 +84,9 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( + @Inject(DI.config) + private config: Config, + @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -148,8 +152,10 @@ export default class extends Endpoint { // eslint- } } + const allowRequest = me != null || !this.config.secureApiMode; + return await this.userEntityService.pack(user, me, { - schema: 'UserDetailed', + schema: allowRequest ? 'UserDetailed' : 'UserLogin', }); } });