mirror of
https://github.com/versia-pub/server.git
synced 2025-12-07 08:48:19 +01:00
feat(api): ✨ Add permissions to every route and permission config
This commit is contained in:
parent
19823d8eca
commit
4902f078a8
|
|
@ -312,6 +312,22 @@ description = "A Lysand instance"
|
||||||
# URL to your instance banner
|
# URL to your instance banner
|
||||||
# banner = ""
|
# banner = ""
|
||||||
|
|
||||||
|
[permissions]
|
||||||
|
# Control default permissions for users
|
||||||
|
# Note that an anonymous user having a permission will not allow them
|
||||||
|
# to do things that require authentication (e.g. 'owner:notes' -> posting a note will need
|
||||||
|
# auth, but viewing a note will not)
|
||||||
|
# See docs/api/roles.md in source code for a list of all permissions
|
||||||
|
|
||||||
|
# Defaults to being able to login and manage their own content
|
||||||
|
# anonymous = []
|
||||||
|
|
||||||
|
# Defaults to identical to anonymous
|
||||||
|
# default = []
|
||||||
|
|
||||||
|
# Defaults to being able to manage all instance data, content, and users
|
||||||
|
# admin = []
|
||||||
|
|
||||||
|
|
||||||
[filters]
|
[filters]
|
||||||
# Regex filters for federated and local data
|
# Regex filters for federated and local data
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
Instances,
|
Instances,
|
||||||
Notifications,
|
Notifications,
|
||||||
Relationships,
|
Relationships,
|
||||||
|
type Roles,
|
||||||
Tokens,
|
Tokens,
|
||||||
Users,
|
Users,
|
||||||
} from "~/drizzle/schema";
|
} from "~/drizzle/schema";
|
||||||
|
|
@ -31,6 +32,7 @@ export type UserWithRelations = UserType & {
|
||||||
followerCount: number;
|
followerCount: number;
|
||||||
followingCount: number;
|
followingCount: number;
|
||||||
statusCount: number;
|
statusCount: number;
|
||||||
|
roles: InferSelectModel<typeof Roles>[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const userRelations: {
|
export const userRelations: {
|
||||||
|
|
@ -44,6 +46,11 @@ export const userRelations: {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
roles: {
|
||||||
|
with: {
|
||||||
|
role: true;
|
||||||
|
};
|
||||||
|
};
|
||||||
} = {
|
} = {
|
||||||
instance: true,
|
instance: true,
|
||||||
emojis: {
|
emojis: {
|
||||||
|
|
@ -55,6 +62,11 @@ export const userRelations: {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
roles: {
|
||||||
|
with: {
|
||||||
|
role: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const userExtras = {
|
export const userExtras = {
|
||||||
|
|
@ -242,6 +254,11 @@ export const transformOutputToUserWithRelations = (
|
||||||
emoji?: EmojiWithInstance;
|
emoji?: EmojiWithInstance;
|
||||||
}[];
|
}[];
|
||||||
instance: InferSelectModel<typeof Instances> | null;
|
instance: InferSelectModel<typeof Instances> | null;
|
||||||
|
roles: {
|
||||||
|
userId: string;
|
||||||
|
roleId: string;
|
||||||
|
role?: InferSelectModel<typeof Roles>;
|
||||||
|
}[];
|
||||||
endpoints: unknown;
|
endpoints: unknown;
|
||||||
},
|
},
|
||||||
): UserWithRelations => {
|
): UserWithRelations => {
|
||||||
|
|
@ -266,6 +283,9 @@ export const transformOutputToUserWithRelations = (
|
||||||
(emoji as unknown as Record<string, object>)
|
(emoji as unknown as Record<string, object>)
|
||||||
.emoji as EmojiWithInstance,
|
.emoji as EmojiWithInstance,
|
||||||
),
|
),
|
||||||
|
roles: user.roles
|
||||||
|
.map((role) => role.role)
|
||||||
|
.filter(Boolean) as InferSelectModel<typeof Roles>[],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,27 @@ Roles can be visible or invisible. Invisible roles are not shown to users in the
|
||||||
|
|
||||||
## Permissions
|
## Permissions
|
||||||
|
|
||||||
|
Default permissions for anonymous users, logged-in users and admins can be set in config. These are always applied in addition to the permissions granted by roles. You may set them to empty arrays to exclusively use roles for permissions (make sure your roles are set up correctly).
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// Last updated: 2024-06-07
|
// Last updated: 2024-06-07
|
||||||
// Search for "RolePermissions" in the source code (GitHub search bar) for the most up-to-date version
|
// Search for "RolePermissions" in the source code (GitHub search bar) for the most up-to-date version
|
||||||
enum RolePermissions {
|
export enum RolePermissions {
|
||||||
MANAGE_NOTES = "notes",
|
MANAGE_NOTES = "notes",
|
||||||
MANAGE_OWN_NOTES = "owner:note",
|
MANAGE_OWN_NOTES = "owner:note",
|
||||||
|
VIEW_NOTES = "read:note",
|
||||||
|
VIEW_NOTE_LIKES = "read:note_likes",
|
||||||
|
VIEW_NOTE_BOOSTS = "read:note_boosts",
|
||||||
MANAGE_ACCOUNTS = "accounts",
|
MANAGE_ACCOUNTS = "accounts",
|
||||||
MANAGE_OWN_ACCOUNT = "owner:account",
|
MANAGE_OWN_ACCOUNT = "owner:account",
|
||||||
|
VIEW_ACCOUNT_FOLLOWS = "read:account_follows",
|
||||||
|
MANAGE_LIKES = "likes",
|
||||||
|
MANAGE_OWN_LIKES = "owner:like",
|
||||||
|
MANAGE_BOOSTS = "boosts",
|
||||||
|
MANAGE_OWN_BOOSTS = "owner:boost",
|
||||||
|
VIEW_ACCOUNTS = "read:account",
|
||||||
MANAGE_EMOJIS = "emojis",
|
MANAGE_EMOJIS = "emojis",
|
||||||
|
VIEW_EMOJIS = "read:emoji",
|
||||||
MANAGE_OWN_EMOJIS = "owner:emoji",
|
MANAGE_OWN_EMOJIS = "owner:emoji",
|
||||||
MANAGE_MEDIA = "media",
|
MANAGE_MEDIA = "media",
|
||||||
MANAGE_OWN_MEDIA = "owner:media",
|
MANAGE_OWN_MEDIA = "owner:media",
|
||||||
|
|
@ -45,6 +57,14 @@ enum RolePermissions {
|
||||||
MANAGE_SETTINGS = "settings",
|
MANAGE_SETTINGS = "settings",
|
||||||
MANAGE_OWN_SETTINGS = "owner:settings",
|
MANAGE_OWN_SETTINGS = "owner:settings",
|
||||||
MANAGE_ROLES = "roles",
|
MANAGE_ROLES = "roles",
|
||||||
|
MANAGE_NOTIFICATIONS = "notifications",
|
||||||
|
MANAGE_OWN_NOTIFICATIONS = "owner:notification",
|
||||||
|
MANAGE_FOLLOWS = "follows",
|
||||||
|
MANAGE_OWN_FOLLOWS = "owner:follow",
|
||||||
|
MANAGE_OWN_APPS = "owner:app",
|
||||||
|
SEARCH = "search",
|
||||||
|
VIEW_PUBLIC_TIMELINES = "public_timelines",
|
||||||
|
VIEW_PRIVATE_TIMELINES = "private_timelines",
|
||||||
IGNORE_RATE_LIMITS = "ignore_rate_limits",
|
IGNORE_RATE_LIMITS = "ignore_rate_limits",
|
||||||
IMPERSONATE = "impersonate",
|
IMPERSONATE = "impersonate",
|
||||||
MANAGE_INSTANCE = "instance",
|
MANAGE_INSTANCE = "instance",
|
||||||
|
|
|
||||||
|
|
@ -493,9 +493,19 @@ export const ModTags = pgTable("ModTags", {
|
||||||
export enum RolePermissions {
|
export enum RolePermissions {
|
||||||
MANAGE_NOTES = "notes",
|
MANAGE_NOTES = "notes",
|
||||||
MANAGE_OWN_NOTES = "owner:note",
|
MANAGE_OWN_NOTES = "owner:note",
|
||||||
|
VIEW_NOTES = "read:note",
|
||||||
|
VIEW_NOTE_LIKES = "read:note_likes",
|
||||||
|
VIEW_NOTE_BOOSTS = "read:note_boosts",
|
||||||
MANAGE_ACCOUNTS = "accounts",
|
MANAGE_ACCOUNTS = "accounts",
|
||||||
MANAGE_OWN_ACCOUNT = "owner:account",
|
MANAGE_OWN_ACCOUNT = "owner:account",
|
||||||
|
VIEW_ACCOUNT_FOLLOWS = "read:account_follows",
|
||||||
|
MANAGE_LIKES = "likes",
|
||||||
|
MANAGE_OWN_LIKES = "owner:like",
|
||||||
|
MANAGE_BOOSTS = "boosts",
|
||||||
|
MANAGE_OWN_BOOSTS = "owner:boost",
|
||||||
|
VIEW_ACCOUNTS = "read:account",
|
||||||
MANAGE_EMOJIS = "emojis",
|
MANAGE_EMOJIS = "emojis",
|
||||||
|
VIEW_EMOJIS = "read:emoji",
|
||||||
MANAGE_OWN_EMOJIS = "owner:emoji",
|
MANAGE_OWN_EMOJIS = "owner:emoji",
|
||||||
MANAGE_MEDIA = "media",
|
MANAGE_MEDIA = "media",
|
||||||
MANAGE_OWN_MEDIA = "owner:media",
|
MANAGE_OWN_MEDIA = "owner:media",
|
||||||
|
|
@ -510,6 +520,14 @@ export enum RolePermissions {
|
||||||
MANAGE_SETTINGS = "settings",
|
MANAGE_SETTINGS = "settings",
|
||||||
MANAGE_OWN_SETTINGS = "owner:settings",
|
MANAGE_OWN_SETTINGS = "owner:settings",
|
||||||
MANAGE_ROLES = "roles",
|
MANAGE_ROLES = "roles",
|
||||||
|
MANAGE_NOTIFICATIONS = "notifications",
|
||||||
|
MANAGE_OWN_NOTIFICATIONS = "owner:notification",
|
||||||
|
MANAGE_FOLLOWS = "follows",
|
||||||
|
MANAGE_OWN_FOLLOWS = "owner:follow",
|
||||||
|
MANAGE_OWN_APPS = "owner:app",
|
||||||
|
SEARCH = "search",
|
||||||
|
VIEW_PUBLIC_TIMELINES = "public_timelines",
|
||||||
|
VIEW_PRIVATE_TIMELINES = "private_timelines",
|
||||||
IGNORE_RATE_LIMITS = "ignore_rate_limits",
|
IGNORE_RATE_LIMITS = "ignore_rate_limits",
|
||||||
IMPERSONATE = "impersonate",
|
IMPERSONATE = "impersonate",
|
||||||
MANAGE_INSTANCE = "instance",
|
MANAGE_INSTANCE = "instance",
|
||||||
|
|
@ -521,14 +539,28 @@ export enum RolePermissions {
|
||||||
|
|
||||||
export const DEFAULT_ROLES = [
|
export const DEFAULT_ROLES = [
|
||||||
RolePermissions.MANAGE_OWN_NOTES,
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTE_LIKES,
|
||||||
|
RolePermissions.VIEW_NOTE_BOOSTS,
|
||||||
RolePermissions.MANAGE_OWN_ACCOUNT,
|
RolePermissions.MANAGE_OWN_ACCOUNT,
|
||||||
|
RolePermissions.VIEW_ACCOUNT_FOLLOWS,
|
||||||
|
RolePermissions.MANAGE_OWN_LIKES,
|
||||||
|
RolePermissions.MANAGE_OWN_BOOSTS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
RolePermissions.MANAGE_OWN_EMOJIS,
|
RolePermissions.MANAGE_OWN_EMOJIS,
|
||||||
|
RolePermissions.VIEW_EMOJIS,
|
||||||
RolePermissions.MANAGE_OWN_MEDIA,
|
RolePermissions.MANAGE_OWN_MEDIA,
|
||||||
RolePermissions.MANAGE_OWN_BLOCKS,
|
RolePermissions.MANAGE_OWN_BLOCKS,
|
||||||
RolePermissions.MANAGE_OWN_FILTERS,
|
RolePermissions.MANAGE_OWN_FILTERS,
|
||||||
RolePermissions.MANAGE_OWN_MUTES,
|
RolePermissions.MANAGE_OWN_MUTES,
|
||||||
RolePermissions.MANAGE_OWN_REPORTS,
|
RolePermissions.MANAGE_OWN_REPORTS,
|
||||||
RolePermissions.MANAGE_OWN_SETTINGS,
|
RolePermissions.MANAGE_OWN_SETTINGS,
|
||||||
|
RolePermissions.MANAGE_OWN_NOTIFICATIONS,
|
||||||
|
RolePermissions.MANAGE_OWN_FOLLOWS,
|
||||||
|
RolePermissions.MANAGE_OWN_APPS,
|
||||||
|
RolePermissions.SEARCH,
|
||||||
|
RolePermissions.VIEW_PUBLIC_TIMELINES,
|
||||||
|
RolePermissions.VIEW_PRIVATE_TIMELINES,
|
||||||
RolePermissions.OAUTH,
|
RolePermissions.OAUTH,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -536,6 +568,8 @@ export const ADMIN_ROLES = [
|
||||||
...DEFAULT_ROLES,
|
...DEFAULT_ROLES,
|
||||||
RolePermissions.MANAGE_NOTES,
|
RolePermissions.MANAGE_NOTES,
|
||||||
RolePermissions.MANAGE_ACCOUNTS,
|
RolePermissions.MANAGE_ACCOUNTS,
|
||||||
|
RolePermissions.MANAGE_LIKES,
|
||||||
|
RolePermissions.MANAGE_BOOSTS,
|
||||||
RolePermissions.MANAGE_EMOJIS,
|
RolePermissions.MANAGE_EMOJIS,
|
||||||
RolePermissions.MANAGE_MEDIA,
|
RolePermissions.MANAGE_MEDIA,
|
||||||
RolePermissions.MANAGE_BLOCKS,
|
RolePermissions.MANAGE_BLOCKS,
|
||||||
|
|
@ -544,6 +578,8 @@ export const ADMIN_ROLES = [
|
||||||
RolePermissions.MANAGE_REPORTS,
|
RolePermissions.MANAGE_REPORTS,
|
||||||
RolePermissions.MANAGE_SETTINGS,
|
RolePermissions.MANAGE_SETTINGS,
|
||||||
RolePermissions.MANAGE_ROLES,
|
RolePermissions.MANAGE_ROLES,
|
||||||
|
RolePermissions.MANAGE_NOTIFICATIONS,
|
||||||
|
RolePermissions.MANAGE_FOLLOWS,
|
||||||
RolePermissions.IMPERSONATE,
|
RolePermissions.IMPERSONATE,
|
||||||
RolePermissions.IGNORE_RATE_LIMITS,
|
RolePermissions.IGNORE_RATE_LIMITS,
|
||||||
RolePermissions.MANAGE_INSTANCE,
|
RolePermissions.MANAGE_INSTANCE,
|
||||||
|
|
@ -564,6 +600,10 @@ export const Roles = pgTable("Roles", {
|
||||||
icon: text("icon"),
|
icon: text("icon"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const RolesRelations = relations(Roles, ({ many }) => ({
|
||||||
|
users: many(RoleToUsers),
|
||||||
|
}));
|
||||||
|
|
||||||
export const RoleToUsers = pgTable("RoleToUsers", {
|
export const RoleToUsers = pgTable("RoleToUsers", {
|
||||||
roleId: uuid("roleId")
|
roleId: uuid("roleId")
|
||||||
.notNull()
|
.notNull()
|
||||||
|
|
@ -733,6 +773,7 @@ export const UsersRelations = relations(Users, ({ many, one }) => ({
|
||||||
references: [Instances.id],
|
references: [Instances.id],
|
||||||
}),
|
}),
|
||||||
mentionedIn: many(NoteToMentions),
|
mentionedIn: many(NoteToMentions),
|
||||||
|
roles: many(RoleToUsers),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const RelationshipsRelations = relations(Relationships, ({ one }) => ({
|
export const RelationshipsRelations = relations(Relationships, ({ one }) => ({
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { types as mimeTypes } from "mime-types";
|
import { types as mimeTypes } from "mime-types";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { ADMIN_ROLES, DEFAULT_ROLES, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export enum MediaBackendType {
|
export enum MediaBackendType {
|
||||||
LOCAL = "local",
|
LOCAL = "local",
|
||||||
|
|
@ -480,6 +481,21 @@ export const configValidator = z.object({
|
||||||
logo: undefined,
|
logo: undefined,
|
||||||
banner: undefined,
|
banner: undefined,
|
||||||
}),
|
}),
|
||||||
|
permissions: z
|
||||||
|
.object({
|
||||||
|
anonymous: z
|
||||||
|
.array(z.nativeEnum(RolePermissions))
|
||||||
|
.default(DEFAULT_ROLES),
|
||||||
|
default: z
|
||||||
|
.array(z.nativeEnum(RolePermissions))
|
||||||
|
.default(DEFAULT_ROLES),
|
||||||
|
admin: z.array(z.nativeEnum(RolePermissions)).default(ADMIN_ROLES),
|
||||||
|
})
|
||||||
|
.default({
|
||||||
|
anonymous: DEFAULT_ROLES,
|
||||||
|
default: DEFAULT_ROLES,
|
||||||
|
admin: ADMIN_ROLES,
|
||||||
|
}),
|
||||||
filters: z.object({
|
filters: z.object({
|
||||||
note_content: z.array(z.string()).default([]),
|
note_content: z.array(z.string()).default([]),
|
||||||
emoji: z.array(z.string()).default([]),
|
emoji: z.array(z.string()).default([]),
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export class Role {
|
||||||
orderBy: SQL<unknown> | undefined = desc(Roles.id),
|
orderBy: SQL<unknown> | undefined = desc(Roles.id),
|
||||||
limit?: number,
|
limit?: number,
|
||||||
offset?: number,
|
offset?: number,
|
||||||
extra?: Parameters<typeof db.query.Users.findMany>[0],
|
extra?: Parameters<typeof db.query.Roles.findMany>[0],
|
||||||
) {
|
) {
|
||||||
const found = await db.query.Roles.findMany({
|
const found = await db.query.Roles.findMany({
|
||||||
where: sql,
|
where: sql,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import {
|
||||||
EmojiToUser,
|
EmojiToUser,
|
||||||
NoteToMentions,
|
NoteToMentions,
|
||||||
Notes,
|
Notes,
|
||||||
|
type RolePermissions,
|
||||||
UserToPinnedNotes,
|
UserToPinnedNotes,
|
||||||
Users,
|
Users,
|
||||||
} from "~/drizzle/schema";
|
} from "~/drizzle/schema";
|
||||||
|
|
@ -117,6 +118,25 @@ export class User {
|
||||||
return uri || new URL(`/users/${id}`, baseUrl).toString();
|
return uri || new URL(`/users/${id}`, baseUrl).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public hasPermission(permission: RolePermissions) {
|
||||||
|
return this.getAllPermissions().includes(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAllPermissions() {
|
||||||
|
return (
|
||||||
|
this.user.roles
|
||||||
|
.flatMap((role) => role.permissions)
|
||||||
|
// Add default permissions
|
||||||
|
.concat(config.permissions.default)
|
||||||
|
// If admin, add admin permissions
|
||||||
|
.concat(this.user.isAdmin ? config.permissions.admin : [])
|
||||||
|
.reduce((acc, permission) => {
|
||||||
|
if (!acc.includes(permission)) acc.push(permission);
|
||||||
|
return acc;
|
||||||
|
}, [] as RolePermissions[])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static async getCount() {
|
static async getCount() {
|
||||||
return (
|
return (
|
||||||
await db
|
await db
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:blocks"],
|
oauthPermissions: ["write:blocks"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_BLOCKS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +40,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import {
|
||||||
followRequestUser,
|
followRequestUser,
|
||||||
getRelationshipToOtherUser,
|
getRelationshipToOtherUser,
|
||||||
} from "~/database/entities/User";
|
} from "~/database/entities/User";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -22,6 +23,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:follows"],
|
oauthPermissions: ["write:follows"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_FOLLOWS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -46,7 +53,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("json", schemas.json, handleZodError),
|
zValidator("json", schemas.json, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
|
|
@ -19,6 +19,12 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
oauthPermissions: ["read:accounts"],
|
oauthPermissions: ["read:accounts"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.VIEW_ACCOUNT_FOLLOWS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -39,7 +45,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { max_id, since_id, min_id, limit } =
|
const { max_id, since_id, min_id, limit } =
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
|
|
@ -19,6 +19,12 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
oauthPermissions: ["read:accounts"],
|
oauthPermissions: ["read:accounts"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.VIEW_ACCOUNT_FOLLOWS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -39,7 +45,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { max_id, since_id, min_id } = context.req.valid("query");
|
const { max_id, since_id, min_id } = context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { errorResponse, jsonResponse } from "@/response";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -16,6 +17,9 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
oauthPermissions: [],
|
oauthPermissions: [],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.VIEW_ACCOUNTS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -29,7 +33,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:mutes"],
|
oauthPermissions: ["write:mutes"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_MUTES,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -44,7 +50,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("json", schemas.json, handleZodError),
|
zValidator("json", schemas.json, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:accounts"],
|
oauthPermissions: ["write:accounts"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_ACCOUNT,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -38,7 +44,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("json", schemas.json, handleZodError),
|
zValidator("json", schemas.json, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:accounts"],
|
oauthPermissions: ["write:accounts"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_ACCOUNT,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +40,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:follows"],
|
oauthPermissions: ["write:follows"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_FOLLOWS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +40,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, eq, gt, gte, isNull, lt, sql } from "drizzle-orm";
|
import { and, eq, gt, gte, isNull, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Notes } from "~/drizzle/schema";
|
import { Notes, RolePermissions } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
|
|
@ -19,6 +19,9 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
oauthPermissions: ["read:statuses"],
|
oauthPermissions: ["read:statuses"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.VIEW_NOTES, RolePermissions.VIEW_ACCOUNTS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -59,7 +62,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:blocks"],
|
oauthPermissions: ["write:blocks"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_BLOCKS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +40,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:follows"],
|
oauthPermissions: ["write:follows"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_FOLLOWS,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +40,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:mutes"],
|
oauthPermissions: ["write:mutes"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_MUTES,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +40,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { z } from "zod";
|
||||||
import { relationshipToAPI } from "~/database/entities/Relationship";
|
import { relationshipToAPI } from "~/database/entities/Relationship";
|
||||||
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
import { getRelationshipToOtherUser } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +21,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:accounts"],
|
oauthPermissions: ["write:accounts"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_ACCOUNT,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +40,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { inArray } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -19,6 +19,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["read:follows"],
|
oauthPermissions: ["read:follows"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_FOLLOWS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -33,7 +36,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
qsQuery(),
|
qsQuery(),
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
const { id: ids } = context.req.valid("query");
|
const { id: ids } = context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const form = context.req.valid("form");
|
const form = context.req.valid("form");
|
||||||
const { username, email, password, agreement, locale } =
|
const { username, email, password, agreement, locale } =
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import {
|
||||||
} from "magic-regexp";
|
} from "magic-regexp";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { resolveWebFinger } from "~/database/entities/User";
|
import { resolveWebFinger } from "~/database/entities/User";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
import { LogLevel } from "~/packages/log-manager";
|
import { LogLevel } from "~/packages/log-manager";
|
||||||
|
|
||||||
|
|
@ -32,6 +32,9 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
oauthPermissions: [],
|
oauthPermissions: [],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.SEARCH],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -45,7 +48,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { acct } = context.req.valid("query");
|
const { acct } = context.req.valid("query");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
relationshipToAPI,
|
relationshipToAPI,
|
||||||
} from "~/database/entities/Relationship";
|
} from "~/database/entities/Relationship";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -21,6 +22,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["read:follows"],
|
oauthPermissions: ["read:follows"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_FOLLOWS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -35,7 +39,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
qsQuery(),
|
qsQuery(),
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
const { id } = context.req.valid("query");
|
const { id } = context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import stringComparison from "string-comparison";
|
import stringComparison from "string-comparison";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { resolveWebFinger } from "~/database/entities/User";
|
import { resolveWebFinger } from "~/database/entities/User";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -31,6 +31,9 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
oauthPermissions: ["read:accounts"],
|
oauthPermissions: ["read:accounts"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.SEARCH, RolePermissions.VIEW_ACCOUNTS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -72,7 +75,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { q, limit, offset, resolve, following } =
|
const { q, limit, offset, resolve, following } =
|
||||||
context.req.valid("query");
|
context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { getUrl } from "~/database/entities/Attachment";
|
||||||
import { type EmojiWithInstance, parseEmojis } from "~/database/entities/Emoji";
|
import { type EmojiWithInstance, parseEmojis } from "~/database/entities/Emoji";
|
||||||
import { contentToHtml } from "~/database/entities/Status";
|
import { contentToHtml } from "~/database/entities/Status";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { EmojiToUser } from "~/drizzle/schema";
|
import { EmojiToUser, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -28,6 +28,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:accounts"],
|
oauthPermissions: ["write:accounts"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_ACCOUNT],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -98,7 +101,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
qs(),
|
qs(),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
const {
|
const {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
// TODO: Add checks for disabled/unverified accounts
|
// TODO: Add checks for disabled/unverified accounts
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Applications } from "~/drizzle/schema";
|
import { Applications, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["POST"],
|
allowedMethods: ["POST"],
|
||||||
|
|
@ -17,6 +17,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_APPS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { applyConfig, auth } from "@/api";
|
||||||
import { errorResponse, jsonResponse } from "@/response";
|
import { errorResponse, jsonResponse } from "@/response";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { getFromToken } from "~/database/entities/Application";
|
import { getFromToken } from "~/database/entities/Application";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET"],
|
allowedMethods: ["GET"],
|
||||||
|
|
@ -13,13 +14,16 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_APPS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (app: Hono) =>
|
export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user, token } = context.req.valid("header");
|
const { user, token } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -18,6 +18,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["read:blocks"],
|
oauthPermissions: ["read:blocks"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_BLOCKS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +37,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { max_id, since_id, min_id, limit } =
|
const { max_id, since_id, min_id, limit } =
|
||||||
context.req.valid("query");
|
context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { jsonResponse } from "@/response";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { emojiToAPI } from "~/database/entities/Emoji";
|
import { emojiToAPI } from "~/database/entities/Emoji";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET"],
|
allowedMethods: ["GET"],
|
||||||
|
|
@ -14,13 +15,16 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.VIEW_EMOJIS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (app: Hono) =>
|
export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { z } from "zod";
|
||||||
import { getUrl } from "~/database/entities/Attachment";
|
import { getUrl } from "~/database/entities/Attachment";
|
||||||
import { emojiToAPI } from "~/database/entities/Emoji";
|
import { emojiToAPI } from "~/database/entities/Emoji";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Emojis } from "~/drizzle/schema";
|
import { Emojis, RolePermissions } from "~/drizzle/schema";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
import { MediaBackend } from "~/packages/media-manager";
|
import { MediaBackend } from "~/packages/media-manager";
|
||||||
|
|
||||||
|
|
@ -28,6 +28,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_EMOJIS,
|
||||||
|
RolePermissions.VIEW_EMOJIS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -71,7 +77,7 @@ export default (app: Hono) =>
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
@ -91,12 +97,12 @@ export default (app: Hono) =>
|
||||||
|
|
||||||
// Check if user is admin
|
// Check if user is admin
|
||||||
if (
|
if (
|
||||||
!user.getUser().isAdmin &&
|
!user.hasPermission(RolePermissions.MANAGE_EMOJIS) &&
|
||||||
emoji.ownerId !== user.getUser().id
|
emoji.ownerId !== user.getUser().id
|
||||||
) {
|
) {
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
error: "You do not have permission to modify this emoji, as it is either global or not owned by you",
|
error: `You cannot modify this emoji, as it is either global, not owned by you, or you do not have the '${RolePermissions.MANAGE_EMOJIS}' permission to manage global emojis`,
|
||||||
},
|
},
|
||||||
403,
|
403,
|
||||||
);
|
);
|
||||||
|
|
@ -139,9 +145,12 @@ export default (app: Hono) =>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.getUser().isAdmin && form.global) {
|
if (
|
||||||
|
!user.hasPermission(RolePermissions.MANAGE_EMOJIS) &&
|
||||||
|
form.global
|
||||||
|
) {
|
||||||
return errorResponse(
|
return errorResponse(
|
||||||
"Only administrators can make an emoji global or not",
|
`Only users with the '${RolePermissions.MANAGE_EMOJIS}' permission can make an emoji global or not`,
|
||||||
401,
|
401,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { z } from "zod";
|
||||||
import { getUrl } from "~/database/entities/Attachment";
|
import { getUrl } from "~/database/entities/Attachment";
|
||||||
import { emojiToAPI } from "~/database/entities/Emoji";
|
import { emojiToAPI } from "~/database/entities/Emoji";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Emojis } from "~/drizzle/schema";
|
import { Emojis, RolePermissions } from "~/drizzle/schema";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
import { MediaBackend } from "~/packages/media-manager";
|
import { MediaBackend } from "~/packages/media-manager";
|
||||||
|
|
||||||
|
|
@ -27,6 +27,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_EMOJIS,
|
||||||
|
RolePermissions.VIEW_EMOJIS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -63,7 +69,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { shortcode, element, alt, global, category } =
|
const { shortcode, element, alt, global, category } =
|
||||||
context.req.valid("form");
|
context.req.valid("form");
|
||||||
|
|
@ -73,9 +79,9 @@ export default (app: Hono) =>
|
||||||
return errorResponse("Unauthorized", 401);
|
return errorResponse("Unauthorized", 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.getUser().isAdmin && global) {
|
if (!user.hasPermission(RolePermissions.MANAGE_EMOJIS) && global) {
|
||||||
return errorResponse(
|
return errorResponse(
|
||||||
"Only administrators can upload global emojis",
|
`Only users with the '${RolePermissions.MANAGE_EMOJIS}' permission can upload global emojis`,
|
||||||
401,
|
401,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Notes } from "~/drizzle/schema";
|
import { Notes, RolePermissions } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -17,6 +17,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_LIKES],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -33,7 +36,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { max_id, since_id, min_id, limit } =
|
const { max_id, since_id, min_id, limit } =
|
||||||
context.req.valid("query");
|
context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
sendFollowAccept,
|
sendFollowAccept,
|
||||||
} from "~/database/entities/User";
|
} from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -26,6 +26,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_FOLLOWS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -39,7 +42,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
sendFollowReject,
|
sendFollowReject,
|
||||||
} from "~/database/entities/User";
|
} from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Relationships } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -26,6 +26,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_FOLLOWS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -39,7 +42,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -17,6 +17,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_FOLLOWS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -33,7 +36,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { max_id, since_id, min_id, limit } =
|
const { max_id, since_id, min_id, limit } =
|
||||||
context.req.valid("query");
|
context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -19,30 +19,41 @@ export const meta = applyConfig({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (app: Hono) =>
|
export default (app: Hono) =>
|
||||||
app.on(meta.allowedMethods, meta.route, auth(meta.auth), async () => {
|
app.on(
|
||||||
let extended_description = (await getMarkdownRenderer()).render(
|
meta.allowedMethods,
|
||||||
"This is a [Lysand](https://lysand.org) server with the default extended description.",
|
meta.route,
|
||||||
);
|
auth(meta.auth, meta.permissions),
|
||||||
let lastModified = new Date(2024, 0, 0);
|
async () => {
|
||||||
|
let extended_description = (await getMarkdownRenderer()).render(
|
||||||
|
"This is a [Lysand](https://lysand.org) server with the default extended description.",
|
||||||
|
);
|
||||||
|
let lastModified = new Date(2024, 0, 0);
|
||||||
|
|
||||||
const extended_description_file = Bun.file(
|
const extended_description_file = Bun.file(
|
||||||
config.instance.extended_description_path || "",
|
config.instance.extended_description_path || "",
|
||||||
);
|
);
|
||||||
|
|
||||||
if (await extended_description_file.exists()) {
|
if (await extended_description_file.exists()) {
|
||||||
extended_description =
|
extended_description =
|
||||||
(await getMarkdownRenderer()).render(
|
(await getMarkdownRenderer()).render(
|
||||||
(await extended_description_file.text().catch(async (e) => {
|
(await extended_description_file
|
||||||
await dualLogger.logError(LogLevel.ERROR, "Routes", e);
|
.text()
|
||||||
return "";
|
.catch(async (e) => {
|
||||||
})) ||
|
await dualLogger.logError(
|
||||||
"This is a [Lysand](https://lysand.org) server with the default extended description.",
|
LogLevel.ERROR,
|
||||||
) || "";
|
"Routes",
|
||||||
lastModified = new Date(extended_description_file.lastModified);
|
e,
|
||||||
}
|
);
|
||||||
|
return "";
|
||||||
|
})) ||
|
||||||
|
"This is a [Lysand](https://lysand.org) server with the default extended description.",
|
||||||
|
) || "";
|
||||||
|
lastModified = new Date(extended_description_file.lastModified);
|
||||||
|
}
|
||||||
|
|
||||||
return jsonResponse({
|
return jsonResponse({
|
||||||
updated_at: lastModified.toISOString(),
|
updated_at: lastModified.toISOString(),
|
||||||
content: extended_description,
|
content: extended_description,
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,86 +23,91 @@ export const meta = applyConfig({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (app: Hono) =>
|
export default (app: Hono) =>
|
||||||
app.on(meta.allowedMethods, meta.route, auth(meta.auth), async () => {
|
app.on(
|
||||||
// Get software version from package.json
|
meta.allowedMethods,
|
||||||
const version = manifest.version;
|
meta.route,
|
||||||
|
auth(meta.auth, meta.permissions),
|
||||||
|
async () => {
|
||||||
|
// Get software version from package.json
|
||||||
|
const version = manifest.version;
|
||||||
|
|
||||||
const statusCount = await Note.getCount();
|
const statusCount = await Note.getCount();
|
||||||
|
|
||||||
const userCount = await User.getCount();
|
const userCount = await User.getCount();
|
||||||
|
|
||||||
const contactAccount = await User.fromSql(
|
const contactAccount = await User.fromSql(
|
||||||
and(isNull(Users.instanceId), eq(Users.isAdmin, true)),
|
and(isNull(Users.instanceId), eq(Users.isAdmin, true)),
|
||||||
);
|
);
|
||||||
|
|
||||||
const knownDomainsCount = (
|
const knownDomainsCount = (
|
||||||
await db
|
await db
|
||||||
.select({
|
.select({
|
||||||
count: count(),
|
count: count(),
|
||||||
})
|
})
|
||||||
.from(Instances)
|
.from(Instances)
|
||||||
)[0].count;
|
)[0].count;
|
||||||
|
|
||||||
// TODO: fill in more values
|
// TODO: fill in more values
|
||||||
return jsonResponse({
|
return jsonResponse({
|
||||||
approval_required: false,
|
approval_required: false,
|
||||||
configuration: {
|
configuration: {
|
||||||
polls: {
|
polls: {
|
||||||
max_characters_per_option:
|
max_characters_per_option:
|
||||||
config.validation.max_poll_option_size,
|
config.validation.max_poll_option_size,
|
||||||
max_expiration: config.validation.max_poll_duration,
|
max_expiration: config.validation.max_poll_duration,
|
||||||
max_options: config.validation.max_poll_options,
|
max_options: config.validation.max_poll_options,
|
||||||
min_expiration: config.validation.min_poll_duration,
|
min_expiration: config.validation.min_poll_duration,
|
||||||
|
},
|
||||||
|
statuses: {
|
||||||
|
characters_reserved_per_url: 0,
|
||||||
|
max_characters: config.validation.max_note_size,
|
||||||
|
max_media_attachments:
|
||||||
|
config.validation.max_media_attachments,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
statuses: {
|
description: config.instance.description,
|
||||||
characters_reserved_per_url: 0,
|
email: "",
|
||||||
max_characters: config.validation.max_note_size,
|
invites_enabled: false,
|
||||||
max_media_attachments:
|
registrations: config.signups.registration,
|
||||||
config.validation.max_media_attachments,
|
languages: ["en"],
|
||||||
},
|
rules: config.signups.rules.map((r, index) => ({
|
||||||
},
|
id: String(index),
|
||||||
description: config.instance.description,
|
text: r,
|
||||||
email: "",
|
|
||||||
invites_enabled: false,
|
|
||||||
registrations: config.signups.registration,
|
|
||||||
languages: ["en"],
|
|
||||||
rules: config.signups.rules.map((r, index) => ({
|
|
||||||
id: String(index),
|
|
||||||
text: r,
|
|
||||||
})),
|
|
||||||
stats: {
|
|
||||||
domain_count: knownDomainsCount,
|
|
||||||
status_count: statusCount,
|
|
||||||
user_count: userCount,
|
|
||||||
},
|
|
||||||
thumbnail: proxyUrl(config.instance.logo),
|
|
||||||
banner: proxyUrl(config.instance.banner),
|
|
||||||
title: config.instance.name,
|
|
||||||
uri: config.http.base_url,
|
|
||||||
urls: {
|
|
||||||
streaming_api: "",
|
|
||||||
},
|
|
||||||
version: "4.3.0-alpha.3+glitch",
|
|
||||||
lysand_version: version,
|
|
||||||
sso: {
|
|
||||||
forced: false,
|
|
||||||
providers: config.oidc.providers.map((p) => ({
|
|
||||||
name: p.name,
|
|
||||||
icon: p.icon,
|
|
||||||
id: p.id,
|
|
||||||
})),
|
})),
|
||||||
},
|
stats: {
|
||||||
contact_account: contactAccount?.toAPI() || undefined,
|
domain_count: knownDomainsCount,
|
||||||
} satisfies APIInstance & {
|
status_count: statusCount,
|
||||||
banner: string | null;
|
user_count: userCount,
|
||||||
lysand_version: string;
|
},
|
||||||
sso: {
|
thumbnail: proxyUrl(config.instance.logo),
|
||||||
forced: boolean;
|
banner: proxyUrl(config.instance.banner),
|
||||||
providers: {
|
title: config.instance.name,
|
||||||
id: string;
|
uri: config.http.base_url,
|
||||||
name: string;
|
urls: {
|
||||||
icon?: string;
|
streaming_api: "",
|
||||||
}[];
|
},
|
||||||
};
|
version: "4.3.0-alpha.3+glitch",
|
||||||
});
|
lysand_version: version,
|
||||||
});
|
sso: {
|
||||||
|
forced: false,
|
||||||
|
providers: config.oidc.providers.map((p) => ({
|
||||||
|
name: p.name,
|
||||||
|
icon: p.icon,
|
||||||
|
id: p.id,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
contact_account: contactAccount?.toAPI() || undefined,
|
||||||
|
} satisfies APIInstance & {
|
||||||
|
banner: string | null;
|
||||||
|
lysand_version: string;
|
||||||
|
sso: {
|
||||||
|
forced: boolean;
|
||||||
|
providers: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
icon?: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
config.signups.rules.map((rule, index) => ({
|
config.signups.rules.map((rule, index) => ({
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { and, count, eq } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Markers } from "~/drizzle/schema";
|
import { Markers, RolePermissions } from "~/drizzle/schema";
|
||||||
import type { Marker as APIMarker } from "~/types/mastodon/marker";
|
import type { Marker as APIMarker } from "~/types/mastodon/marker";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -19,6 +19,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["read:blocks"],
|
oauthPermissions: ["read:blocks"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_ACCOUNT],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -38,7 +41,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { "timeline[]": timelines } = context.req.valid("query");
|
const { "timeline[]": timelines } = context.req.valid("query");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { LocalMediaBackend, S3MediaBackend } from "media-manager";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { attachmentToAPI, getUrl } from "~/database/entities/Attachment";
|
import { attachmentToAPI, getUrl } from "~/database/entities/Attachment";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Attachments } from "~/drizzle/schema";
|
import { Attachments, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET", "PUT"],
|
allowedMethods: ["GET", "PUT"],
|
||||||
|
|
@ -23,6 +23,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:media"],
|
oauthPermissions: ["write:media"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_MEDIA],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -45,7 +48,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import sharp from "sharp";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { attachmentToAPI, getUrl } from "~/database/entities/Attachment";
|
import { attachmentToAPI, getUrl } from "~/database/entities/Attachment";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Attachments } from "~/drizzle/schema";
|
import { Attachments, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["POST"],
|
allowedMethods: ["POST"],
|
||||||
|
|
@ -24,6 +24,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:media"],
|
oauthPermissions: ["write:media"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_MEDIA],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -43,7 +46,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { file, thumbnail, description } = context.req.valid("form");
|
const { file, thumbnail, description } = context.req.valid("form");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -18,6 +18,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["read:mutes"],
|
oauthPermissions: ["read:mutes"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_MUTES],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -34,7 +37,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { max_id, since_id, limit, min_id } =
|
const { max_id, since_id, limit, min_id } =
|
||||||
context.req.valid("query");
|
context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { eq } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Notifications } from "~/drizzle/schema";
|
import { Notifications, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["POST"],
|
allowedMethods: ["POST"],
|
||||||
|
|
@ -18,6 +18,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:notifications"],
|
oauthPermissions: ["write:notifications"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_NOTIFICATIONS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -31,7 +34,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { findManyNotifications } from "~/database/entities/Notification";
|
import { findManyNotifications } from "~/database/entities/Notification";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET"],
|
allowedMethods: ["GET"],
|
||||||
|
|
@ -16,6 +17,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["read:notifications"],
|
oauthPermissions: ["read:notifications"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_NOTIFICATIONS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -29,7 +33,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { errorResponse, jsonResponse } from "@/response";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Notifications } from "~/drizzle/schema";
|
import { Notifications, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["POST"],
|
allowedMethods: ["POST"],
|
||||||
|
|
@ -16,13 +16,16 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:notifications"],
|
oauthPermissions: ["write:notifications"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_NOTIFICATIONS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (app: Hono) =>
|
export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
if (!user) return errorResponse("Unauthorized", 401);
|
if (!user) return errorResponse("Unauthorized", 401);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { and, eq, inArray } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Notifications } from "~/drizzle/schema";
|
import { Notifications, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["DELETE"],
|
allowedMethods: ["DELETE"],
|
||||||
|
|
@ -18,6 +18,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:notifications"],
|
oauthPermissions: ["write:notifications"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_NOTIFICATIONS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -31,7 +34,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import {
|
||||||
notificationToAPI,
|
notificationToAPI,
|
||||||
} from "~/database/entities/Notification";
|
} from "~/database/entities/Notification";
|
||||||
import type { NotificationWithRelations } from "~/database/entities/Notification";
|
import type { NotificationWithRelations } from "~/database/entities/Notification";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET"],
|
allowedMethods: ["GET"],
|
||||||
|
|
@ -22,6 +23,12 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["read:notifications"],
|
oauthPermissions: ["read:notifications"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTIFICATIONS,
|
||||||
|
RolePermissions.VIEW_PRIVATE_TIMELINES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -89,7 +96,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
if (!user) return errorResponse("Unauthorized", 401);
|
if (!user) return errorResponse("Unauthorized", 401);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { applyConfig, auth } from "@/api";
|
import { applyConfig, auth } from "@/api";
|
||||||
import { errorResponse, jsonResponse } from "@/response";
|
import { errorResponse, jsonResponse } from "@/response";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["DELETE"],
|
allowedMethods: ["DELETE"],
|
||||||
|
|
@ -12,13 +13,16 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_ACCOUNT],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (app: Hono) =>
|
export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { applyConfig, auth } from "@/api";
|
import { applyConfig, auth } from "@/api";
|
||||||
import { errorResponse, jsonResponse } from "@/response";
|
import { errorResponse, jsonResponse } from "@/response";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["DELETE"],
|
allowedMethods: ["DELETE"],
|
||||||
|
|
@ -12,13 +13,16 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_ACCOUNT],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (app: Hono) =>
|
export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ describe(meta.route, () => {
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
const output = await response.json();
|
const output = await response.json();
|
||||||
expect(output).toMatchObject({
|
expect(output).toMatchObject({
|
||||||
error: "You do not have permission to manage roles",
|
error: "You do not have the required permissions to access this route. Missing: roles",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,13 @@ export const meta = applyConfig({
|
||||||
max: 20,
|
max: 20,
|
||||||
},
|
},
|
||||||
route: "/api/v1/roles/:id",
|
route: "/api/v1/roles/:id",
|
||||||
|
permissions: {
|
||||||
|
required: [],
|
||||||
|
methodOverrides: {
|
||||||
|
POST: [RolePermissions.MANAGE_ROLES],
|
||||||
|
DELETE: [RolePermissions.MANAGE_ROLES],
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -29,7 +36,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
|
|
@ -51,22 +58,6 @@ export default (app: Hono) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
case "POST": {
|
case "POST": {
|
||||||
// Check if user has MANAGE_ROLES permission
|
|
||||||
if (
|
|
||||||
!userRoles.some((r) =>
|
|
||||||
r
|
|
||||||
.getRole()
|
|
||||||
.permissions.includes(
|
|
||||||
RolePermissions.MANAGE_ROLES,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return errorResponse(
|
|
||||||
"You do not have permission to manage roles",
|
|
||||||
403,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const userHighestRole = userRoles.reduce((prev, current) =>
|
const userHighestRole = userRoles.reduce((prev, current) =>
|
||||||
prev.getRole().priority > current.getRole().priority
|
prev.getRole().priority > current.getRole().priority
|
||||||
? prev
|
? prev
|
||||||
|
|
@ -94,22 +85,6 @@ export default (app: Hono) =>
|
||||||
return response(null, 204);
|
return response(null, 204);
|
||||||
}
|
}
|
||||||
case "DELETE": {
|
case "DELETE": {
|
||||||
// Check if user has MANAGE_ROLES permission
|
|
||||||
if (
|
|
||||||
!userRoles.some((r) =>
|
|
||||||
r
|
|
||||||
.getRole()
|
|
||||||
.permissions.includes(
|
|
||||||
RolePermissions.MANAGE_ROLES,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return errorResponse(
|
|
||||||
"You do not have permission to manage roles",
|
|
||||||
403,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const userHighestRole = userRoles.reduce((prev, current) =>
|
const userHighestRole = userRoles.reduce((prev, current) =>
|
||||||
prev.getRole().priority > current.getRole().priority
|
prev.getRole().priority > current.getRole().priority
|
||||||
? prev
|
? prev
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export default (app: Hono) =>
|
||||||
app.on(
|
app.on(
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { eq } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { OpenIdAccounts } from "~/drizzle/schema";
|
import { OpenIdAccounts, RolePermissions } from "~/drizzle/schema";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -18,6 +18,9 @@ export const meta = applyConfig({
|
||||||
max: 20,
|
max: 20,
|
||||||
},
|
},
|
||||||
route: "/api/v1/sso/:id",
|
route: "/api/v1/sso/:id",
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.OAUTH],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -36,7 +39,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id: issuerId } = context.req.valid("param");
|
const { id: issuerId } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,11 @@ import {
|
||||||
} from "oauth4webapi";
|
} from "oauth4webapi";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Applications, OpenIdLoginFlows } from "~/drizzle/schema";
|
import {
|
||||||
|
Applications,
|
||||||
|
OpenIdLoginFlows,
|
||||||
|
RolePermissions,
|
||||||
|
} from "~/drizzle/schema";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -25,6 +29,9 @@ export const meta = applyConfig({
|
||||||
max: 20,
|
max: 20,
|
||||||
},
|
},
|
||||||
route: "/api/v1/sso",
|
route: "/api/v1/sso",
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.OAUTH],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -46,7 +53,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const form = context.req.valid("form");
|
const form = context.req.valid("form");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { errorResponse, jsonResponse } from "@/response";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -15,6 +16,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.VIEW_NOTES],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -28,7 +32,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createLike } from "~/database/entities/Like";
|
import { createLike } from "~/database/entities/Like";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -17,6 +18,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_LIKES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -30,7 +37,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
|
|
@ -18,6 +18,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.VIEW_NOTES, RolePermissions.VIEW_NOTE_LIKES],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -38,7 +41,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { max_id, since_id, min_id, limit } =
|
const { max_id, since_id, min_id, limit } =
|
||||||
context.req.valid("query");
|
context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import ISO6391 from "iso-639-1";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { undoFederationRequest } from "~/database/entities/Federation";
|
import { undoFederationRequest } from "~/database/entities/Federation";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -26,6 +27,16 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
requiredOnMethods: ["DELETE", "PUT"],
|
requiredOnMethods: ["DELETE", "PUT"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.VIEW_NOTES],
|
||||||
|
methodOverrides: {
|
||||||
|
DELETE: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
PUT: [RolePermissions.MANAGE_OWN_NOTES, RolePermissions.VIEW_NOTES],
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -78,7 +89,7 @@ export default (app: Hono) =>
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -16,6 +17,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -29,7 +36,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { and, eq } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Notes, Notifications } from "~/drizzle/schema";
|
import { Notes, Notifications, RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -18,6 +18,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_BOOSTS,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -36,7 +42,7 @@ export default (app: Hono) =>
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { visibility } = context.req.valid("form");
|
const { visibility } = context.req.valid("form");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Users } from "~/drizzle/schema";
|
import { RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
|
|
@ -18,6 +18,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTE_BOOSTS,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -38,7 +44,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { max_id, min_id, since_id, limit } =
|
const { max_id, min_id, since_id, limit } =
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { errorResponse, jsonResponse } from "@/response";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
import type { StatusSource as APIStatusSource } from "~/types/mastodon/status_source";
|
import type { StatusSource as APIStatusSource } from "~/types/mastodon/status_source";
|
||||||
|
|
||||||
|
|
@ -16,6 +17,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -29,7 +36,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { deleteLike } from "~/database/entities/Like";
|
import { deleteLike } from "~/database/entities/Like";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -16,6 +17,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -29,7 +36,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { errorResponse, jsonResponse } from "@/response";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -15,6 +16,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -28,7 +35,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { and, eq } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { undoFederationRequest } from "~/database/entities/Federation";
|
import { undoFederationRequest } from "~/database/entities/Federation";
|
||||||
import { Notes } from "~/drizzle/schema";
|
import { Notes, RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -18,6 +18,12 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -31,7 +37,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import ISO6391 from "iso-639-1";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { federateNote, parseTextMentions } from "~/database/entities/Status";
|
import { federateNote, parseTextMentions } from "~/database/entities/Status";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
|
import { RolePermissions } from "~/drizzle/schema";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -19,6 +20,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_NOTES],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -85,7 +89,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user, application } = context.req.valid("header");
|
const { user, application } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, eq, gt, gte, lt, or, sql } from "drizzle-orm";
|
import { and, eq, gt, gte, lt, or, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Notes } from "~/drizzle/schema";
|
import { Notes, RolePermissions } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -17,6 +17,14 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.MANAGE_OWN_NOTES,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
RolePermissions.VIEW_PRIVATE_TIMELINES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -33,7 +41,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { max_id, since_id, min_id, limit } =
|
const { max_id, since_id, min_id, limit } =
|
||||||
context.req.valid("query");
|
context.req.valid("query");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
import { and, gt, gte, lt, sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Notes } from "~/drizzle/schema";
|
import { Notes, RolePermissions } from "~/drizzle/schema";
|
||||||
import { Timeline } from "~/packages/database-interface/timeline";
|
import { Timeline } from "~/packages/database-interface/timeline";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -17,6 +17,13 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
RolePermissions.VIEW_PUBLIC_TIMELINES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -45,7 +52,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const {
|
const {
|
||||||
max_id,
|
max_id,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { and, eq, inArray } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { FilterKeywords, Filters } from "~/drizzle/schema";
|
import { FilterKeywords, Filters, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET", "PUT", "DELETE"],
|
allowedMethods: ["GET", "PUT", "DELETE"],
|
||||||
|
|
@ -17,6 +17,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_FILTERS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -73,7 +76,7 @@ export default (app: Hono) =>
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("param", schemas.param, handleZodError),
|
zValidator("param", schemas.param, handleZodError),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
const { id } = context.req.valid("param");
|
const { id } = context.req.valid("param");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { FilterKeywords, Filters } from "~/drizzle/schema";
|
import { FilterKeywords, Filters, RolePermissions } from "~/drizzle/schema";
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET", "POST"],
|
allowedMethods: ["GET", "POST"],
|
||||||
route: "/api/v2/filters",
|
route: "/api/v2/filters",
|
||||||
|
|
@ -15,6 +15,9 @@ export const meta = applyConfig({
|
||||||
auth: {
|
auth: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_FILTERS],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -62,7 +65,7 @@ export default (app: Hono) =>
|
||||||
meta.route,
|
meta.route,
|
||||||
jsonOrForm(),
|
jsonOrForm(),
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user } = context.req.valid("header");
|
const { user } = context.req.valid("header");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import sharp from "sharp";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { attachmentToAPI, getUrl } from "~/database/entities/Attachment";
|
import { attachmentToAPI, getUrl } from "~/database/entities/Attachment";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Attachments } from "~/drizzle/schema";
|
import { Attachments, RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["POST"],
|
allowedMethods: ["POST"],
|
||||||
|
|
@ -24,6 +24,9 @@ export const meta = applyConfig({
|
||||||
required: true,
|
required: true,
|
||||||
oauthPermissions: ["write:media"],
|
oauthPermissions: ["write:media"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [RolePermissions.MANAGE_OWN_MEDIA],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -43,7 +46,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("form", schemas.form, handleZodError),
|
zValidator("form", schemas.form, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { file, thumbnail, description } = context.req.valid("form");
|
const { file, thumbnail, description } = context.req.valid("form");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { resolveWebFinger } from "~/database/entities/User";
|
import { resolveWebFinger } from "~/database/entities/User";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Instances, Notes, Users } from "~/drizzle/schema";
|
import { Instances, Notes, RolePermissions, Users } from "~/drizzle/schema";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
@ -25,6 +25,13 @@ export const meta = applyConfig({
|
||||||
required: false,
|
required: false,
|
||||||
oauthPermissions: ["read:search"],
|
oauthPermissions: ["read:search"],
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
required: [
|
||||||
|
RolePermissions.SEARCH,
|
||||||
|
RolePermissions.VIEW_ACCOUNTS,
|
||||||
|
RolePermissions.VIEW_NOTES,
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
|
|
@ -46,7 +53,7 @@ export default (app: Hono) =>
|
||||||
meta.allowedMethods,
|
meta.allowedMethods,
|
||||||
meta.route,
|
meta.route,
|
||||||
zValidator("query", schemas.query, handleZodError),
|
zValidator("query", schemas.query, handleZodError),
|
||||||
auth(meta.auth),
|
auth(meta.auth, meta.permissions),
|
||||||
async (context) => {
|
async (context) => {
|
||||||
const { user: self } = context.req.valid("header");
|
const { user: self } = context.req.valid("header");
|
||||||
const { q, type, resolve, following, account_id, limit, offset } =
|
const { q, type, resolve, following, account_id, limit, offset } =
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { SignJWT, jwtVerify } from "jose";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { TokenType } from "~/database/entities/Token";
|
import { TokenType } from "~/database/entities/Token";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Tokens } from "~/drizzle/schema";
|
import { RolePermissions, Tokens } from "~/drizzle/schema";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
|
|
@ -158,6 +158,14 @@ export default (app: Hono) =>
|
||||||
if (!user)
|
if (!user)
|
||||||
return returnError(body, "invalid_request", "Invalid sub");
|
return returnError(body, "invalid_request", "Invalid sub");
|
||||||
|
|
||||||
|
if (!user.hasPermission(RolePermissions.OAUTH)) {
|
||||||
|
return returnError(
|
||||||
|
body,
|
||||||
|
"invalid_request",
|
||||||
|
`User is missing the ${RolePermissions.OAUTH} permission`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const responseTypes = response_type.split(" ");
|
const responseTypes = response_type.split(" ");
|
||||||
|
|
||||||
const asksCode = responseTypes.includes("code");
|
const asksCode = responseTypes.includes("code");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { SignJWT } from "jose";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { TokenType } from "~/database/entities/Token";
|
import { TokenType } from "~/database/entities/Token";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Tokens } from "~/drizzle/schema";
|
import { RolePermissions, Tokens } from "~/drizzle/schema";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
import { OAuthManager } from "~/packages/database-interface/oauth";
|
import { OAuthManager } from "~/packages/database-interface/oauth";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
@ -139,6 +139,19 @@ export default (app: Hono) =>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!user.hasPermission(RolePermissions.OAUTH)) {
|
||||||
|
return returnError(
|
||||||
|
{
|
||||||
|
redirect_uri: flow.application?.redirectUri,
|
||||||
|
client_id: flow.application?.clientId,
|
||||||
|
response_type: "code",
|
||||||
|
scope: flow.application?.scopes,
|
||||||
|
},
|
||||||
|
"invalid_request",
|
||||||
|
`User does not have the '${RolePermissions.OAUTH}' permission`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!flow.application)
|
if (!flow.application)
|
||||||
return errorResponse("Application not found", 500);
|
return errorResponse("Application not found", 500);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import type { RouterRoute } from "hono/types";
|
import type { RouterRoute } from "hono/types";
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
|
import type { RolePermissions } from "~/drizzle/schema";
|
||||||
|
|
||||||
export type HttpVerb = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS";
|
export type HttpVerb = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS";
|
||||||
export interface APIRouteMetadata {
|
export interface APIRouteMetadata {
|
||||||
|
|
@ -15,6 +16,12 @@ export interface APIRouteMetadata {
|
||||||
requiredOnMethods?: HttpVerb[];
|
requiredOnMethods?: HttpVerb[];
|
||||||
oauthPermissions?: string[];
|
oauthPermissions?: string[];
|
||||||
};
|
};
|
||||||
|
permissions?: {
|
||||||
|
required: RolePermissions[];
|
||||||
|
methodOverrides?: {
|
||||||
|
[key in HttpVerb]?: RolePermissions[];
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface APIRouteExports {
|
export interface APIRouteExports {
|
||||||
|
|
|
||||||
35
utils/api.ts
35
utils/api.ts
|
|
@ -101,7 +101,10 @@ export const handleZodError = (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const auth = (authData: APIRouteMetadata["auth"]) =>
|
export const auth = (
|
||||||
|
authData: APIRouteMetadata["auth"],
|
||||||
|
permissionData?: APIRouteMetadata["permissions"],
|
||||||
|
) =>
|
||||||
validator("header", async (value, context) => {
|
validator("header", async (value, context) => {
|
||||||
const auth = value.authorization
|
const auth = value.authorization
|
||||||
? await getFromHeader(value.authorization)
|
? await getFromHeader(value.authorization)
|
||||||
|
|
@ -109,6 +112,34 @@ export const auth = (authData: APIRouteMetadata["auth"]) =>
|
||||||
|
|
||||||
const error = errorResponse("Unauthorized", 401);
|
const error = errorResponse("Unauthorized", 401);
|
||||||
|
|
||||||
|
// Permissions check
|
||||||
|
if (permissionData) {
|
||||||
|
const userPerms = auth?.user
|
||||||
|
? auth.user.getAllPermissions()
|
||||||
|
: config.permissions.anonymous;
|
||||||
|
|
||||||
|
const requiredPerms =
|
||||||
|
permissionData.methodOverrides?.[
|
||||||
|
context.req.method as HttpVerb
|
||||||
|
] ?? permissionData.required;
|
||||||
|
|
||||||
|
if (!requiredPerms.every((perm) => userPerms.includes(perm))) {
|
||||||
|
const missingPerms = requiredPerms.filter(
|
||||||
|
(perm) => !userPerms.includes(perm),
|
||||||
|
);
|
||||||
|
|
||||||
|
return context.json(
|
||||||
|
{
|
||||||
|
error: `You do not have the required permissions to access this route. Missing: ${missingPerms.join(
|
||||||
|
", ",
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
403,
|
||||||
|
error.headers.toJSON(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!auth?.user) {
|
if (!auth?.user) {
|
||||||
if (authData.required) {
|
if (authData.required) {
|
||||||
return context.json(
|
return context.json(
|
||||||
|
|
@ -133,6 +164,8 @@ export const auth = (authData: APIRouteMetadata["auth"]) =>
|
||||||
error.headers.toJSON(),
|
error.headers.toJSON(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check role permissions
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
user: auth.user as User,
|
user: auth.user as User,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue