From b687bfe721b6594b12d84c625ea10e42ead67482 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 26 Apr 2026 21:02:27 +0200 Subject: [PATCH] feat(federation): schema for outbound peering gate (direction column, subscribers, notifications) --- .../server/drizzle/0003_brave_inhumans.sql | 50 + .../server/drizzle/meta/0003_snapshot.json | 3445 +++++++++++++++++ packages/server/drizzle/meta/_journal.json | 7 + packages/server/src/db/schema.ts | 34 +- packages/server/src/routes/federation.ts | 9 + packages/server/src/utils/storageJanitor.ts | 7 + 6 files changed, 3549 insertions(+), 3 deletions(-) create mode 100644 packages/server/drizzle/0003_brave_inhumans.sql create mode 100644 packages/server/drizzle/meta/0003_snapshot.json diff --git a/packages/server/drizzle/0003_brave_inhumans.sql b/packages/server/drizzle/0003_brave_inhumans.sql new file mode 100644 index 00000000..f4f436e5 --- /dev/null +++ b/packages/server/drizzle/0003_brave_inhumans.sql @@ -0,0 +1,50 @@ +CREATE TABLE `peer_approval_notifications` ( + `id` text PRIMARY KEY NOT NULL, + `user_id` text NOT NULL, + `kind` text NOT NULL, + `peer_origin` text NOT NULL, + `trigger_reason` text NOT NULL, + `trigger_target` text NOT NULL, + `created_at` integer NOT NULL, + `read_at` integer, + FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE TABLE `peer_approval_subscribers` ( + `id` text PRIMARY KEY NOT NULL, + `request_id` text NOT NULL, + `user_id` text NOT NULL, + `trigger_reason` text NOT NULL, + `trigger_target` text NOT NULL, + `created_at` integer NOT NULL, + FOREIGN KEY (`request_id`) REFERENCES `peer_approval_requests`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `idx_peer_approval_notifications_user_id` ON `peer_approval_notifications` (`user_id`);--> statement-breakpoint +CREATE INDEX `idx_peer_approval_subscribers_user_id` ON `peer_approval_subscribers` (`user_id`);--> statement-breakpoint +CREATE UNIQUE INDEX `peer_approval_subscribers_request_id_user_id_trigger_reason_trigger_target_unique` ON `peer_approval_subscribers` (`request_id`,`user_id`,`trigger_reason`,`trigger_target`);--> statement-breakpoint +-- Recreate peer_approval_requests: +-- - add direction column (default 'inbound') so existing rows classify correctly +-- - relax hmac_secret to nullable (outbound rows generate fresh on approval) +-- - drop UNIQUE(origin); add UNIQUE(origin, direction) +-- - add CHECK enforcing inbound rows always carry hmac_secret +CREATE TABLE `__new_peer_approval_requests` ( + `id` text PRIMARY KEY NOT NULL, + `origin` text NOT NULL, + `direction` text DEFAULT 'inbound' NOT NULL, + `instance_name` text, + `hmac_secret` text, + `requested_at` integer NOT NULL, + `expires_at` integer NOT NULL, + `approval_token` text, + CHECK ( + (direction = 'inbound' AND hmac_secret IS NOT NULL) + OR (direction = 'outbound') + ) +);--> statement-breakpoint +INSERT INTO `__new_peer_approval_requests` (`id`, `origin`, `direction`, `instance_name`, `hmac_secret`, `requested_at`, `expires_at`, `approval_token`) +SELECT `id`, `origin`, 'inbound', `instance_name`, `hmac_secret`, `requested_at`, `expires_at`, `approval_token` FROM `peer_approval_requests`;--> statement-breakpoint +DROP TABLE `peer_approval_requests`;--> statement-breakpoint +ALTER TABLE `__new_peer_approval_requests` RENAME TO `peer_approval_requests`;--> statement-breakpoint +CREATE UNIQUE INDEX `peer_approval_requests_origin_direction_unique` ON `peer_approval_requests` (`origin`,`direction`); diff --git a/packages/server/drizzle/meta/0003_snapshot.json b/packages/server/drizzle/meta/0003_snapshot.json new file mode 100644 index 00000000..684da74d --- /dev/null +++ b/packages/server/drizzle/meta/0003_snapshot.json @@ -0,0 +1,3445 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "5ae0d7c7-5409-464d-b8d2-8af70cf6601f", + "prevId": "a603a29a-c462-46c0-b559-5fcfb2453b27", + "tables": { + "attachments": { + "name": "attachments", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dm_message_id": { + "name": "dm_message_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "uploader_id": { + "name": "uploader_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "original_name": { + "name": "original_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "mimetype": { + "name": "mimetype", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "thumbnail_filename": { + "name": "thumbnail_filename", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "duration": { + "name": "duration", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_url": { + "name": "source_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "federation_status": { + "name": "federation_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "federation_meta": { + "name": "federation_meta", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_attachments_message_id": { + "name": "idx_attachments_message_id", + "columns": [ + "message_id" + ], + "isUnique": false + }, + "idx_attachments_dm_message_id": { + "name": "idx_attachments_dm_message_id", + "columns": [ + "dm_message_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "attachments_message_id_messages_id_fk": { + "name": "attachments_message_id_messages_id_fk", + "tableFrom": "attachments", + "tableTo": "messages", + "columnsFrom": [ + "message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "attachments_dm_message_id_dm_messages_id_fk": { + "name": "attachments_dm_message_id_dm_messages_id_fk", + "tableFrom": "attachments", + "tableTo": "dm_messages", + "columnsFrom": [ + "dm_message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "bans": { + "name": "bans", + "columns": { + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "banned_by": { + "name": "banned_by", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_bans_space_id": { + "name": "idx_bans_space_id", + "columns": [ + "space_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "bans_space_id_spaces_id_fk": { + "name": "bans_space_id_spaces_id_fk", + "tableFrom": "bans", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bans_user_id_users_id_fk": { + "name": "bans_user_id_users_id_fk", + "tableFrom": "bans", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bans_banned_by_users_id_fk": { + "name": "bans_banned_by_users_id_fk", + "tableFrom": "bans", + "tableTo": "users", + "columnsFrom": [ + "banned_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "bans_space_id_user_id_pk": { + "columns": [ + "space_id", + "user_id" + ], + "name": "bans_space_id_user_id_pk" + } + }, + "uniqueConstraints": {} + }, + "category_overrides": { + "name": "category_overrides", + "columns": { + "category_id": { + "name": "category_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "allow": { + "name": "allow", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'0'" + }, + "deny": { + "name": "deny", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'0'" + } + }, + "indexes": { + "idx_category_overrides_category_id": { + "name": "idx_category_overrides_category_id", + "columns": [ + "category_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "category_overrides_category_id_channel_categories_id_fk": { + "name": "category_overrides_category_id_channel_categories_id_fk", + "tableFrom": "category_overrides", + "tableTo": "channel_categories", + "columnsFrom": [ + "category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "category_overrides_category_id_target_type_target_id_pk": { + "columns": [ + "category_id", + "target_type", + "target_id" + ], + "name": "category_overrides_category_id_target_type_target_id_pk" + } + }, + "uniqueConstraints": {} + }, + "channel_categories": { + "name": "channel_categories", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_channel_categories_space_id": { + "name": "idx_channel_categories_space_id", + "columns": [ + "space_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "channel_categories_space_id_spaces_id_fk": { + "name": "channel_categories_space_id_spaces_id_fk", + "tableFrom": "channel_categories", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "channel_overrides": { + "name": "channel_overrides", + "columns": { + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "allow": { + "name": "allow", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'0'" + }, + "deny": { + "name": "deny", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'0'" + } + }, + "indexes": { + "idx_channel_overrides_channel_id": { + "name": "idx_channel_overrides_channel_id", + "columns": [ + "channel_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "channel_overrides_channel_id_channels_id_fk": { + "name": "channel_overrides_channel_id_channels_id_fk", + "tableFrom": "channel_overrides", + "tableTo": "channels", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "channel_overrides_channel_id_target_type_target_id_pk": { + "columns": [ + "channel_id", + "target_type", + "target_id" + ], + "name": "channel_overrides_channel_id_target_type_target_id_pk" + } + }, + "uniqueConstraints": {} + }, + "channels": { + "name": "channels", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "topic": { + "name": "topic", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "category_id": { + "name": "category_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_channels_space_id": { + "name": "idx_channels_space_id", + "columns": [ + "space_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "channels_space_id_spaces_id_fk": { + "name": "channels_space_id_spaces_id_fk", + "tableFrom": "channels", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "dm_channels": { + "name": "dm_channels", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "owner_id": { + "name": "owner_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "federated_id": { + "name": "federated_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "owner_home_user_id": { + "name": "owner_home_user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "owner_home_instance": { + "name": "owner_home_instance", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_dm_federated": { + "name": "idx_dm_federated", + "columns": [ + "federated_id" + ], + "isUnique": true, + "where": "federated_id IS NOT NULL" + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "dm_members": { + "name": "dm_members", + "columns": { + "dm_channel_id": { + "name": "dm_channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "closed": { + "name": "closed", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + } + }, + "indexes": { + "idx_dm_members_user_id": { + "name": "idx_dm_members_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "dm_members_dm_channel_id_dm_channels_id_fk": { + "name": "dm_members_dm_channel_id_dm_channels_id_fk", + "tableFrom": "dm_members", + "tableTo": "dm_channels", + "columnsFrom": [ + "dm_channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "dm_members_user_id_users_id_fk": { + "name": "dm_members_user_id_users_id_fk", + "tableFrom": "dm_members", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "dm_members_dm_channel_id_user_id_pk": { + "columns": [ + "dm_channel_id", + "user_id" + ], + "name": "dm_members_dm_channel_id_user_id_pk" + } + }, + "uniqueConstraints": {} + }, + "dm_messages": { + "name": "dm_messages", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "dm_channel_id": { + "name": "dm_channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "reply_to_id": { + "name": "reply_to_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'user'" + }, + "edited_at": { + "name": "edited_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_instance": { + "name": "source_instance", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_message_id": { + "name": "source_message_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "encryption_version": { + "name": "encryption_version", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_dm_messages_dm_channel_id": { + "name": "idx_dm_messages_dm_channel_id", + "columns": [ + "dm_channel_id" + ], + "isUnique": false + }, + "idx_dm_messages_user_id": { + "name": "idx_dm_messages_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_dm_messages_source_unique": { + "name": "idx_dm_messages_source_unique", + "columns": [ + "source_instance", + "source_message_id" + ], + "isUnique": true, + "where": "source_instance IS NOT NULL" + } + }, + "foreignKeys": { + "dm_messages_dm_channel_id_dm_channels_id_fk": { + "name": "dm_messages_dm_channel_id_dm_channels_id_fk", + "tableFrom": "dm_messages", + "tableTo": "dm_channels", + "columnsFrom": [ + "dm_channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "dm_messages_user_id_users_id_fk": { + "name": "dm_messages_user_id_users_id_fk", + "tableFrom": "dm_messages", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "dm_messages_reply_to_id_dm_messages_id_fk": { + "name": "dm_messages_reply_to_id_dm_messages_id_fk", + "tableFrom": "dm_messages", + "tableTo": "dm_messages", + "columnsFrom": [ + "reply_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "dm_reactions": { + "name": "dm_reactions", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "dm_message_id": { + "name": "dm_message_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "emoji": { + "name": "emoji", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_dm_reactions_dm_message_id": { + "name": "idx_dm_reactions_dm_message_id", + "columns": [ + "dm_message_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "dm_reactions_dm_message_id_dm_messages_id_fk": { + "name": "dm_reactions_dm_message_id_dm_messages_id_fk", + "tableFrom": "dm_reactions", + "tableTo": "dm_messages", + "columnsFrom": [ + "dm_message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "dm_reactions_user_id_users_id_fk": { + "name": "dm_reactions_user_id_users_id_fk", + "tableFrom": "dm_reactions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "embeds": { + "name": "embeds", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dm_message_id": { + "name": "dm_message_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "embed_type": { + "name": "embed_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "embed_url": { + "name": "embed_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_embeds_message_id": { + "name": "idx_embeds_message_id", + "columns": [ + "message_id" + ], + "isUnique": false + }, + "idx_embeds_dm_message_id": { + "name": "idx_embeds_dm_message_id", + "columns": [ + "dm_message_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "embeds_message_id_messages_id_fk": { + "name": "embeds_message_id_messages_id_fk", + "tableFrom": "embeds", + "tableTo": "messages", + "columnsFrom": [ + "message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "embeds_dm_message_id_dm_messages_id_fk": { + "name": "embeds_dm_message_id_dm_messages_id_fk", + "tableFrom": "embeds", + "tableTo": "dm_messages", + "columnsFrom": [ + "dm_message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "federation_file_queue": { + "name": "federation_file_queue", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "peer_origin": { + "name": "peer_origin", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dm_message_id": { + "name": "dm_message_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_url": { + "name": "source_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "target_filename": { + "name": "target_filename", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "original_name": { + "name": "original_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "mimetype": { + "name": "mimetype", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "rejection_reason": { + "name": "rejection_reason", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "next_retry_at": { + "name": "next_retry_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "federation_mutation_log": { + "name": "federation_mutation_log", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "context_id": { + "name": "context_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "context_type": { + "name": "context_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'dm'" + }, + "mutation_type": { + "name": "mutation_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "mutated_at": { + "name": "mutated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_mutation_log_time": { + "name": "idx_mutation_log_time", + "columns": [ + "mutated_at" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "federation_outbox": { + "name": "federation_outbox", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "peer_id": { + "name": "peer_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "context_id": { + "name": "context_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "context_type": { + "name": "context_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'dm'" + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "encryption_version": { + "name": "encryption_version", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "next_retry_at": { + "name": "next_retry_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_outbox_retry": { + "name": "idx_outbox_retry", + "columns": [ + "next_retry_at" + ], + "isUnique": false + }, + "federation_outbox_peer_id_entity_id_unique": { + "name": "federation_outbox_peer_id_entity_id_unique", + "columns": [ + "peer_id", + "entity_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "federation_outbox_peer_id_federation_peers_id_fk": { + "name": "federation_outbox_peer_id_federation_peers_id_fk", + "tableFrom": "federation_outbox", + "tableTo": "federation_peers", + "columnsFrom": [ + "peer_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "federation_peers": { + "name": "federation_peers", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "origin": { + "name": "origin", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "instance_name": { + "name": "instance_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "hmac_secret": { + "name": "hmac_secret", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'active'" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_failure_at": { + "name": "last_failure_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "consecutive_failures": { + "name": "consecutive_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "consecutive_auth_failures": { + "name": "consecutive_auth_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "remote_max_upload_size": { + "name": "remote_max_upload_size", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "nonce_supported": { + "name": "nonce_supported", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "pending_hmac_secret": { + "name": "pending_hmac_secret", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "secret_rotation_at": { + "name": "secret_rotation_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "secret_rotated_at": { + "name": "secret_rotated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auto_rotate_interval_days": { + "name": "auto_rotate_interval_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 90 + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "approval_token": { + "name": "approval_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "federation_peers_origin_unique": { + "name": "federation_peers_origin_unique", + "columns": [ + "origin" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "friend_requests": { + "name": "friend_requests", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "from_id": { + "name": "from_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "to_id": { + "name": "to_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'pending'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "relay_message_id": { + "name": "relay_message_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_friend_requests_to_id": { + "name": "idx_friend_requests_to_id", + "columns": [ + "to_id" + ], + "isUnique": false + }, + "idx_friend_requests_from_id": { + "name": "idx_friend_requests_from_id", + "columns": [ + "from_id" + ], + "isUnique": false + }, + "idx_friend_requests_relay_message_id": { + "name": "idx_friend_requests_relay_message_id", + "columns": [ + "relay_message_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "friend_requests_from_id_users_id_fk": { + "name": "friend_requests_from_id_users_id_fk", + "tableFrom": "friend_requests", + "tableTo": "users", + "columnsFrom": [ + "from_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "friend_requests_to_id_users_id_fk": { + "name": "friend_requests_to_id_users_id_fk", + "tableFrom": "friend_requests", + "tableTo": "users", + "columnsFrom": [ + "to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "friends": { + "name": "friends", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "friend_id": { + "name": "friend_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_friends_user_id": { + "name": "idx_friends_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_friends_friend_id": { + "name": "idx_friends_friend_id", + "columns": [ + "friend_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "friends_user_id_users_id_fk": { + "name": "friends_user_id_users_id_fk", + "tableFrom": "friends", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "friends_friend_id_users_id_fk": { + "name": "friends_friend_id_users_id_fk", + "tableFrom": "friends", + "tableTo": "users", + "columnsFrom": [ + "friend_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "friends_user_id_friend_id_pk": { + "columns": [ + "user_id", + "friend_id" + ], + "name": "friends_user_id_friend_id_pk" + } + }, + "uniqueConstraints": {} + }, + "instance_settings": { + "name": "instance_settings", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "instance_name": { + "name": "instance_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'Backspace'" + }, + "worker_id": { + "name": "worker_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "discovery_enabled": { + "name": "discovery_enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "max_bitrate_kbps": { + "name": "max_bitrate_kbps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 20000 + }, + "min_bitrate_kbps": { + "name": "min_bitrate_kbps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 500 + }, + "bitrate_step_kbps": { + "name": "bitrate_step_kbps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 500 + }, + "allowed_resolutions": { + "name": "allowed_resolutions", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'540,720,1080'" + }, + "allowed_framerates": { + "name": "allowed_framerates", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'30,45,60'" + }, + "max_resolution": { + "name": "max_resolution", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1080 + }, + "max_framerate": { + "name": "max_framerate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 60 + }, + "registration_open": { + "name": "registration_open", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "gif_api_key": { + "name": "gif_api_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "bitrate_matrix_overrides": { + "name": "bitrate_matrix_overrides", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "allow_custom_bitrate": { + "name": "allow_custom_bitrate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "max_upload_size_bytes": { + "name": "max_upload_size_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "federation_relay_enabled": { + "name": "federation_relay_enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "federation_relay_ttl_days": { + "name": "federation_relay_ttl_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 30 + }, + "default_auto_rotate_interval_days": { + "name": "default_auto_rotate_interval_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 90 + }, + "auto_accept_peering": { + "name": "auto_accept_peering", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "join_requests": { + "name": "join_requests", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "decided_by": { + "name": "decided_by", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "decided_at": { + "name": "decided_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_join_requests_space_id_status": { + "name": "idx_join_requests_space_id_status", + "columns": [ + "space_id", + "status" + ], + "isUnique": false + } + }, + "foreignKeys": { + "join_requests_space_id_spaces_id_fk": { + "name": "join_requests_space_id_spaces_id_fk", + "tableFrom": "join_requests", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "join_requests_user_id_users_id_fk": { + "name": "join_requests_user_id_users_id_fk", + "tableFrom": "join_requests", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "join_requests_decided_by_users_id_fk": { + "name": "join_requests_decided_by_users_id_fk", + "tableFrom": "join_requests", + "tableTo": "users", + "columnsFrom": [ + "decided_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "member_roles": { + "name": "member_roles", + "columns": { + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role_id": { + "name": "role_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_member_roles_user_id_space_id": { + "name": "idx_member_roles_user_id_space_id", + "columns": [ + "user_id", + "space_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "member_roles_space_id_spaces_id_fk": { + "name": "member_roles_space_id_spaces_id_fk", + "tableFrom": "member_roles", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_roles_user_id_users_id_fk": { + "name": "member_roles_user_id_users_id_fk", + "tableFrom": "member_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_roles_role_id_roles_id_fk": { + "name": "member_roles_role_id_roles_id_fk", + "tableFrom": "member_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "member_roles_space_id_user_id_role_id_pk": { + "columns": [ + "space_id", + "user_id", + "role_id" + ], + "name": "member_roles_space_id_user_id_role_id_pk" + } + }, + "uniqueConstraints": {} + }, + "messages": { + "name": "messages", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "reply_to_id": { + "name": "reply_to_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "edited_at": { + "name": "edited_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_messages_channel_id": { + "name": "idx_messages_channel_id", + "columns": [ + "channel_id" + ], + "isUnique": false + }, + "idx_messages_user_id": { + "name": "idx_messages_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "messages_channel_id_channels_id_fk": { + "name": "messages_channel_id_channels_id_fk", + "tableFrom": "messages", + "tableTo": "channels", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "messages_user_id_users_id_fk": { + "name": "messages_user_id_users_id_fk", + "tableFrom": "messages", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "messages_reply_to_id_messages_id_fk": { + "name": "messages_reply_to_id_messages_id_fk", + "tableFrom": "messages", + "tableTo": "messages", + "columnsFrom": [ + "reply_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "peer_approval_notifications": { + "name": "peer_approval_notifications", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "peer_origin": { + "name": "peer_origin", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_reason": { + "name": "trigger_reason", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_target": { + "name": "trigger_target", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "read_at": { + "name": "read_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_peer_approval_notifications_user_id": { + "name": "idx_peer_approval_notifications_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "peer_approval_notifications_user_id_users_id_fk": { + "name": "peer_approval_notifications_user_id_users_id_fk", + "tableFrom": "peer_approval_notifications", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "peer_approval_requests": { + "name": "peer_approval_requests", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "origin": { + "name": "origin", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "direction": { + "name": "direction", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'inbound'" + }, + "instance_name": { + "name": "instance_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "hmac_secret": { + "name": "hmac_secret", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "requested_at": { + "name": "requested_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "approval_token": { + "name": "approval_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "peer_approval_requests_origin_direction_unique": { + "name": "peer_approval_requests_origin_direction_unique", + "columns": [ + "origin", + "direction" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "peer_approval_subscribers": { + "name": "peer_approval_subscribers", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_reason": { + "name": "trigger_reason", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "trigger_target": { + "name": "trigger_target", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_peer_approval_subscribers_user_id": { + "name": "idx_peer_approval_subscribers_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "peer_approval_subscribers_request_id_user_id_trigger_reason_trigger_target_unique": { + "name": "peer_approval_subscribers_request_id_user_id_trigger_reason_trigger_target_unique", + "columns": [ + "request_id", + "user_id", + "trigger_reason", + "trigger_target" + ], + "isUnique": true + } + }, + "foreignKeys": { + "peer_approval_subscribers_request_id_peer_approval_requests_id_fk": { + "name": "peer_approval_subscribers_request_id_peer_approval_requests_id_fk", + "tableFrom": "peer_approval_subscribers", + "tableTo": "peer_approval_requests", + "columnsFrom": [ + "request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "peer_approval_subscribers_user_id_users_id_fk": { + "name": "peer_approval_subscribers_user_id_users_id_fk", + "tableFrom": "peer_approval_subscribers", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "reactions": { + "name": "reactions", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "emoji": { + "name": "emoji", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_reactions_message_id": { + "name": "idx_reactions_message_id", + "columns": [ + "message_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "reactions_message_id_messages_id_fk": { + "name": "reactions_message_id_messages_id_fk", + "tableFrom": "reactions", + "tableTo": "messages", + "columnsFrom": [ + "message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reactions_user_id_users_id_fk": { + "name": "reactions_user_id_users_id_fk", + "tableFrom": "reactions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "read_states": { + "name": "read_states", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_read_message_id": { + "name": "last_read_message_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_read_states_user_id": { + "name": "idx_read_states_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "read_states_user_id_users_id_fk": { + "name": "read_states_user_id_users_id_fk", + "tableFrom": "read_states", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "read_states_user_id_channel_id_pk": { + "columns": [ + "user_id", + "channel_id" + ], + "name": "read_states_user_id_channel_id_pk" + } + }, + "uniqueConstraints": {} + }, + "roles": { + "name": "roles", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'#b9bbbe'" + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_roles_space_id": { + "name": "idx_roles_space_id", + "columns": [ + "space_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "roles_space_id_spaces_id_fk": { + "name": "roles_space_id_spaces_id_fk", + "tableFrom": "roles", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "space_folder_members": { + "name": "space_folder_members", + "columns": { + "folder_id": { + "name": "folder_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "space_folder_members_folder_id_space_folders_id_fk": { + "name": "space_folder_members_folder_id_space_folders_id_fk", + "tableFrom": "space_folder_members", + "tableTo": "space_folders", + "columnsFrom": [ + "folder_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "space_folder_members_folder_id_space_id_pk": { + "columns": [ + "folder_id", + "space_id" + ], + "name": "space_folder_members_folder_id_space_id_pk" + } + }, + "uniqueConstraints": {} + }, + "space_folders": { + "name": "space_folders", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "space_folders_user_id_users_id_fk": { + "name": "space_folders_user_id_users_id_fk", + "tableFrom": "space_folders", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "space_members": { + "name": "space_members", + "columns": { + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "nickname": { + "name": "nickname", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "joined_at": { + "name": "joined_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_space_members_user_id": { + "name": "idx_space_members_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "space_members_space_id_spaces_id_fk": { + "name": "space_members_space_id_spaces_id_fk", + "tableFrom": "space_members", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "space_members_user_id_users_id_fk": { + "name": "space_members_user_id_users_id_fk", + "tableFrom": "space_members", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "space_members_space_id_user_id_pk": { + "columns": [ + "space_id", + "user_id" + ], + "name": "space_members_space_id_user_id_pk" + } + }, + "uniqueConstraints": {} + }, + "spaces": { + "name": "spaces", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "banner": { + "name": "banner", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "avatar_color": { + "name": "avatar_color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "owner_id": { + "name": "owner_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "invite_code": { + "name": "invite_code", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'private'" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "spaces_invite_code_unique": { + "name": "spaces_invite_code_unique", + "columns": [ + "invite_code" + ], + "isUnique": true + } + }, + "foreignKeys": { + "spaces_owner_id_users_id_fk": { + "name": "spaces_owner_id_users_id_fk", + "tableFrom": "spaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user_federation_registry": { + "name": "user_federation_registry", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "origin": { + "name": "origin", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "remote_user_id": { + "name": "remote_user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'connected'" + }, + "added_at": { + "name": "added_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_connected_at": { + "name": "last_connected_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disconnected_at": { + "name": "disconnected_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_federation_registry_user_id_users_id_fk": { + "name": "user_federation_registry_user_id_users_id_fk", + "tableFrom": "user_federation_registry", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_federation_registry_user_id_origin_pk": { + "columns": [ + "user_id", + "origin" + ], + "name": "user_federation_registry_user_id_origin_pk" + } + }, + "uniqueConstraints": {} + }, + "user_space_layout": { + "name": "user_space_layout", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "layout": { + "name": "layout", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'[]'" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_space_layout_user_id_users_id_fk": { + "name": "user_space_layout_user_id_users_id_fk", + "tableFrom": "user_space_layout", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "users": { + "name": "users", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "avatar": { + "name": "avatar", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'offline'" + }, + "custom_status": { + "name": "custom_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_admin": { + "name": "is_admin", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "home_instance": { + "name": "home_instance", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "home_user_id": { + "name": "home_user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "replicated_instances": { + "name": "replicated_instances", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'[]'" + }, + "banner": { + "name": "banner", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "avatar_color": { + "name": "avatar_color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_deleted": { + "name": "is_deleted", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "discoverable": { + "name": "discoverable", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 1 + }, + "profile_updated_at": { + "name": "profile_updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password_changed_at": { + "name": "password_changed_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_activity": { + "name": "show_activity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "federation_registry_updated_at": { + "name": "federation_registry_updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "users_username_unique": { + "name": "users_username_unique", + "columns": [ + "username" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "voice_restrictions": { + "name": "voice_restrictions", + "columns": { + "space_id": { + "name": "space_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "restriction_type": { + "name": "restriction_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "moderator_id": { + "name": "moderator_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_voice_restrictions_space_id": { + "name": "idx_voice_restrictions_space_id", + "columns": [ + "space_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "voice_restrictions_space_id_spaces_id_fk": { + "name": "voice_restrictions_space_id_spaces_id_fk", + "tableFrom": "voice_restrictions", + "tableTo": "spaces", + "columnsFrom": [ + "space_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "voice_restrictions_user_id_users_id_fk": { + "name": "voice_restrictions_user_id_users_id_fk", + "tableFrom": "voice_restrictions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "voice_restrictions_moderator_id_users_id_fk": { + "name": "voice_restrictions_moderator_id_users_id_fk", + "tableFrom": "voice_restrictions", + "tableTo": "users", + "columnsFrom": [ + "moderator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "voice_restrictions_space_id_user_id_restriction_type_pk": { + "columns": [ + "space_id", + "user_id", + "restriction_type" + ], + "name": "voice_restrictions_space_id_user_id_restriction_type_pk" + } + }, + "uniqueConstraints": {} + } + }, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/packages/server/drizzle/meta/_journal.json b/packages/server/drizzle/meta/_journal.json index 72a4d99a..3880987d 100644 --- a/packages/server/drizzle/meta/_journal.json +++ b/packages/server/drizzle/meta/_journal.json @@ -22,6 +22,13 @@ "when": 1777196627239, "tag": "0002_peer_approval_token", "breakpoints": true + }, + { + "idx": 3, + "version": "6", + "when": 1777229997210, + "tag": "0003_brave_inhumans", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/server/src/db/schema.ts b/packages/server/src/db/schema.ts index 17c3a696..5f877c4d 100644 --- a/packages/server/src/db/schema.ts +++ b/packages/server/src/db/schema.ts @@ -379,13 +379,41 @@ export const federationPeers = sqliteTable('federation_peers', { export const peerApprovalRequests = sqliteTable('peer_approval_requests', { id: text('id').primaryKey(), - origin: text('origin').notNull().unique(), + origin: text('origin').notNull(), + direction: text('direction').notNull().default('inbound'), instanceName: text('instance_name'), - hmacSecret: text('hmac_secret').notNull(), + hmacSecret: text('hmac_secret'), requestedAt: integer('requested_at').notNull(), expiresAt: integer('expires_at').notNull(), approvalToken: text('approval_token'), -}); +}, (table) => ({ + uniqOriginDirection: unique().on(table.origin, table.direction), +})); + +export const peerApprovalSubscribers = sqliteTable('peer_approval_subscribers', { + id: text('id').primaryKey(), + requestId: text('request_id').notNull().references(() => peerApprovalRequests.id, { onDelete: 'cascade' }), + userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }), + triggerReason: text('trigger_reason').notNull(), + triggerTarget: text('trigger_target').notNull(), + createdAt: integer('created_at').notNull(), +}, (table) => ({ + uniqSubscription: unique().on(table.requestId, table.userId, table.triggerReason, table.triggerTarget), + userIdx: index('idx_peer_approval_subscribers_user_id').on(table.userId), +})); + +export const peerApprovalNotifications = sqliteTable('peer_approval_notifications', { + id: text('id').primaryKey(), + userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }), + kind: text('kind').notNull(), + peerOrigin: text('peer_origin').notNull(), + triggerReason: text('trigger_reason').notNull(), + triggerTarget: text('trigger_target').notNull(), + createdAt: integer('created_at').notNull(), + readAt: integer('read_at'), +}, (table) => ({ + userIdx: index('idx_peer_approval_notifications_user_id').on(table.userId), +})); export const federationOutbox = sqliteTable('federation_outbox', { id: text('id').primaryKey(), diff --git a/packages/server/src/routes/federation.ts b/packages/server/src/routes/federation.ts index 34e18bdf..62c784df 100644 --- a/packages/server/src/routes/federation.ts +++ b/packages/server/src/routes/federation.ts @@ -1370,6 +1370,15 @@ export async function federationRoutes(app: FastifyInstance): Promise { return reply.code(404).send({ error: 'Approval request not found', statusCode: 404 }); } + // Outbound rows have no hmac_secret and no remote /peer/denied endpoint to call. + // Direction-branched handling lands in Task 7; until then, inbound is the only path here. + if (!approvalReq.hmacSecret) { + return reply.code(400).send({ + error: 'Cannot deny an outbound peering request via this endpoint yet — outbound denial handling is not implemented.', + statusCode: 400, + }); + } + const ourOrigin = getOurOrigin(); const denialBody = JSON.stringify({ origin: ourOrigin, diff --git a/packages/server/src/utils/storageJanitor.ts b/packages/server/src/utils/storageJanitor.ts index d1ac81bb..73f0ebd2 100644 --- a/packages/server/src/utils/storageJanitor.ts +++ b/packages/server/src/utils/storageJanitor.ts @@ -452,6 +452,13 @@ export async function cleanupExpiredApprovalRequests(): Promise { let cleaned = 0; for (const req of expired) { + // Outbound rows have no hmac_secret and no remote /peer/denied endpoint; + // their expiry handling (subscriber notifications) lands in Task 9. + // Until then, skip outbound rows here so this loop only processes inbound expirations. + if (!req.hmacSecret) { + continue; + } + const denialBody = JSON.stringify({ origin: ourOrigin, reason: 'expired' as const,