feat(federation): federation_attach_proofs table (re-attach spec §3.1)

This commit is contained in:
Jannis Braun
2026-07-03 01:36:30 +02:00
parent 70a68ebe1e
commit 669d80d7c7
4 changed files with 3875 additions and 0 deletions
@@ -0,0 +1,8 @@
CREATE TABLE `federation_attach_proofs` (
`token` text PRIMARY KEY NOT NULL,
`home_user_id` text NOT NULL,
`target_domain` text NOT NULL,
`created_at` integer NOT NULL,
`expires_at` integer NOT NULL,
`used_at` integer
);
File diff suppressed because it is too large Load Diff
@@ -71,6 +71,13 @@
"when": 1783011477517,
"tag": "0009_uneven_red_ghost",
"breakpoints": true
},
{
"idx": 10,
"version": "6",
"when": 1783035334526,
"tag": "0010_broken_blazing_skull",
"breakpoints": true
}
]
}
+13
View File
@@ -407,6 +407,19 @@ export const federationResetEvents = sqliteTable('federation_reset_events', {
acknowledgedAt: integer('acknowledged_at'),
});
// One-time proof tokens for detached-account re-attach (re-attach spec §3.1).
// Minted by POST /api/auth/attach-proof for a logged-in native user, verified
// once by a peer via POST /api/federation/verify-attach-proof. Expired/used
// rows are deleted opportunistically on each mint.
export const federationAttachProofs = sqliteTable('federation_attach_proofs', {
token: text('token').primaryKey(),
homeUserId: text('home_user_id').notNull(),
targetDomain: text('target_domain').notNull(),
createdAt: integer('created_at').notNull(),
expiresAt: integer('expires_at').notNull(),
usedAt: integer('used_at'),
});
// SQL-level CHECK constraint enforces (direction='inbound' → hmac_secret NOT NULL).
// See packages/server/drizzle/0003_brave_inhumans.sql. drizzle-kit cannot represent
// CHECK constraints in its snapshot, so any future migration that recreates this