aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/db/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/db/models.py')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/db/models.py35
1 files changed, 35 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/db/models.py b/packages/meshbay-hub/src/meshbay_hub/db/models.py
index a220a64..12507a6 100644
--- a/packages/meshbay-hub/src/meshbay_hub/db/models.py
+++ b/packages/meshbay-hub/src/meshbay_hub/db/models.py
@@ -178,6 +178,41 @@ class FederatedGroup(Base):
)
+class UserDevice(Base):
+ """
+ A device's key for authenticating **to the hub**, and nothing else.
+
+ This is not a reintroduction of the key directory that was H3, and the
+ distinction is worth being precise about because it looks like one:
+
+ * **Nobody reads this but the hub.** No endpoint publishes it, nothing
+ wraps a group key for it, and no node ever asks for it. H3 was a
+ directory *others* read from, where a substituted key was handed the
+ GEK by an honest member.
+ * **It is not a node identity key.** Those are generated per node, pinned
+ there, and never leave that relationship (`docs/per-node-identity-v1.md`).
+ A device holds one of these *plus* a different key per node, so nothing
+ here correlates a person across operators.
+
+ What it does cost, stated plainly: the hub now knows how many devices an
+ account has and when each one last signed in. That is new metadata, and it
+ is the price of not deriving a key from the passphrase on every sign-in.
+ """
+
+ __tablename__ = "user_devices"
+
+ id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_uuid)
+ user_id: Mapped[str] = mapped_column(ForeignKey("users.id"), nullable=False)
+ # base64 raw Ed25519, unique so one device key belongs to one account
+ pk_auth_ed25519: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
+ label: Mapped[str] = mapped_column(String(64), default="")
+ created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now)
+ last_seen: Mapped[datetime | None] = mapped_column(
+ DateTime(timezone=True), nullable=True)
+
+ __table_args__ = (Index("ix_user_devices_user", "user_id"),)
+
+
class SwarmSource(Base):
"""
Tracks which nodes can serve a given content hash (public swarm).