diff --git a/packages/backend/src/server/api/mastodon/converters/user.ts b/packages/backend/src/server/api/mastodon/converters/user.ts index cd60c3937..afc80bf30 100644 --- a/packages/backend/src/server/api/mastodon/converters/user.ts +++ b/packages/backend/src/server/api/mastodon/converters/user.ts @@ -57,7 +57,8 @@ export class UserConverter { emojis: populateEmojis(u.emojis, u.host).then(emoji => emoji.map((e) => EmojiConverter.encode(e))), moved: null, //FIXME fields: profile.then(profile => profile?.fields.map(p => this.encodeField(p)) ?? []), - bot: u.isBot + bot: u.isBot, + discoverable: u.isExplorable }).then(p => { cache.accounts.push(p); return p; diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index b00861065..d5dff331a 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -31,14 +31,17 @@ export function apiAccountMastodon(router: Router): void { } }); router.patch("/v1/accounts/update_credentials", async (ctx) => { - const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; - const accessTokens = ctx.headers.authorization; - const client = getClient(BASE_URL, accessTokens); try { - const data = await client.updateCredentials( - (ctx.request as any).body as any, - ); - ctx.body = convertAccount(data.data); + const auth = await authenticate(ctx.headers.authorization, null); + const user = auth[0] ?? null; + + if (!user) { + ctx.status = 401; + return; + } + + const acct = await UserHelpers.updateCredentials(user, (ctx.request as any).body as any); + ctx.body = convertAccount(acct) } catch (e: any) { console.error(e); console.error(e.response.data); diff --git a/packages/backend/src/server/api/mastodon/entities/account.ts b/packages/backend/src/server/api/mastodon/entities/account.ts index 737f8ee0d..8ba8a3710 100644 --- a/packages/backend/src/server/api/mastodon/entities/account.ts +++ b/packages/backend/src/server/api/mastodon/entities/account.ts @@ -22,6 +22,7 @@ namespace MastodonEntity { moved: Account | null; fields: Array; bot: boolean | null; + discoverable: boolean; source?: Source; }; diff --git a/packages/backend/src/server/api/mastodon/helpers/user.ts b/packages/backend/src/server/api/mastodon/helpers/user.ts index e09124b40..bc09d97fa 100644 --- a/packages/backend/src/server/api/mastodon/helpers/user.ts +++ b/packages/backend/src/server/api/mastodon/helpers/user.ts @@ -30,15 +30,15 @@ import { genId } from "@/misc/gen-id.js"; import { Muting } from "@/models/entities/muting.js"; import { publishUserEvent } from "@/services/stream.js"; import { UserConverter } from "@/server/api/mastodon/converters/user.js"; -import { convertId, IdType } from "@/misc/convert-id.js"; import acceptFollowRequest from "@/services/following/requests/accept.js"; import { rejectFollowRequest } from "@/services/following/reject.js"; import { IsNull } from "typeorm"; import { VisibilityConverter } from "@/server/api/mastodon/converters/visibility.js"; +import { UserProfile } from "@/models/entities/user-profile.js"; export type AccountCache = { locks: AsyncLock; - accounts: Entity.Account[]; + accounts: MastodonEntity.Account[]; users: User[]; }; @@ -48,6 +48,14 @@ export type LinkPaginationObject = { minId?: string | undefined; } +export type updateCredsData = { + display_name: string; + note: string; + locked: boolean; + bot: boolean; + discoverable: boolean; +} + type RelationshipType = 'followers' | 'following'; export class UserHelpers { @@ -138,6 +146,21 @@ export class UserHelpers { return this.getUserRelationshipTo(target.id, localUser.id); } + public static async updateCredentials(user: ILocalUser, formData: updateCredsData): Promise { + //FIXME: Actually implement this + //FIXME: handle multipart avatar & header image upload + //FIXME: handle field attributes + const obj: any = {}; + + if (formData.display_name) obj.name = formData.display_name; + if (formData.note) obj.description = formData.note; + if (formData.locked) obj.isLocked = formData.locked; + if (formData.bot) obj.isBot = formData.bot; + if (formData.discoverable) obj.isExplorable = formData.discoverable; + + return this.verifyCredentials(user); + } + public static async verifyCredentials(user: ILocalUser): Promise { const acct = UserConverter.encode(user); const profile = UserProfiles.findOneByOrFail({userId: user.id});