diff --git a/docs/api/mastodon.md b/docs/api/mastodon.md index ac71da11..fb539fc6 100644 --- a/docs/api/mastodon.md +++ b/docs/api/mastodon.md @@ -44,4 +44,21 @@ Single Sign-On (SSO) settings for the instance. This object contains two fields: ## `/api/v2/instance` -Contains the same extensions as `/api/v1/instance`, except `banner` which uses the normal Mastodon API attribute. \ No newline at end of file +Contains the same extensions as `/api/v1/instance`, except `banner` which uses the normal Mastodon API attribute. + +## `Account` + +(`/api/v1/accounts/:id`, `/api/v1/accounts/verify_credentials`, ...) + +An extra attribute has been adding to all returned account objects: + +```ts +{ + // ... + roles: LysandRoles[]; +} +``` + +### `roles` + +An array of roles from [Lysand Roles](./roles.md). \ No newline at end of file diff --git a/packages/database-interface/role.ts b/packages/database-interface/role.ts index 99fc9272..1716ebf0 100644 --- a/packages/database-interface/role.ts +++ b/packages/database-interface/role.ts @@ -14,6 +14,10 @@ import { RoleToUsers, Roles } from "~/drizzle/schema"; export class Role { private constructor(private role: InferSelectModel) {} + public static fromRole(role: InferSelectModel) { + return new Role(role); + } + public static async fromId(id: string | null): Promise { if (!id) return null; diff --git a/packages/database-interface/user.ts b/packages/database-interface/user.ts index 0ef18246..1abef889 100644 --- a/packages/database-interface/user.ts +++ b/packages/database-interface/user.ts @@ -43,6 +43,7 @@ import { type Config, config } from "~/packages/config-manager"; import type { Account as APIAccount } from "~/types/mastodon/account"; import type { Mention as APIMention } from "~/types/mastodon/mention"; import type { Note } from "./note"; +import { Role } from "./role"; /** * Gives helpers to fetch users from database in a nice format @@ -602,6 +603,36 @@ export class User { suspended: false, discoverable: undefined, mute_expires_at: undefined, + roles: user.roles + .map((role) => Role.fromRole(role)) + .concat( + Role.fromRole({ + id: "default", + name: "Default", + permissions: config.permissions.default, + priority: 0, + description: "Default role for all users", + visible: false, + icon: null, + }), + ) + .concat( + user.isAdmin + ? [ + Role.fromRole({ + id: "admin", + name: "Admin", + permissions: config.permissions.admin, + priority: 2 ** 31 - 1, + description: + "Default role for all administrators", + visible: false, + icon: null, + }), + ] + : [], + ) + .map((r) => r.toAPI()), group: false, }; } diff --git a/server/api/api/v1/accounts/:id/index.test.ts b/server/api/api/v1/accounts/:id/index.test.ts index a9e964ca..0e3eae6c 100644 --- a/server/api/api/v1/accounts/:id/index.test.ts +++ b/server/api/api/v1/accounts/:id/index.test.ts @@ -83,6 +83,16 @@ describe(meta.route, () => { limited: false, noindex: false, suspended: false, + roles: expect.arrayContaining([ + expect.objectContaining({ + id: "default", + name: "Default", + priority: 0, + description: "Default role for all users", + visible: false, + icon: null, + }), + ]), } satisfies APIAccount); }); }); diff --git a/types/mastodon/account.ts b/types/mastodon/account.ts index 9d796c8a..3e8366b6 100644 --- a/types/mastodon/account.ts +++ b/types/mastodon/account.ts @@ -1,5 +1,6 @@ import type { Emoji } from "./emoji"; import type { Field } from "./field"; +import type { LysandRole } from "./lysand"; import type { Role } from "./role"; import type { Source } from "./source"; @@ -30,5 +31,6 @@ export type Account = { bot: boolean | null; source?: Source; role?: Role; + roles: LysandRole[]; mute_expires_at?: string; }; diff --git a/types/mastodon/lysand.ts b/types/mastodon/lysand.ts new file mode 100644 index 00000000..3a407f36 --- /dev/null +++ b/types/mastodon/lysand.ts @@ -0,0 +1,11 @@ +import type { RolePermissions } from "~/drizzle/schema"; + +export type LysandRole = { + id: string; + name: string; + permissions: RolePermissions[]; + priority: number; + description: string | null; + visible: boolean; + icon: string | null; +};