From fd3c35d23caebab8d8adab9126d120fceddc4b71 Mon Sep 17 00:00:00 2001 From: Owais Jamil Date: Sat, 13 Jun 2026 18:16:27 -0500 Subject: [PATCH] build: update synced lexicons --- lib/mix/tasks/tempest.lexicon.sync.ex | 1 + lib/tempest/accounts.ex | 22 +- lib/tempest/lexicon/bundled.ex | 279 +++++++++++++----- lib/tempest/repo_storage.ex | 3 + .../official/app/bsky/embed/gallery.json | 79 +++++ .../official/app/bsky/embed/record.json | 1 + .../app/bsky/embed/recordWithMedia.json | 2 + .../lexicons/official/app/bsky/feed/defs.json | 1 + .../official/com/atproto/repo/importRepo.json | 19 +- .../com/atproto/repo/listMissingBlobs.json | 27 +- .../com/atproto/server/activateAccount.json | 5 +- .../atproto/server/checkAccountStatus.json | 31 +- .../com/atproto/server/deactivateAccount.json | 17 +- .../com/atproto/server/deleteAccount.json | 17 +- .../com/atproto/server/getServiceAuth.json | 38 ++- .../atproto/server/requestAccountDelete.json | 4 +- .../com/atproto/server/reserveSigningKey.json | 25 +- 17 files changed, 433 insertions(+), 138 deletions(-) create mode 100644 priv/lexicons/official/app/bsky/embed/gallery.json diff --git a/lib/mix/tasks/tempest.lexicon.sync.ex b/lib/mix/tasks/tempest.lexicon.sync.ex index 61ebc85..0e954e2 100644 --- a/lib/mix/tasks/tempest.lexicon.sync.ex +++ b/lib/mix/tasks/tempest.lexicon.sync.ex @@ -38,6 +38,7 @@ defmodule Mix.Tasks.Tempest.Lexicon.Sync do app/bsky/actor/putPreferences.json app/bsky/embed/defs.json app/bsky/embed/external.json + app/bsky/embed/gallery.json app/bsky/embed/images.json app/bsky/embed/record.json app/bsky/embed/recordWithMedia.json diff --git a/lib/tempest/accounts.ex b/lib/tempest/accounts.ex index 41ff25c..6bb8996 100644 --- a/lib/tempest/accounts.ex +++ b/lib/tempest/accounts.ex @@ -159,11 +159,23 @@ defmodule Tempest.Accounts do def check_account_status(%AuthContext{account: account}) do with {:ok, repo_counts} <- RepoStorage.status_counts(account.did), - {:ok, blob_counts} <- Tempest.Blobs.status_counts(account.did, repo_counts.referenced_blob_cids) do + {:ok, blob_counts} <- Tempest.Blobs.status_counts(account.did, repo_counts.referenced_blob_cids), + {:ok, repo_head} <- account_repo_head(account.did, repo_counts.repo_count) do + activated? = account.active and account.status == "active" + {:ok, %{ + "activated" => activated?, + "validDid" => true, + "repoCommit" => repo_head.cid, + "repoRev" => repo_head.rev, + "repoBlocks" => repo_counts.block_count, + "indexedRecords" => repo_counts.record_count, + "privateStateValues" => 0, + "expectedBlobs" => repo_counts.referenced_blob_count, + "importedBlobs" => blob_counts.blob_count, "did" => account.did, - "active" => account.active and account.status == "active", + "active" => activated?, "status" => account.status, "repoCount" => repo_counts.repo_count, "recordCount" => repo_counts.record_count, @@ -174,6 +186,12 @@ defmodule Tempest.Accounts do end end + defp account_repo_head(did, repo_count) when repo_count > 0 do + RepoStorage.latest_commit(did) + end + + defp account_repo_head(_did, _repo_count), do: {:ok, %{cid: "", rev: ""}} + def get_service_auth(%AuthContext{account: account}, params) when is_map(params) do audience = Map.get(params, "aud") || Map.get(params, "audience") method_nsid = Map.get(params, "lxm") || Map.get(params, "method") diff --git a/lib/tempest/lexicon/bundled.ex b/lib/tempest/lexicon/bundled.ex index f6bc58b..e09f1b6 100644 --- a/lib/tempest/lexicon/bundled.ex +++ b/lib/tempest/lexicon/bundled.ex @@ -10,7 +10,7 @@ defmodule Tempest.Lexicon.Bundled do @behaviour Tempest.Lexicon.Provider @manifest %{ - "document_count" => 70, + "document_count" => 71, "document_ids" => [ "app.bsky.actor.defs", "app.bsky.actor.getPreferences", @@ -18,6 +18,7 @@ defmodule Tempest.Lexicon.Bundled do "app.bsky.actor.putPreferences", "app.bsky.embed.defs", "app.bsky.embed.external", + "app.bsky.embed.gallery", "app.bsky.embed.images", "app.bsky.embed.record", "app.bsky.embed.recordWithMedia", @@ -1027,6 +1028,86 @@ defmodule Tempest.Lexicon.Bundled do "id" => "app.bsky.embed.external", "lexicon" => 1 }, + %{ + "defs" => %{ + "image" => %{ + "properties" => %{ + "alt" => %{ + "description" => "Alt text description of the image, for accessibility.", + "type" => "string" + }, + "aspectRatio" => %{ + "ref" => "app.bsky.embed.defs#aspectRatio", + "type" => "ref" + }, + "image" => %{ + "accept" => ["image/*"], + "maxSize" => 2_000_000, + "type" => "blob" + } + }, + "required" => ["image", "alt", "aspectRatio"], + "type" => "object" + }, + "main" => %{ + "properties" => %{ + "items" => %{ + "description" => + "The schema-level maxLength of 20 is a future-proof ceiling. Clients should currently enforce a soft limit of 10 items in authoring UIs.", + "items" => %{ + "description" => + "The media items in the gallery. Each item may be of a different type, but all types must be supported by the client.", + "refs" => ["#image"], + "type" => "union" + }, + "maxLength" => 20, + "type" => "array" + } + }, + "required" => ["items"], + "type" => "object" + }, + "view" => %{ + "properties" => %{ + "items" => %{ + "items" => %{"refs" => ["#viewImage"], "type" => "union"}, + "type" => "array" + } + }, + "required" => ["items"], + "type" => "object" + }, + "viewImage" => %{ + "properties" => %{ + "alt" => %{ + "description" => "Alt text description of the image, for accessibility.", + "type" => "string" + }, + "aspectRatio" => %{ + "ref" => "app.bsky.embed.defs#aspectRatio", + "type" => "ref" + }, + "fullsize" => %{ + "description" => + "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View.", + "format" => "uri", + "type" => "string" + }, + "thumbnail" => %{ + "description" => + "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View.", + "format" => "uri", + "type" => "string" + } + }, + "required" => ["thumbnail", "fullsize", "alt", "aspectRatio"], + "type" => "object" + } + }, + "description" => "An assortment of media embedded in a Bluesky record (eg, a post).", + "id" => "app.bsky.embed.gallery", + "lexicon" => 1 + }, %{ "defs" => %{ "image" => %{ @@ -1170,6 +1251,7 @@ defmodule Tempest.Lexicon.Bundled do "refs" => [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", "app.bsky.embed.external#view", "app.bsky.embed.record#view", "app.bsky.embed.recordWithMedia#view" @@ -1210,7 +1292,12 @@ defmodule Tempest.Lexicon.Bundled do "main" => %{ "properties" => %{ "media" => %{ - "refs" => ["app.bsky.embed.images", "app.bsky.embed.video", "app.bsky.embed.external"], + "refs" => [ + "app.bsky.embed.images", + "app.bsky.embed.video", + "app.bsky.embed.gallery", + "app.bsky.embed.external" + ], "type" => "union" }, "record" => %{"ref" => "app.bsky.embed.record", "type" => "ref"} @@ -1221,7 +1308,12 @@ defmodule Tempest.Lexicon.Bundled do "view" => %{ "properties" => %{ "media" => %{ - "refs" => ["app.bsky.embed.images#view", "app.bsky.embed.video#view", "app.bsky.embed.external#view"], + "refs" => [ + "app.bsky.embed.images#view", + "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", + "app.bsky.embed.external#view" + ], "type" => "union" }, "record" => %{"ref" => "app.bsky.embed.record#view", "type" => "ref"} @@ -1502,6 +1594,7 @@ defmodule Tempest.Lexicon.Bundled do "refs" => [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", "app.bsky.embed.external#view", "app.bsky.embed.record#view", "app.bsky.embed.recordWithMedia#view" @@ -3044,21 +3137,8 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Import a repository CAR for the authenticated account.", - "errors" => [%{"name" => "InvalidRequest"}], + "description" => "Import a repo in the form of a CAR file. Requires Content-Length HTTP header to be set.", "input" => %{"encoding" => "application/vnd.ipld.car"}, - "output" => %{ - "encoding" => "application/json", - "schema" => %{ - "properties" => %{ - "cid" => %{"format" => "cid", "type" => "string"}, - "recordCount" => %{"type" => "integer"}, - "rev" => %{"format" => "tid", "type" => "string"} - }, - "required" => ["cid", "rev"], - "type" => "object" - } - }, "type" => "procedure" } }, @@ -3068,19 +3148,14 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "List blob CIDs referenced by the authenticated repo but missing from local storage.", + "description" => + "Returns a list of missing blobs for the requesting account. Intended to be used in the account migration flow.", "output" => %{ "encoding" => "application/json", "schema" => %{ "properties" => %{ "blobs" => %{ - "items" => %{ - "properties" => %{ - "cid" => %{"format" => "cid", "type" => "string"} - }, - "required" => ["cid"], - "type" => "object" - }, + "items" => %{"ref" => "#recordBlob", "type" => "ref"}, "type" => "array" }, "cursor" => %{"type" => "string"} @@ -3092,11 +3167,24 @@ defmodule Tempest.Lexicon.Bundled do "parameters" => %{ "properties" => %{ "cursor" => %{"type" => "string"}, - "limit" => %{"maximum" => 1000, "minimum" => 1, "type" => "integer"} + "limit" => %{ + "default" => 500, + "maximum" => 1000, + "minimum" => 1, + "type" => "integer" + } }, "type" => "params" }, "type" => "query" + }, + "recordBlob" => %{ + "properties" => %{ + "cid" => %{"format" => "cid", "type" => "string"}, + "recordUri" => %{"format" => "at-uri", "type" => "string"} + }, + "required" => ["cid", "recordUri"], + "type" => "object" } }, "id" => "com.atproto.repo.listMissingBlobs", @@ -3279,16 +3367,8 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Activate the authenticated account after migration checks pass.", - "errors" => [%{"name" => "InvalidRequest"}], - "input" => %{ - "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} - }, - "output" => %{ - "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} - }, + "description" => + "Activates a currently deactivated account. Used to finalize account migration after the account's repo is imported and identity is setup.", "type" => "procedure" } }, @@ -3298,21 +3378,33 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Get status information about the authenticated account.", + "description" => + "Returns the status of an account, especially as pertaining to import or recovery. Can be called many times over the course of an account migration. Requires auth and can only be called pertaining to oneself.", "output" => %{ "encoding" => "application/json", "schema" => %{ "properties" => %{ - "active" => %{"type" => "boolean"}, - "blobCount" => %{"type" => "integer"}, - "did" => %{"format" => "did", "type" => "string"}, - "migrationReady" => %{"type" => "boolean"}, - "missingBlobCount" => %{"type" => "integer"}, - "recordCount" => %{"type" => "integer"}, - "repoCount" => %{"type" => "integer"}, - "status" => %{"type" => "string"} + "activated" => %{"type" => "boolean"}, + "expectedBlobs" => %{"type" => "integer"}, + "importedBlobs" => %{"type" => "integer"}, + "indexedRecords" => %{"type" => "integer"}, + "privateStateValues" => %{"type" => "integer"}, + "repoBlocks" => %{"type" => "integer"}, + "repoCommit" => %{"format" => "cid", "type" => "string"}, + "repoRev" => %{"type" => "string"}, + "validDid" => %{"type" => "boolean"} }, - "required" => ["did", "active"], + "required" => [ + "activated", + "validDid", + "repoCommit", + "repoRev", + "repoBlocks", + "indexedRecords", + "privateStateValues", + "expectedBlobs", + "importedBlobs" + ], "type" => "object" } }, @@ -3525,14 +3617,21 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Deactivate the authenticated account and suppress public repo/blob serving.", + "description" => + "Deactivates a currently active account. Stops serving of repo, and future writes to repo until reactivated. Used to finalize account migration with the old host after the account has been activated on the new host.", "input" => %{ "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} - }, - "output" => %{ - "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} + "schema" => %{ + "properties" => %{ + "deleteAfter" => %{ + "description" => + "A recommendation to server as to how long they should hold onto the deactivated account before deleting.", + "format" => "datetime", + "type" => "string" + } + }, + "type" => "object" + } }, "type" => "procedure" } @@ -3543,14 +3642,20 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Mark the authenticated account deleted and revoke active sessions.", + "description" => + "Delete an actor's account with a token and password. Can only be called after requesting a deletion token. Requires auth.", + "errors" => [%{"name" => "ExpiredToken"}, %{"name" => "InvalidToken"}], "input" => %{ "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} - }, - "output" => %{ - "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} + "schema" => %{ + "properties" => %{ + "did" => %{"format" => "did", "type" => "string"}, + "password" => %{"type" => "string"}, + "token" => %{"type" => "string"} + }, + "required" => ["did", "password", "token"], + "type" => "object" + } }, "type" => "procedure" } @@ -3627,7 +3732,14 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Get a short-lived service-auth token for a constrained audience and Lexicon method.", + "description" => "Get a signed token on behalf of the requesting DID for the requested service.", + "errors" => [ + %{ + "description" => + "Indicates that the requested expiration date is not a valid. May be in the past or may be reliant on the requested scopes.", + "name" => "BadExpiration" + } + ], "output" => %{ "encoding" => "application/json", "schema" => %{ @@ -3638,14 +3750,24 @@ defmodule Tempest.Lexicon.Bundled do }, "parameters" => %{ "properties" => %{ - "aud" => %{"description" => "Token audience.", "type" => "string"}, + "aud" => %{ + "description" => + "The DID or `did#serviceId` reference of the service that the token will be used to authenticate with.", + "maxLength" => 2048, + "type" => "string" + }, + "exp" => %{ + "description" => + "The time in Unix Epoch seconds that the JWT expires. Defaults to 60 seconds in the future. The service may enforce certain time bounds on tokens depending on the requested scope.", + "type" => "integer" + }, "lxm" => %{ - "description" => "Lexicon method this token may be used with.", + "description" => "Lexicon (XRPC) method to bind the requested token to", "format" => "nsid", "type" => "string" } }, - "required" => ["aud", "lxm"], + "required" => ["aud"], "type" => "params" }, "type" => "query" @@ -3763,15 +3885,7 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Record an authenticated account deletion request.", - "input" => %{ - "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} - }, - "output" => %{ - "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} - }, + "description" => "Initiate a user account deletion via email.", "type" => "procedure" } }, @@ -3827,20 +3941,31 @@ defmodule Tempest.Lexicon.Bundled do %{ "defs" => %{ "main" => %{ - "description" => "Reserve or return stable signing-key material for the authenticated account.", + "description" => + "Reserve a repo signing key, for use with account creation. Necessary so that a DID PLC update operation can be constructed during an account migraiton. Public and does not require auth; implemented by PDS. NOTE: this endpoint may change when full account migration is implemented.", "input" => %{ "encoding" => "application/json", - "schema" => %{"properties" => %{}, "type" => "object"} + "schema" => %{ + "properties" => %{ + "did" => %{ + "description" => "The DID to reserve a key for.", + "format" => "did", + "type" => "string" + } + }, + "type" => "object" + } }, "output" => %{ "encoding" => "application/json", "schema" => %{ "properties" => %{ - "did" => %{"format" => "did", "type" => "string"}, - "signingKey" => %{"type" => "string"}, - "verificationMethod" => %{"type" => "string"} + "signingKey" => %{ + "description" => "The public key for the reserved signing key, in did:key serialization.", + "type" => "string" + } }, - "required" => ["did", "signingKey", "verificationMethod"], + "required" => ["signingKey"], "type" => "object" } }, diff --git a/lib/tempest/repo_storage.ex b/lib/tempest/repo_storage.ex index 6bc2d72..03da65f 100644 --- a/lib/tempest/repo_storage.ex +++ b/lib/tempest/repo_storage.ex @@ -423,10 +423,13 @@ defmodule Tempest.RepoStorage do result = with {:ok, records} <- scalar_count(conn, "SELECT COUNT(*) FROM records", []), {:ok, commits} <- scalar_count(conn, "SELECT COUNT(*) FROM commits", []), + {:ok, blocks} <- scalar_count(conn, "SELECT COUNT(*) FROM blocks", []), {:ok, referenced_cids} <- referenced_blob_cids_from_db(conn) do {:ok, %{ repo_count: if(commits > 0, do: 1, else: 0), + block_count: blocks, + commit_count: commits, record_count: records, referenced_blob_count: length(referenced_cids), referenced_blob_cids: referenced_cids diff --git a/priv/lexicons/official/app/bsky/embed/gallery.json b/priv/lexicons/official/app/bsky/embed/gallery.json new file mode 100644 index 0000000..916093d --- /dev/null +++ b/priv/lexicons/official/app/bsky/embed/gallery.json @@ -0,0 +1,79 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.gallery", + "description": "An assortment of media embedded in a Bluesky record (eg, a post).", + "defs": { + "main": { + "type": "object", + "required": ["items"], + "properties": { + "items": { + "type": "array", + "maxLength": 20, + "description": "The schema-level maxLength of 20 is a future-proof ceiling. Clients should currently enforce a soft limit of 10 items in authoring UIs.", + "items": { + "type": "union", + "refs": ["#image"], + "description": "The media items in the gallery. Each item may be of a different type, but all types must be supported by the client." + } + } + } + }, + "image": { + "type": "object", + "required": ["image", "alt", "aspectRatio"], + "properties": { + "image": { + "type": "blob", + "accept": ["image/*"], + "maxSize": 2000000 + }, + "alt": { + "type": "string", + "description": "Alt text description of the image, for accessibility." + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + }, + "view": { + "type": "object", + "required": ["items"], + "properties": { + "items": { + "type": "array", + "items": { + "type": "union", + "refs": ["#viewImage"] + } + } + } + }, + "viewImage": { + "type": "object", + "required": ["thumbnail", "fullsize", "alt", "aspectRatio"], + "properties": { + "thumbnail": { + "type": "string", + "format": "uri", + "description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View." + }, + "fullsize": { + "type": "string", + "format": "uri", + "description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View." + }, + "alt": { + "type": "string", + "description": "Alt text description of the image, for accessibility." + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + } + } +} diff --git a/priv/lexicons/official/app/bsky/embed/record.json b/priv/lexicons/official/app/bsky/embed/record.json index a73200a..4ca0f00 100644 --- a/priv/lexicons/official/app/bsky/embed/record.json +++ b/priv/lexicons/official/app/bsky/embed/record.json @@ -58,6 +58,7 @@ "refs": [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", "app.bsky.embed.external#view", "app.bsky.embed.record#view", "app.bsky.embed.recordWithMedia#view" diff --git a/priv/lexicons/official/app/bsky/embed/recordWithMedia.json b/priv/lexicons/official/app/bsky/embed/recordWithMedia.json index 5baf685..edd7650 100644 --- a/priv/lexicons/official/app/bsky/embed/recordWithMedia.json +++ b/priv/lexicons/official/app/bsky/embed/recordWithMedia.json @@ -16,6 +16,7 @@ "refs": [ "app.bsky.embed.images", "app.bsky.embed.video", + "app.bsky.embed.gallery", "app.bsky.embed.external" ] } @@ -34,6 +35,7 @@ "refs": [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", "app.bsky.embed.external#view" ] } diff --git a/priv/lexicons/official/app/bsky/feed/defs.json b/priv/lexicons/official/app/bsky/feed/defs.json index 0a19cf3..5e46243 100644 --- a/priv/lexicons/official/app/bsky/feed/defs.json +++ b/priv/lexicons/official/app/bsky/feed/defs.json @@ -18,6 +18,7 @@ "refs": [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", "app.bsky.embed.external#view", "app.bsky.embed.record#view", "app.bsky.embed.recordWithMedia#view" diff --git a/priv/lexicons/official/com/atproto/repo/importRepo.json b/priv/lexicons/official/com/atproto/repo/importRepo.json index 29e97c5..fc850b1 100644 --- a/priv/lexicons/official/com/atproto/repo/importRepo.json +++ b/priv/lexicons/official/com/atproto/repo/importRepo.json @@ -4,21 +4,10 @@ "defs": { "main": { "type": "procedure", - "description": "Import a repository CAR for the authenticated account.", - "input": { "encoding": "application/vnd.ipld.car" }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["cid", "rev"], - "properties": { - "cid": { "type": "string", "format": "cid" }, - "rev": { "type": "string", "format": "tid" }, - "recordCount": { "type": "integer" } - } - } - }, - "errors": [{ "name": "InvalidRequest" }] + "description": "Import a repo in the form of a CAR file. Requires Content-Length HTTP header to be set.", + "input": { + "encoding": "application/vnd.ipld.car" + } } } } diff --git a/priv/lexicons/official/com/atproto/repo/listMissingBlobs.json b/priv/lexicons/official/com/atproto/repo/listMissingBlobs.json index 83651d3..c39913d 100644 --- a/priv/lexicons/official/com/atproto/repo/listMissingBlobs.json +++ b/priv/lexicons/official/com/atproto/repo/listMissingBlobs.json @@ -4,11 +4,16 @@ "defs": { "main": { "type": "query", - "description": "List blob CIDs referenced by the authenticated repo but missing from local storage.", + "description": "Returns a list of missing blobs for the requesting account. Intended to be used in the account migration flow.", "parameters": { "type": "params", "properties": { - "limit": { "type": "integer", "minimum": 1, "maximum": 1000 }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 1000, + "default": 500 + }, "cursor": { "type": "string" } } }, @@ -18,18 +23,22 @@ "type": "object", "required": ["blobs"], "properties": { + "cursor": { "type": "string" }, "blobs": { "type": "array", - "items": { - "type": "object", - "required": ["cid"], - "properties": { "cid": { "type": "string", "format": "cid" } } - } - }, - "cursor": { "type": "string" } + "items": { "type": "ref", "ref": "#recordBlob" } + } } } } + }, + "recordBlob": { + "type": "object", + "required": ["cid", "recordUri"], + "properties": { + "cid": { "type": "string", "format": "cid" }, + "recordUri": { "type": "string", "format": "at-uri" } + } } } } diff --git a/priv/lexicons/official/com/atproto/server/activateAccount.json b/priv/lexicons/official/com/atproto/server/activateAccount.json index e314840..e06935f 100644 --- a/priv/lexicons/official/com/atproto/server/activateAccount.json +++ b/priv/lexicons/official/com/atproto/server/activateAccount.json @@ -4,10 +4,7 @@ "defs": { "main": { "type": "procedure", - "description": "Activate the authenticated account after migration checks pass.", - "input": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, - "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, - "errors": [{ "name": "InvalidRequest" }] + "description": "Activates a currently deactivated account. Used to finalize account migration after the account's repo is imported and identity is setup." } } } diff --git a/priv/lexicons/official/com/atproto/server/checkAccountStatus.json b/priv/lexicons/official/com/atproto/server/checkAccountStatus.json index 666faa1..d34596e 100644 --- a/priv/lexicons/official/com/atproto/server/checkAccountStatus.json +++ b/priv/lexicons/official/com/atproto/server/checkAccountStatus.json @@ -4,21 +4,32 @@ "defs": { "main": { "type": "query", - "description": "Get status information about the authenticated account.", + "description": "Returns the status of an account, especially as pertaining to import or recovery. Can be called many times over the course of an account migration. Requires auth and can only be called pertaining to oneself.", "output": { "encoding": "application/json", "schema": { "type": "object", - "required": ["did", "active"], + "required": [ + "activated", + "validDid", + "repoCommit", + "repoRev", + "repoBlocks", + "indexedRecords", + "privateStateValues", + "expectedBlobs", + "importedBlobs" + ], "properties": { - "did": { "type": "string", "format": "did" }, - "active": { "type": "boolean" }, - "status": { "type": "string" }, - "repoCount": { "type": "integer" }, - "recordCount": { "type": "integer" }, - "blobCount": { "type": "integer" }, - "missingBlobCount": { "type": "integer" }, - "migrationReady": { "type": "boolean" } + "activated": { "type": "boolean" }, + "validDid": { "type": "boolean" }, + "repoCommit": { "type": "string", "format": "cid" }, + "repoRev": { "type": "string" }, + "repoBlocks": { "type": "integer" }, + "indexedRecords": { "type": "integer" }, + "privateStateValues": { "type": "integer" }, + "expectedBlobs": { "type": "integer" }, + "importedBlobs": { "type": "integer" } } } } diff --git a/priv/lexicons/official/com/atproto/server/deactivateAccount.json b/priv/lexicons/official/com/atproto/server/deactivateAccount.json index 9722896..698fccf 100644 --- a/priv/lexicons/official/com/atproto/server/deactivateAccount.json +++ b/priv/lexicons/official/com/atproto/server/deactivateAccount.json @@ -4,9 +4,20 @@ "defs": { "main": { "type": "procedure", - "description": "Deactivate the authenticated account and suppress public repo/blob serving.", - "input": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, - "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } + "description": "Deactivates a currently active account. Stops serving of repo, and future writes to repo until reactivated. Used to finalize account migration with the old host after the account has been activated on the new host.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "deleteAfter": { + "type": "string", + "format": "datetime", + "description": "A recommendation to server as to how long they should hold onto the deactivated account before deleting." + } + } + } + } } } } diff --git a/priv/lexicons/official/com/atproto/server/deleteAccount.json b/priv/lexicons/official/com/atproto/server/deleteAccount.json index f0140d0..cf4babf 100644 --- a/priv/lexicons/official/com/atproto/server/deleteAccount.json +++ b/priv/lexicons/official/com/atproto/server/deleteAccount.json @@ -4,9 +4,20 @@ "defs": { "main": { "type": "procedure", - "description": "Mark the authenticated account deleted and revoke active sessions.", - "input": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, - "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } + "description": "Delete an actor's account with a token and password. Can only be called after requesting a deletion token. Requires auth.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["did", "password", "token"], + "properties": { + "did": { "type": "string", "format": "did" }, + "password": { "type": "string" }, + "token": { "type": "string" } + } + } + }, + "errors": [{ "name": "ExpiredToken" }, { "name": "InvalidToken" }] } } } diff --git a/priv/lexicons/official/com/atproto/server/getServiceAuth.json b/priv/lexicons/official/com/atproto/server/getServiceAuth.json index 648e940..e0c6947 100644 --- a/priv/lexicons/official/com/atproto/server/getServiceAuth.json +++ b/priv/lexicons/official/com/atproto/server/getServiceAuth.json @@ -4,19 +4,45 @@ "defs": { "main": { "type": "query", - "description": "Get a short-lived service-auth token for a constrained audience and Lexicon method.", + "description": "Get a signed token on behalf of the requesting DID for the requested service.", "parameters": { "type": "params", - "required": ["aud", "lxm"], + "required": ["aud"], "properties": { - "aud": { "type": "string", "description": "Token audience." }, - "lxm": { "type": "string", "format": "nsid", "description": "Lexicon method this token may be used with." } + "aud": { + "type": "string", + "maxLength": 2048, + "description": "The DID or `did#serviceId` reference of the service that the token will be used to authenticate with." + }, + "exp": { + "type": "integer", + "description": "The time in Unix Epoch seconds that the JWT expires. Defaults to 60 seconds in the future. The service may enforce certain time bounds on tokens depending on the requested scope." + }, + "lxm": { + "type": "string", + "format": "nsid", + "description": "Lexicon (XRPC) method to bind the requested token to" + } } }, "output": { "encoding": "application/json", - "schema": { "type": "object", "required": ["token"], "properties": { "token": { "type": "string" } } } - } + "schema": { + "type": "object", + "required": ["token"], + "properties": { + "token": { + "type": "string" + } + } + } + }, + "errors": [ + { + "name": "BadExpiration", + "description": "Indicates that the requested expiration date is not a valid. May be in the past or may be reliant on the requested scopes." + } + ] } } } diff --git a/priv/lexicons/official/com/atproto/server/requestAccountDelete.json b/priv/lexicons/official/com/atproto/server/requestAccountDelete.json index 228dcc0..aaac0b7 100644 --- a/priv/lexicons/official/com/atproto/server/requestAccountDelete.json +++ b/priv/lexicons/official/com/atproto/server/requestAccountDelete.json @@ -4,9 +4,7 @@ "defs": { "main": { "type": "procedure", - "description": "Record an authenticated account deletion request.", - "input": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, - "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } + "description": "Initiate a user account deletion via email." } } } diff --git a/priv/lexicons/official/com/atproto/server/reserveSigningKey.json b/priv/lexicons/official/com/atproto/server/reserveSigningKey.json index 1cd1100..a33e1ed 100644 --- a/priv/lexicons/official/com/atproto/server/reserveSigningKey.json +++ b/priv/lexicons/official/com/atproto/server/reserveSigningKey.json @@ -4,17 +4,30 @@ "defs": { "main": { "type": "procedure", - "description": "Reserve or return stable signing-key material for the authenticated account.", - "input": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, + "description": "Reserve a repo signing key, for use with account creation. Necessary so that a DID PLC update operation can be constructed during an account migraiton. Public and does not require auth; implemented by PDS. NOTE: this endpoint may change when full account migration is implemented.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "did": { + "type": "string", + "format": "did", + "description": "The DID to reserve a key for." + } + } + } + }, "output": { "encoding": "application/json", "schema": { "type": "object", - "required": ["did", "signingKey", "verificationMethod"], + "required": ["signingKey"], "properties": { - "did": { "type": "string", "format": "did" }, - "signingKey": { "type": "string" }, - "verificationMethod": { "type": "string" } + "signingKey": { + "type": "string", + "description": "The public key for the reserved signing key, in did:key serialization." + } } } } -- 2.51.2