From 748dc308e95dbcef8ea49c8e39fa4549ddc1480f Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Sun, 19 Apr 2026 11:13:32 +0200 Subject: [PATCH 1/5] fix: select `visibility` on `connected_accounts` --- src/api/routes/users/#user_id/profile.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/api/routes/users/#user_id/profile.ts b/src/api/routes/users/#user_id/profile.ts index 2a580c4b3..c6a55201a 100644 --- a/src/api/routes/users/#user_id/profile.ts +++ b/src/api/routes/users/#user_id/profile.ts @@ -35,6 +35,17 @@ router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), id: user_id, }, relations: { connected_accounts: true }, + select: { + // Manually select everything cause typeorm is a fuck + connected_accounts: { + id: true, + type: true, + name: true, + verified: true, + metadata_: true, + visibility: true, + }, + }, }); const mutual_guilds: object[] = []; From 9a46c3a7128fbc448abe87752fcae36cf2f62753 Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Sun, 19 Apr 2026 11:17:44 +0200 Subject: [PATCH 2/5] fix: expose only public properties --- src/api/routes/users/#user_id/profile.ts | 29 +++++++++++++++++-- .../PartialConnectedAccountResponse.ts | 25 ++++++++++++++++ src/schemas/responses/index.ts | 1 + 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/schemas/responses/PartialConnectedAccountResponse.ts diff --git a/src/api/routes/users/#user_id/profile.ts b/src/api/routes/users/#user_id/profile.ts index c6a55201a..64e09bb68 100644 --- a/src/api/routes/users/#user_id/profile.ts +++ b/src/api/routes/users/#user_id/profile.ts @@ -20,7 +20,7 @@ import { route } from "@spacebar/api"; import { Badge, Config, emitEvent, FieldErrors, handleFile, Member, Relationship, User, UserUpdateEvent } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { In } from "typeorm"; -import { PrivateUserProjection, PublicUser, PublicUserProjection, RelationshipType, UserProfileModifySchema } from "@spacebar/schemas"; +import { PartialConnectedAccountResponse, PrivateUserProjection, PublicUser, PublicUserProjection, RelationshipType, UserProfileModifySchema } from "@spacebar/schemas"; const router: Router = Router({ mergeParams: true }); @@ -123,8 +123,33 @@ router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), } } + // Only expose public propeties to response + const publicUserConnections: PartialConnectedAccountResponse[] = []; + + user.connected_accounts + .filter((x) => x.visibility != 0) + .map((x) => { + const publicUserConnection = { + id: x.id, + type: x.type, + name: x.name, + verified: x.verified ?? false, + } satisfies PartialConnectedAccountResponse; + + if (x.verified) { + publicUserConnection.verified = x.verified; + } + + if (x.metadata_visibility != 0) { + // @ts-expect-error idk + x.metadata = x.metadata_; + } + + publicUserConnections.push(publicUserConnection); + }); + res.json({ - connected_accounts: user.connected_accounts.filter((x) => x.visibility != 0), + connected_accounts: publicUserConnections, premium_guild_since: premium_guild_since, // TODO premium_since: user.premium_since, // TODO mutual_guilds: with_mutual_guilds ? mutual_guilds : undefined, // TODO {id: "", nick: null} when ?with_mutual_guilds=true diff --git a/src/schemas/responses/PartialConnectedAccountResponse.ts b/src/schemas/responses/PartialConnectedAccountResponse.ts new file mode 100644 index 000000000..d5d3ee844 --- /dev/null +++ b/src/schemas/responses/PartialConnectedAccountResponse.ts @@ -0,0 +1,25 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2026 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +export interface PartialConnectedAccountResponse { + id: string; + type: string; + name: string; + verified: boolean; + metadata?: object; +} diff --git a/src/schemas/responses/index.ts b/src/schemas/responses/index.ts index 690b1ec53..e231879e8 100644 --- a/src/schemas/responses/index.ts +++ b/src/schemas/responses/index.ts @@ -49,6 +49,7 @@ export * from "./InstanceStatsResponse"; export * from "./LocationMetadataResponse"; export * from "./MemberJoinGuildResponse"; export * from "./OAuthAuthorizeResponse"; +export * from "./PartialConnectedAccountResponse"; export * from "./PreloadMessagesResponseSchema"; export * from "./RefreshUrlsResponse"; export * from "./SettingsProtoUpdateResponse"; From 7619e08c9d86c796eae0716d0afb1a03589a2543 Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Sun, 19 Apr 2026 11:19:50 +0200 Subject: [PATCH 3/5] fix: expose metadata if should be visible --- src/api/routes/users/#user_id/profile.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api/routes/users/#user_id/profile.ts b/src/api/routes/users/#user_id/profile.ts index 64e09bb68..a29fe748b 100644 --- a/src/api/routes/users/#user_id/profile.ts +++ b/src/api/routes/users/#user_id/profile.ts @@ -43,6 +43,7 @@ router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), name: true, verified: true, metadata_: true, + metadata_visibility: true, visibility: true, }, }, @@ -142,7 +143,7 @@ router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), if (x.metadata_visibility != 0) { // @ts-expect-error idk - x.metadata = x.metadata_; + publicUserConnection.metadata = x.metadata_; } publicUserConnections.push(publicUserConnection); From 086f3378f90c8e7f445e66dc973cc7f1f5a2bfb2 Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Sun, 19 Apr 2026 11:31:45 +0200 Subject: [PATCH 4/5] remove oversight --- src/api/routes/users/#user_id/profile.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/api/routes/users/#user_id/profile.ts b/src/api/routes/users/#user_id/profile.ts index a29fe748b..7dd4e7a4b 100644 --- a/src/api/routes/users/#user_id/profile.ts +++ b/src/api/routes/users/#user_id/profile.ts @@ -137,10 +137,6 @@ router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), verified: x.verified ?? false, } satisfies PartialConnectedAccountResponse; - if (x.verified) { - publicUserConnection.verified = x.verified; - } - if (x.metadata_visibility != 0) { // @ts-expect-error idk publicUserConnection.metadata = x.metadata_; From 0bf9a09a6a70a36bfde98338210e5715c6c38bea Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Sun, 19 Apr 2026 11:34:36 +0200 Subject: [PATCH 5/5] fix comment typo --- src/api/routes/users/#user_id/profile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/routes/users/#user_id/profile.ts b/src/api/routes/users/#user_id/profile.ts index 7dd4e7a4b..c9a9bb92d 100644 --- a/src/api/routes/users/#user_id/profile.ts +++ b/src/api/routes/users/#user_id/profile.ts @@ -124,7 +124,7 @@ router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), } } - // Only expose public propeties to response + // Only expose public properties to response const publicUserConnections: PartialConnectedAccountResponse[] = []; user.connected_accounts