diff --git a/src/keria/app/aiding.py b/src/keria/app/aiding.py index a8bfbc20..2a8f08d9 100644 --- a/src/keria/app/aiding.py +++ b/src/keria/app/aiding.py @@ -654,16 +654,16 @@ def on_get(req, rep, name): --- summary: Retrieve an identifier. - description: This endpoint retrieves an identifier by its human-readable name. + description: This endpoint retrieves an identifier by its prefix or human-readable name. tags: - Identifier parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: The human-readable name of the identifier. + description: The human-readable name of the identifier or its prefix. responses: 200: description: Successfully retrieved the identifier details. @@ -676,10 +676,10 @@ def on_get(req, rep, name): raise falcon.HTTPBadRequest(description="name is required") agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: raise falcon.HTTPNotFound( - description=f"{name} is not a valid identifier name" + description=f"{name} is not a valid identifier name or prefix" ) data = info(hab, agent.mgr, full=True) @@ -693,7 +693,7 @@ def on_put(self, req, rep, name): Parameters: req (Request): falcon.Request HTTP request object rep (Response): falcon.Response HTTP response object - name (str): human readable name for Hab to rename + name (str): human readable name for Hab to rename or its prefix --- summary: Rename an identifier. @@ -702,11 +702,11 @@ def on_put(self, req, rep, name): - Identifier parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: The current human-readable name of the identifier. + description: The current human-readable name of the identifier or its prefix. requestBody: content: application/json: @@ -715,7 +715,7 @@ def on_put(self, req, rep, name): properties: name: type: string - description: The new name for the identifier. + description: The new human-readable name for the identifier. required: - name responses: @@ -729,17 +729,18 @@ def on_put(self, req, rep, name): if not name: raise falcon.HTTPBadRequest(description="name is required") agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(title=f"No AID with name {name} found") + raise falcon.HTTPNotFound(title=f"No AID with name or prefix {name} found") body = req.get_media() newName = body.get("name") habord = hab.db.habs.get(keys=(hab.pre,)) + oldName = habord.name habord.name = newName hab.db.habs.pin(keys=(hab.pre,), val=habord) hab.db.names.pin(keys=("", newName), val=hab.pre) - hab.db.names.rem(keys=("", name)) + hab.db.names.rem(keys=("", oldName)) hab.name = newName hab = agent.hby.habByName(newName) data = info(hab, agent.mgr, full=True) @@ -753,7 +754,7 @@ def on_post(self, req, rep, name): Parameters: req (Request): falcon.Request HTTP request object rep (Response): falcon.Response HTTP response object - name (str): human-readable name for Hab to rotate or interact + name (str): human-readable name or prefix for Hab to rotate or interact --- summary: Process identifier events. @@ -762,11 +763,11 @@ def on_post(self, req, rep, name): - Identifier parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: The human-readable name of the identifier. + description: The human-readable name of the identifier or its prefix. requestBody: content: application/json: @@ -821,9 +822,9 @@ def on_post(self, req, rep, name): @staticmethod def rotate(agent, name, body): - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(title=f"No AID with name {name} found") + raise falcon.HTTPNotFound(title=f"No AID with name or prefix {name} found") rot = body.get("rot") if rot is None: @@ -918,7 +919,7 @@ def rotate(agent, name, body): @staticmethod def interact(agent, name, body): - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: raise falcon.HTTPNotFound(title=f"No AID {name} found") @@ -1024,7 +1025,7 @@ def on_get(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human-readable name for Hab to GET + name (str): human-readable name or prefix for Hab to GET --- summary: Fetch OOBI URLs of an identifier. description: This endpoint fetches the OOBI URLs for a specific role associated with an identifier. @@ -1032,11 +1033,11 @@ def on_get(req, rep, name): - Identifier parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: The human-readable name of the identifier. + description: The human-readable name of the identifier or its prefix. - in: query name: role schema: @@ -1055,9 +1056,9 @@ def on_get(req, rep, name): if not name: raise falcon.HTTPBadRequest(description="name is required") - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if not hab: - raise falcon.HTTPNotFound(description="invalid alias {name}") + raise falcon.HTTPNotFound(description="invalid alias or prefix {name}") if "role" not in req.params: raise falcon.HTTPBadRequest(description="role parameter required") @@ -1177,23 +1178,24 @@ def on_get(req, rep, name=None, aid=None, role=None): Parameters: req (Request): falcon HTTP request object rep (Response): falcon HTTP response object - name (str): human readable alias for AID + name (str): human readable alias or prefix for AID + aid (str): aid to use instead of name aid (str): aid to use instead of name role (str): optional role to search for --- summary: Retrieve end roles. - description: This endpoint retrieves the end roles associated with AID or human-readable name. + description: This endpoint retrieves the end roles associated with an identifier prefix or human-readable name. It can also filter the end roles based on a specific role. tags: - End Role parameters: - in: path - name: name + name: name or prefix schema: type: string required: false - description: The human-readable name of the identifier. + description: The human-readable name of the identifier or its prefix. - in: path name: aid schema: @@ -1217,15 +1219,15 @@ def on_get(req, rep, name=None, aid=None, role=None): agent = req.context.agent if name is not None: - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.errors.HTTPNotFound(description=f"invalid alias {name}") + raise falcon.errors.HTTPNotFound(description=f"invalid alias or prefix {name}") pre = hab.pre elif aid is not None: pre = aid else: raise falcon.HTTPBadRequest( - description="either `aid` or `name` are required in the path" + description="name or prefix is required in the path" ) if role is not None: @@ -1251,22 +1253,22 @@ def on_post(req, rep, name, aid=None, role=None): Args: req (Request): Falcon HTTP request object rep (Response): Falcon HTTP response object - name (str): human readable alias for AID + name (str): human readable alias or prefix for identifier aid (str): Not supported for POST. If provided, a 404 is returned role (str): Not supported for POST. If provided, a 404 is returned --- summary: Create an end role. - description: This endpoint creates an end role associated with a given identifier (AID) or name. + description: This endpoint creates an end role associated with a given identifier prefix or human-readable name. tags: - End Role parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: The human-readable name of the identifier. + description: The human-readable name of the identifier or its prefix. - in: path name: aid schema: @@ -1310,9 +1312,9 @@ def on_post(req, rep, name, aid=None, role=None): role = data["role"] eid = data["eid"] - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.errors.HTTPNotFound(description=f"invalid alias {name}") + raise falcon.errors.HTTPNotFound(description=f"invalid alias or prefix {name}") if pre != hab.pre: raise falcon.errors.HTTPBadRequest( @@ -1451,7 +1453,7 @@ def on_post(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name: human readable name of identifier to use to sign the challenge/response + name: human readable name or prefix of identifier to use to sign the challenge/response --- summary: Sign challenge message and forward to peer identifier @@ -1461,11 +1463,11 @@ def on_post(req, rep, name): - Challenge/Response parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: Human readable alias for the identifier to create + description: Human readable alias or prefix for the identifier to create requestBody: required: true content: @@ -1486,9 +1488,9 @@ def on_post(req, rep, name): description: Success submission of signed challenge/response """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPBadRequest(description="no matching Hab for alias {name}") + raise falcon.HTTPBadRequest(description="no matching Hab for alias or prefix {name}") body = req.get_media() if "exn" not in body or "sig" not in body or "recipient" not in body: @@ -2057,7 +2059,7 @@ def on_get(req, rep, name): Parameters: req (falcon.Request): The request object. rep (falcon.Response): The response object. - name (str): The human-readable name of the identifier. + name (str): The human-readable name or prefix of the identifier. --- summary: Fetch group member information. @@ -2066,11 +2068,11 @@ def on_get(req, rep, name): - Group Member parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: The human-readable name of the identifier. + description: The human-readable name of the identifier or its prefix. responses: 200: description: Successfully fetched the group member information. @@ -2081,9 +2083,9 @@ def on_get(req, rep, name): """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.errors.HTTPNotFound(description=f"invalid alias {name}") + raise falcon.errors.HTTPNotFound(description=f"invalid alias or prefix {name}") if not isinstance(hab, habbing.SignifyGroupHab): raise falcon.HTTPBadRequest( diff --git a/src/keria/app/credentialing.py b/src/keria/app/credentialing.py index 62bdba77..acc7230c 100644 --- a/src/keria/app/credentialing.py +++ b/src/keria/app/credentialing.py @@ -66,7 +66,7 @@ def on_get(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID --- summary: List credential issuance and revocation registies @@ -80,9 +80,9 @@ def on_get(req, rep, name): """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description="name is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") res = [] for name, registry in agent.rgy.regs.items(): @@ -108,7 +108,7 @@ def on_post(self, req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): AID of Hab to load credentials for + name (str): human readable name or prefix of Hab to load credentials for --- summary: Request to create a credential issuance and revocation registry @@ -163,9 +163,9 @@ def on_post(self, req, rep, name): ked = httping.getRequiredParam(body, "ixn") ixn = serdering.SerderKERI(sad=ked) - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description="alias is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") if agent.rgy.registryByName(name=rname) is not None: raise falcon.HTTPBadRequest(description=f"registry name {rname} already in use") @@ -199,7 +199,7 @@ def on_get(req, rep, name, registryName): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID registryName(str): human readable name for registry --- @@ -228,7 +228,7 @@ def on_get(req, rep, name, registryName): """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") @@ -256,7 +256,7 @@ def on_put(req, rep, name, registryName): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID registryName(str): human readable name for registry or its SAID --- @@ -296,7 +296,7 @@ def on_put(req, rep, name, registryName): """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") @@ -514,7 +514,7 @@ def on_post(self, req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable alias for AID to use as issuer + name (str): human readable alias or prefix for AID to use as issuer --- summary: Perform credential issuance @@ -523,11 +523,11 @@ def on_post(self, req, rep, name): - Credentials parameters: - in: path - name: alias + name: alias or prefix schema: type: string required: true - description: Human readable alias for the identifier to create + description: Human readable alias or prefix for the identifier to create requestBody: required: true content: @@ -576,9 +576,9 @@ def on_post(self, req, rep, name): agent = req.context.agent body = req.get_media() - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description="name is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") try: creder = serdering.SerderACDC(sad=httping.getRequiredParam(body, "acdc")) iserder = serdering.SerderKERI(sad=httping.getRequiredParam(body, "iss")) @@ -737,7 +737,7 @@ def on_delete(self, req, rep, name, said): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable alias for AID to use as issuer + name (str): human readable alias or prefix for AID to use as issuer said (str): SAID of credential to revoke RequestBody: @@ -752,11 +752,11 @@ def on_delete(self, req, rep, name, said): - Credentials parameters: - in: path - name: name + name: name or prefix schema: type: string required: true - description: The human-readable alias for the AID to use as issuer. + description: The human-readable alias or prefix for the AID to use as issuer. - in: path name: said schema: @@ -795,9 +795,9 @@ def on_delete(self, req, rep, name, said): agent = req.context.agent body = req.get_media() - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description="name is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") rserder = serdering.SerderKERI(sad=httping.getRequiredParam(body, "rev")) diff --git a/src/keria/app/delegating.py b/src/keria/app/delegating.py index da624ed4..797d19b3 100644 --- a/src/keria/app/delegating.py +++ b/src/keria/app/delegating.py @@ -197,16 +197,16 @@ def on_post(self, req, rep, name): Parameters: req (Request): falcon.Request HTTP request object rep (Response): falcon.Response HTTP response object - name (str): human readable name for Hab to rename + name (str): human readable name or prefix for Hab to rename """ if not name: raise falcon.HTTPBadRequest(description="name is required") agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(title=f"No AID with name {name} found") + raise falcon.HTTPNotFound(title=f"No AID with name or prefix {name} found") body = req.get_media() anc = httping.getRequiredParam(body, "ixn") diff --git a/src/keria/app/grouping.py b/src/keria/app/grouping.py index b6946525..cfa34722 100644 --- a/src/keria/app/grouping.py +++ b/src/keria/app/grouping.py @@ -36,7 +36,7 @@ def on_post(req, rep, name): Parameters: req (falcon.Request): HTTP request object rep (falcon.Response): HTTP response object - name (str): AID of Hab to load credentials for + name (str): AID prefix or human-readable name of Hab to load credentials for """ agent = req.context.agent @@ -44,13 +44,13 @@ def on_post(req, rep, name): body = req.get_media() # Get the hab - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description=f"alias={name} is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"alias or prefix {name} is not a valid reference to an identifier") # ...and make sure we're a Group if not isinstance(hab, habbing.SignifyGroupHab): - raise falcon.HTTPBadRequest(description=f"hab for alias {name} is not a multisig") + raise falcon.HTTPBadRequest(description=f"hab for alias or prefix {name} is not a multisig") # grab all of the required parameters ked = httping.getRequiredParam(body, "exn") @@ -93,7 +93,7 @@ def on_post(req, rep, name): Parameters: req (falcon.Request): HTTP request object rep (falcon.Response): HTTP response object - name (str): AID of Hab to load credentials for + name (str): AID prefix or human-readable name of Hab to load credentials for --- summary: Create a multisig group request. description: This endpoint creates a multisig request based on the provided name. @@ -101,7 +101,7 @@ def on_post(req, rep, name): - Multisig Request parameters: - in: path - name: name + name: name or prefix schema: type: string required: true @@ -144,9 +144,9 @@ def on_post(req, rep, name): agent = req.context.agent # Get the hab - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is not None: - raise falcon.HTTPBadRequest(description=f"attempt to create identifier with an already used alias={name}") + raise falcon.HTTPBadRequest(description=f"attempt to create identifier with an already used alias or prefix {name}") agent = req.context.agent body = req.get_media() @@ -169,7 +169,7 @@ def on_post(req, rep, name): both = list(set(smids + (rmids or []))) for recp in both: # Have to verify we already know all the recipients. if recp not in agent.hby.kevers: - agent.hby.deleteHab(name=name) + agent.hby.deleteHab(name=hab.name) raise falcon.HTTPBadRequest(description=f"attempt to merge with unknown AID={recp}") sigers = [core.Siger(qb64=sig) for sig in sigs] diff --git a/src/keria/app/ipexing.py b/src/keria/app/ipexing.py index 6762bd67..ad975a65 100644 --- a/src/keria/app/ipexing.py +++ b/src/keria/app/ipexing.py @@ -38,7 +38,7 @@ def on_post(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID --- summary: Accept a credential being issued or presented in response to an IPEX grant @@ -52,9 +52,9 @@ def on_post(req, rep, name): """ agent = req.context.agent # Get the hab - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description=f"alias={name} is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") body = req.get_media() @@ -167,7 +167,7 @@ def on_post(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID --- summary: Reply to IPEX agree message or initiate an IPEX exchange with a credential issuance or presentation @@ -180,9 +180,9 @@ def on_post(req, rep, name): """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description=f"alias={name} is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") body = req.get_media() @@ -289,7 +289,7 @@ def on_post(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID --- summary: Request a credential from another party by initiating an IPEX exchange @@ -303,9 +303,9 @@ def on_post(req, rep, name): """ agent = req.context.agent # Get the hab - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description=f"alias={name} is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") body = req.get_media() @@ -403,7 +403,7 @@ def on_post(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID --- summary: Reply to IPEX apply message or initiate an IPEX exchange with an offer for a credential with certain characteristics @@ -416,9 +416,9 @@ def on_post(req, rep, name): """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description=f"alias={name} is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") body = req.get_media() @@ -521,7 +521,7 @@ def on_post(req, rep, name): Parameters: req: falcon.Request HTTP request rep: falcon.Response HTTP response - name (str): human readable name for AID + name (str): human readable name or prefix for AID --- summary: Reply to IPEX offer message acknowledged willingness to accept offered credential @@ -534,9 +534,9 @@ def on_post(req, rep, name): """ agent = req.context.agent - hab = agent.hby.habByName(name) + hab = agent.hby.habs[name] if name in agent.hby.habs else agent.hby.habByName(name) if hab is None: - raise falcon.HTTPNotFound(description=f"alias={name} is not a valid reference to an identifier") + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") body = req.get_media() diff --git a/tests/app/test_aiding.py b/tests/app/test_aiding.py index b66f7199..dc4a3789 100644 --- a/tests/app/test_aiding.py +++ b/tests/app/test_aiding.py @@ -858,7 +858,7 @@ def test_identifier_collection_end(helpers): } res = client.simulate_post(path="/identifiers/randybad/events", body=json.dumps(body)) assert res.status_code == 404 - assert res.json == {'title': 'No AID with name randybad found'} + assert res.json == {'title': 'No AID with name or prefix randybad found'} body = { 'sigs': sigers, @@ -1333,12 +1333,16 @@ def test_identifier_resource_end(helpers): res = client.simulate_get(path="/identifiers/bad") assert res.status_code == 404 - assert res.json == {'description': 'bad is not a valid identifier name', 'title': '404 Not Found'} + assert res.json == {'description': 'bad is not a valid identifier name or prefix', 'title': '404 Not Found'} res = client.simulate_get(path="/identifiers/aid1") assert res.status_code == 200 assert res.json['prefix'] == 'EHgwVwQT15OJvilVvW57HE4w0-GPs_Stj2OFoAHZSysY' + res = client.simulate_get(path="/identifiers/EHgwVwQT15OJvilVvW57HE4w0-GPs_Stj2OFoAHZSysY") + assert res.status_code == 200 + assert res.json['prefix'] == 'EHgwVwQT15OJvilVvW57HE4w0-GPs_Stj2OFoAHZSysY' + def test_oobi_ends(helpers): with helpers.openKeria() as (agency, agent, app, client): diff --git a/tests/app/test_credentialing.py b/tests/app/test_credentialing.py index c4efb06d..6d0d6813 100644 --- a/tests/app/test_credentialing.py +++ b/tests/app/test_credentialing.py @@ -161,7 +161,7 @@ def test_registry_end(helpers, seeder): body = dict(name="test", alias="test", vcp=regser.ked, ixn=serder.ked, sigs=sigers) result = client.simulate_post(path="/identifiers/bad_test/registries", body=json.dumps(body).encode("utf-8")) assert result.status == falcon.HTTP_404 - assert result.json == {'description': 'alias is not a valid reference to an identifier', + assert result.json == {'description': 'bad_test is not a valid reference to an identifier', 'title': '404 Not Found'} # Try with bad identifier name @@ -199,7 +199,7 @@ def test_registry_end(helpers, seeder): result = client.simulate_get(path="/identifiers/not_test/registries") assert result.status == falcon.HTTP_404 - assert result.json == {'description': 'name is not a valid reference to an identifier', 'title': '404 Not Found'} + assert result.json == {'description': 'not_test is not a valid reference to an identifier', 'title': '404 Not Found'} # Test Operation Resource result = client.simulate_get(path=f"/operations/{op['name']}") @@ -291,7 +291,7 @@ def test_issue_credential(helpers, seeder): result = client.simulate_post(path="/identifiers/badname/credentials", body=json.dumps(body).encode("utf-8")) assert result.status_code == 404 - assert result.json == {'description': "name is not a valid reference to an identifier", + assert result.json == {'description': "badname is not a valid reference to an identifier", 'title': '404 Not Found'} result = client.simulate_post(path="/identifiers/issuer/credentials", body=json.dumps(body).encode("utf-8")) @@ -511,7 +511,7 @@ def test_revoke_credential(helpers, seeder): result = client.simulate_post(path="/identifiers/badname/credentials", body=json.dumps(body).encode("utf-8")) assert result.status_code == 404 - assert result.json == {'description': "name is not a valid reference to an identifier", + assert result.json == {'description': "badname is not a valid reference to an identifier", 'title': '404 Not Found'} result = client.simulate_post(path="/identifiers/issuer/credentials", body=json.dumps(body).encode("utf-8")) @@ -547,7 +547,7 @@ def test_revoke_credential(helpers, seeder): sigs=sigers) res = client.simulate_delete(path=f"/identifiers/badname/credentials/{creder.said}", body=json.dumps(body).encode("utf-8")) assert res.status_code == 404 - assert res.json == {'description': "name is not a valid reference to an identifier", + assert res.json == {'description': "badname is not a valid reference to an identifier", 'title': '404 Not Found'} res = client.simulate_delete(path=f"/identifiers/issuer/credentials/{regser.said}", body=json.dumps(body).encode("utf-8")) diff --git a/tests/app/test_grouping.py b/tests/app/test_grouping.py index 0d9e0acd..aa022e76 100644 --- a/tests/app/test_grouping.py +++ b/tests/app/test_grouping.py @@ -298,6 +298,6 @@ def make(self, serder, sigers): res = client.simulate_post("/identifiers/mms/multisig/join", json=body) assert res.status_code == 400 assert res.json == { - "description": "attempt to create identifier with an already used alias=mms", + "description": "attempt to create identifier with an already used alias or prefix mms", "title": "400 Bad Request", } diff --git a/tests/app/test_ipexing.py b/tests/app/test_ipexing.py index f878eaef..ab2f1828 100644 --- a/tests/app/test_ipexing.py +++ b/tests/app/test_ipexing.py @@ -1504,7 +1504,7 @@ def test_ipex_apply(helpers, mockHelpingNowIso8601): data = json.dumps(body).encode("utf-8") res = client.simulate_post(path="/identifiers/BAD/ipex/apply", body=data) assert res.status_code == 404 - assert res.json == {'description': 'alias=BAD is not a valid reference to an identifier', + assert res.json == {'description': 'BAD is not a valid reference to an identifier', 'title': '404 Not Found'} data = json.dumps(body).encode("utf-8") @@ -1623,7 +1623,7 @@ def test_ipex_offer(helpers, mockHelpingNowIso8601): data = json.dumps(body).encode("utf-8") res = client.simulate_post(path="/identifiers/BAD/ipex/offer", body=data) assert res.status_code == 404 - assert res.json == {'description': 'alias=BAD is not a valid reference to an identifier', + assert res.json == {'description': 'BAD is not a valid reference to an identifier', 'title': '404 Not Found'} data = json.dumps(body).encode("utf-8") @@ -1780,7 +1780,7 @@ def test_ipex_agree(helpers, mockHelpingNowIso8601): data = json.dumps(body).encode("utf-8") res = client.simulate_post(path="/identifiers/BAD/ipex/agree", body=data) assert res.status_code == 404 - assert res.json == {'description': 'alias=BAD is not a valid reference to an identifier', + assert res.json == {'description': 'BAD is not a valid reference to an identifier', 'title': '404 Not Found'} data = json.dumps(body).encode("utf-8") diff --git a/tests/app/test_specing.py b/tests/app/test_specing.py index 46dce1d1..0e82b079 100644 --- a/tests/app/test_specing.py +++ b/tests/app/test_specing.py @@ -51,5 +51,4 @@ def test_spec_resource(helpers): js = json.dumps(sd) print(js) # Assert on the entire JSON to ensure we are getting all the docs - assert js == '{"paths": {"/operations": {"get": {"summary": "Get list of long running operations", "parameters": [{"in": "query", "name": "type", "schema": {"type": "string"}, "required": false, "description": "filter list of long running operations by type"}], "responses": {"200": {"description": "list of long running operations", "content": {"application/json": {"schema": {"type": "array", "items": {"properties": {"name": {"type": "string"}, "metadata": {"type": "object"}, "done": {"type": "boolean"}, "error": {"type": "object"}, "response": {"type": "object"}}}}}}}}}}, "/oobis": {"post": {"summary": "Resolve OOBI and assign an alias for the remote identifier", "description": "Resolve OOBI URL or `rpy` message by process results of request and assign \'alias\' in contact data for resolved identifier", "tags": ["OOBIs"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "OOBI", "oneOf": [{"type": "object", "properties": {"oobialias": {"type": "string", "description": "alias to assign to the identifier resolved from this OOBI"}, "url": {"type": "string", "description": "URL OOBI"}, "rpy": {"type": "object", "description": "unsigned KERI `rpy` event message with endpoints"}}}]}}}}, "responses": {"202": {"description": "OOBI resolution to key state successful"}}}}, "/states": {"get": {"summary": "Display key event log (KEL) for given identifier prefix", "description": "If provided qb64 identifier prefix is in Kevers, return the current state of the identifier along with the KEL and all associated signatures and receipts", "tags": ["Key Event Log"], "parameters": [{"in": "path", "name": "pre", "description": "qb64 identifier prefix of KEL to load", "schema": {"type": "string"}, "required": true}], "responses": {"200": {"description": "Key event log and key state of identifier"}, "404": {"description": "Identifier not found in Key event database"}}}}, "/events": {"get": {"summary": "Display key event log (KEL) for given identifier prefix", "description": "If provided qb64 identifier prefix is in Kevers, return the current state of the identifier along with the KEL and all associated signatures and receipts", "tags": ["Key Event Log"], "parameters": [{"in": "path", "name": "pre", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of KEL to load"}], "responses": {"200": {"description": "Key event log and key state of identifier"}, "404": {"description": "Identifier not found in Key event database"}}}}, "/queries": {"post": {"summary": "Display key event log (KEL) for given identifier prefix", "description": "If provided qb64 identifier prefix is in Kevers, return the current state of the identifier along with the KEL and all associated signatures and receipts", "tags": ["Query"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["pre"], "properties": {"pre": {"type": "string", "description": "qb64 identifier prefix of KEL to load"}, "anchor": {"type": "string", "description": "Anchor"}, "sn": {"type": "string", "description": "Serial number"}}}}}}, "responses": {"200": {"description": "Key event log and key state of identifier"}, "404": {"description": "Identifier not found in Key event database"}}}}, "/identifiers": {"get": {"summary": "Retrieve a list of identifiers associated with the agent.", "description": "This endpoint retrieves a list of identifiers associated with the agent. It supports pagination through the \'Range\' header.", "tags": ["Identifier"], "parameters": [{"in": "header", "name": "Range", "schema": {"type": "string"}, "required": false, "description": "The \'Range\' header is used for pagination. The default range is 0-9."}], "responses": {"200": {"description": "Successfully retrieved identifiers."}, "206": {"description": "Successfully retrieved identifiers within the specified range."}}}, "options": {}, "post": {"summary": "Create an identifier.", "description": "This endpoint creates an identifier with the provided inception event, name, and signatures.", "tags": ["Identifier"], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"icp": {"type": "object", "description": "The inception event for the identifier."}, "name": {"type": "string", "description": "The name of the identifier."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures for the inception event."}, "group": {"type": "object", "description": "Multisig group information."}, "salty": {"type": "object", "description": "Salty parameters."}, "randy": {"type": "object", "description": "Randomly generated materials."}, "extern": {"type": "object", "description": "External parameters."}}}}}}, "responses": {"202": {"description": "Identifier creation is in progress. The response is a long running operation."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}}, "/challenges": {"get": {"summary": "Get random list of words for a 2 factor auth challenge", "description": "Get the list of identifiers associated with this agent", "tags": ["Challenge/Response"], "parameters": [{"in": "query", "name": "strength", "schema": {"type": "integer"}, "description": "cryptographic strength of word list", "required": false}], "responses": {"200": {"description": "An array of random words", "content": {"application/json": {"schema": {"description": "Random word list", "type": "object", "properties": {"words": {"type": "array", "description": "random challenge word list", "items": {"type": "string"}}}}}}}}}}, "/contacts": {"get": {"summary": "Get list of contact information associated with remote identifiers", "description": "Get list of contact information associated with remote identifiers. All information is metadata and kept in local storage only", "tags": ["Contacts"], "parameters": [{"in": "query", "name": "group", "schema": {"type": "string"}, "required": false, "description": "field name to group results by"}, {"in": "query", "name": "filter_field", "schema": {"type": "string"}, "description": "field name to search", "required": false}, {"in": "query", "name": "filter_value", "schema": {"type": "string"}, "description": "value to search for", "required": false}], "responses": {"200": {"description": "List of contact information for remote identifiers"}}}}, "/oobi": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/": {"post": {"summary": "Accept KERI events with attachment headers and parse", "description": "Accept KERI events with attachment headers and parse.", "tags": ["Events"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "KERI event message"}}}}, "responses": {"204": {"description": "KEL EXN, QRY, RPY event accepted."}}}, "put": {"summary": "Accept KERI events with attachment headers and parse", "description": "Accept KERI events with attachment headers and parse.", "tags": ["Events"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "KERI event message"}}}}, "responses": {"200": {"description": "Mailbox query response for server sent events"}, "204": {"description": "KEL or EXN event accepted."}}}}, "/notifications": {"get": {"summary": "Get list of notifications for the controller of the agent", "description": "Get list of notifications for the controller of the agent. Notifications will be sorted by creation date/time", "parameters": [{"in": "header", "name": "Range", "schema": {"type": "string"}, "required": false, "description": "size of the result list. Defaults to 25"}], "tags": ["Notifications"], "responses": {"200": {"description": "List of contact information for remote identifiers"}}}}, "/operations/{name}": {"delete": {"summary": "Remove a specific long running operation.", "description": "This endpoint removes a long running operation by its name.", "tags": ["Operation"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The name of the long running operation to remove."}], "responses": {"204": {"description": "Successfully removed the long running operation."}, "404": {"description": "The requested long running operation was not found."}, "500": {"description": "Internal server error. This could be due to an issue with removing the operation."}}}, "get": {"summary": "Retrieve a specific long running operation.", "description": "This endpoint retrieves the status of a long running operation by its name.", "tags": ["Operation"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The name of the long running operation to retrieve."}], "responses": {"200": {"description": "Successfully retrieved the status of the long running operation."}, "404": {"description": "The requested long running operation was not found."}}}}, "/oobis/{alias}": {"get": {"summary": "Get OOBI for specific identifier", "description": "Generate OOBI for the identifier of the specified alias and role", "tags": ["OOBIs"], "parameters": [{"in": "path", "name": "alias", "schema": {"type": "string"}, "required": true, "description": "human readable alias for the identifier generate OOBI for"}, {"in": "query", "name": "role", "schema": {"type": "string"}, "required": true, "description": "role for which to generate OOBI"}], "responses": {"200": {"description": "An array of Identifier key state information", "content": {"application/json": {"schema": {"description": "Key state information for current identifiers", "type": "object"}}}}}}}, "/agent/{caid}": {"get": {"summary": "Retrieve key state record of an agent by controller AID.", "description": "This endpoint retrieves the key state record for a given controller of an agent.", "tags": ["Agent"], "parameters": [{"in": "path", "name": "caid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of Controller."}], "responses": {"200": {"description": "Successfully retrieved the key state record."}, "400": {"description": "Bad request. This could be due to an invalid agent or controller configuration."}, "404": {"description": "The requested controller or agent was not found."}}}, "put": {"summary": "Update agent configuration by controller AID.", "description": "This endpoint updates the agent configuration based on the provided request parameters and body.", "tags": ["Agent"], "parameters": [{"in": "path", "name": "caid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of Controller."}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["rot", "sigs", "sxlt", "kyes"], "properties": {"rot": {"type": "object", "description": "The rotation event."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}, "sxlt": {"type": "string", "description": "The salty parameters."}, "keys": {"type": "object", "description": "The keys."}}}}}}, "responses": {"204": {"description": "Successfully updated the agent configuration."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested agent was not found."}, "500": {"description": "Internal server error. This could be due to an issue with updating the agent configuration."}}}}, "/identifiers/{name}": {"get": {"summary": "Retrieve an identifier.", "description": "This endpoint retrieves an identifier by its human-readable name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}], "responses": {"200": {"description": "Successfully retrieved the identifier details."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Process identifier events.", "description": "This endpoint handles the \'rot\' or \'ixn\' events of an identifier, or the request to resubmit the KEL, based on the provided request.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rot": {"type": "object", "description": "The rotation event details."}, "ixn": {"type": "object", "description": "The interaction event details."}, "submit": {"type": "object", "description": "The request to resubmit event details to witnesses."}}, "oneOf": [{"required": ["rot"]}, {"required": ["ixn"]}, {"required": ["submit"]}]}}}}, "responses": {"200": {"description": "Successfully processed the identifier\'s event."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}, "put": {"summary": "Rename an identifier.", "description": "This endpoint renames an identifier with the provided new name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The current human-readable name of the identifier."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string", "description": "The new name for the identifier."}}, "required": ["name"]}}}}, "responses": {"200": {"description": "Successfully renamed the identifier and returns the updated information."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}}, "/endroles/{aid}": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with AID or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier (AID) or name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/escrows/rpy": {"get": {"summary": "Retrieve reply escrows.", "description": "This endpoint retrieves the reply escrows and can filter the collection based on a specific route.", "tags": ["Reply Escrow"], "parameters": [{"in": "query", "name": "route", "schema": {"type": "string"}, "required": false, "description": "The specific route to filter the reply escrow collection."}], "responses": {"200": {"description": "Successfully retrieved the reply escrows."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}}, "/challenges/{name}": {"post": {"summary": "Sign challenge message and forward to peer identifier", "description": "Sign a challenge word list received out of bands and send `exn` peer to peer message to recipient", "tags": ["Challenge/Response"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "Human readable alias for the identifier to create"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Challenge response", "properties": {"recipient": {"type": "string", "description": "human readable alias recipient identifier to send signed challenge to"}, "words": {"type": "array", "description": "challenge in form of word list", "items": {"type": "string"}}}}}}}, "responses": {"202": {"description": "Success submission of signed challenge/response"}}}}, "/challenges_verify/{source}": {"post": {"summary": "Sign challenge message and forward to peer identifier", "description": "Sign a challenge word list received out of bands and send `exn` peer to peer message to recipient", "tags": ["Challenge/Response"], "parameters": [{"in": "path", "name": "source", "schema": {"type": "string"}, "required": true, "description": "Human readable alias for the identifier to create"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Challenge response", "properties": {"recipient": {"type": "string", "description": "human readable alias recipient identifier to send signed challenge to"}, "words": {"type": "array", "description": "challenge in form of word list", "items": {"type": "string"}}}}}}}, "responses": {"202": {"description": "Success submission of signed challenge/response"}}}, "put": {"summary": "Mark challenge response exn message as signed", "description": "Mark challenge response exn message as signed", "tags": ["Challenge/Response"], "parameters": [{"in": "path", "name": "source", "schema": {"type": "string"}, "required": true, "description": "Human readable alias for the identifier to create"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Challenge response", "properties": {"aid": {"type": "string", "description": "aid of signer of accepted challenge response"}, "said": {"type": "array", "description": "SAID of challenge message signed", "items": {"type": "string"}}}}}}}, "responses": {"202": {"description": "Success submission of signed challenge/response"}}}}, "/contacts/{prefix}": {"delete": {"summary": "Delete contact information associated with remote identifier", "description": "Delete contact information associated with remote identifier", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of contact to delete"}], "responses": {"202": {"description": "Contact information successfully deleted for prefix"}, "404": {"description": "No contact information found for prefix"}}}, "get": {"summary": "Get contact information associated with single remote identifier", "description": "Get contact information associated with single remote identifier. All information is meta-data and kept in local storage only", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of contact to get"}], "responses": {"200": {"description": "Contact information successfully retrieved for prefix"}, "404": {"description": "No contact information found for prefix"}}}, "post": {"summary": "Create new contact information for an identifier", "description": "Creates new information for an identifier, overwriting all existing information for that identifier", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix to add contact metadata to"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Contact information", "type": "object"}}}}, "responses": {"200": {"description": "Updated contact information for remote identifier"}, "400": {"description": "Invalid identifier used to update contact information"}, "404": {"description": "Prefix not found in identifier contact information"}}}, "put": {"summary": "Update provided fields in contact information associated with remote identifier prefix", "description": "Update provided fields in contact information associated with remote identifier prefix. All information is metadata and kept in local storage only", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix to add contact metadata to"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Contact information", "type": "object"}}}}, "responses": {"200": {"description": "Updated contact information for remote identifier"}, "400": {"description": "Invalid identifier used to update contact information"}, "404": {"description": "Prefix not found in identifier contact information"}}}}, "/oobi/{aid}": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/notifications/{said}": {"delete": {"summary": "Delete notification", "description": "Delete notification", "tags": ["Notifications"], "parameters": [{"in": "path", "name": "said", "schema": {"type": "string"}, "required": true, "description": "qb64 said of note to delete"}], "responses": {"202": {"description": "Notification successfully deleted for prefix"}, "404": {"description": "No notification information found for prefix"}}}, "put": {"summary": "Mark notification as read", "description": "Mark notification as read", "tags": ["Notifications"], "parameters": [{"in": "path", "name": "said", "schema": {"type": "string"}, "required": true, "description": "qb64 said of note to mark as read"}], "responses": {"202": {"description": "Notification successfully marked as read for prefix"}, "404": {"description": "No notification information found for SAID"}}}}, "/identifiers/{name}/events": {"get": {"summary": "Retrieve an identifier.", "description": "This endpoint retrieves an identifier by its human-readable name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}], "responses": {"200": {"description": "Successfully retrieved the identifier details."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Process identifier events.", "description": "This endpoint handles the \'rot\' or \'ixn\' events of an identifier, or the request to resubmit the KEL, based on the provided request.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rot": {"type": "object", "description": "The rotation event details."}, "ixn": {"type": "object", "description": "The interaction event details."}, "submit": {"type": "object", "description": "The request to resubmit event details to witnesses."}}, "oneOf": [{"required": ["rot"]}, {"required": ["ixn"]}, {"required": ["submit"]}]}}}}, "responses": {"200": {"description": "Successfully processed the identifier\'s event."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}, "put": {"summary": "Rename an identifier.", "description": "This endpoint renames an identifier with the provided new name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The current human-readable name of the identifier."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string", "description": "The new name for the identifier."}}, "required": ["name"]}}}}, "responses": {"200": {"description": "Successfully renamed the identifier and returns the updated information."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/submit": {"get": {"summary": "Retrieve an identifier.", "description": "This endpoint retrieves an identifier by its human-readable name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}], "responses": {"200": {"description": "Successfully retrieved the identifier details."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Process identifier events.", "description": "This endpoint handles the \'rot\' or \'ixn\' events of an identifier, or the request to resubmit the KEL, based on the provided request.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rot": {"type": "object", "description": "The rotation event details."}, "ixn": {"type": "object", "description": "The interaction event details."}, "submit": {"type": "object", "description": "The request to resubmit event details to witnesses."}}, "oneOf": [{"required": ["rot"]}, {"required": ["ixn"]}, {"required": ["submit"]}]}}}}, "responses": {"200": {"description": "Successfully processed the identifier\'s event."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}, "put": {"summary": "Rename an identifier.", "description": "This endpoint renames an identifier with the provided new name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The current human-readable name of the identifier."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string", "description": "The new name for the identifier."}}, "required": ["name"]}}}}, "responses": {"200": {"description": "Successfully renamed the identifier and returns the updated information."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/oobis": {"get": {"summary": "Fetch OOBI URLs of an identifier.", "description": "This endpoint fetches the OOBI URLs for a specific role associated with an identifier.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "query", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The role for which to fetch the OOBI URLs. Can be a witness, controller, agent, or mailbox."}], "responses": {"200": {"description": "Successfully fetched the OOBI URLs. The response body contains the OOBI URLs."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/endroles": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with AID or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier (AID) or name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/identifiers/{name}/members": {"get": {"summary": "Fetch group member information.", "description": "This endpoint retrieves the signing and rotation members for a specific group associated with an identifier.", "tags": ["Group Member"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}], "responses": {"200": {"description": "Successfully fetched the group member information."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/delegation": {"post": {}}, "/endroles/{aid}/{role}": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with AID or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier (AID) or name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/contacts/{prefix}/img": {"get": {"summary": "Get contact image for identifer prefix", "description": "Get contact image for identifer prefix", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of contact image to get"}], "responses": {"200": {"description": "Contact information successfully retrieved for prefix", "content": {"image/jpg": {"schema": {"description": "Image", "type": "binary"}}}}, "404": {"description": "No contact information found for prefix"}}}, "post": {"summary": "Uploads an image to associate with identifier.", "description": "Uploads an image to associate with identifier.", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "description": "identifier prefix to associate image to", "required": true}], "requestBody": {"required": true, "content": {"image/jpg": {"schema": {"type": "string", "format": "binary"}}, "image/png": {"schema": {"type": "string", "format": "binary"}}}}, "responses": {"200": {"description": "Image successfully uploaded"}}}}, "/oobi/{aid}/{role}": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/identifiers/{name}/endroles/{role}": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with AID or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier (AID) or name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/oobi/{aid}/{role}/{eid}": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/identifiers/{name}/endroles/{role}/{eid}": {"delete": {}}}, "info": {"title": "KERIA Interactive Web Interface API", "version": "1.0.1"}, "openapi": "3.1.0"}' - + assert js == '{"paths": {"/operations": {"get": {"summary": "Get list of long running operations", "parameters": [{"in": "query", "name": "type", "schema": {"type": "string"}, "required": false, "description": "filter list of long running operations by type"}], "responses": {"200": {"description": "list of long running operations", "content": {"application/json": {"schema": {"type": "array", "items": {"properties": {"name": {"type": "string"}, "metadata": {"type": "object"}, "done": {"type": "boolean"}, "error": {"type": "object"}, "response": {"type": "object"}}}}}}}}}}, "/oobis": {"post": {"summary": "Resolve OOBI and assign an alias for the remote identifier", "description": "Resolve OOBI URL or `rpy` message by process results of request and assign \'alias\' in contact data for resolved identifier", "tags": ["OOBIs"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "OOBI", "oneOf": [{"type": "object", "properties": {"oobialias": {"type": "string", "description": "alias to assign to the identifier resolved from this OOBI"}, "url": {"type": "string", "description": "URL OOBI"}, "rpy": {"type": "object", "description": "unsigned KERI `rpy` event message with endpoints"}}}]}}}}, "responses": {"202": {"description": "OOBI resolution to key state successful"}}}}, "/states": {"get": {"summary": "Display key event log (KEL) for given identifier prefix", "description": "If provided qb64 identifier prefix is in Kevers, return the current state of the identifier along with the KEL and all associated signatures and receipts", "tags": ["Key Event Log"], "parameters": [{"in": "path", "name": "pre", "description": "qb64 identifier prefix of KEL to load", "schema": {"type": "string"}, "required": true}], "responses": {"200": {"description": "Key event log and key state of identifier"}, "404": {"description": "Identifier not found in Key event database"}}}}, "/events": {"get": {"summary": "Display key event log (KEL) for given identifier prefix", "description": "If provided qb64 identifier prefix is in Kevers, return the current state of the identifier along with the KEL and all associated signatures and receipts", "tags": ["Key Event Log"], "parameters": [{"in": "path", "name": "pre", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of KEL to load"}], "responses": {"200": {"description": "Key event log and key state of identifier"}, "404": {"description": "Identifier not found in Key event database"}}}}, "/queries": {"post": {"summary": "Display key event log (KEL) for given identifier prefix", "description": "If provided qb64 identifier prefix is in Kevers, return the current state of the identifier along with the KEL and all associated signatures and receipts", "tags": ["Query"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["pre"], "properties": {"pre": {"type": "string", "description": "qb64 identifier prefix of KEL to load"}, "anchor": {"type": "string", "description": "Anchor"}, "sn": {"type": "string", "description": "Serial number"}}}}}}, "responses": {"200": {"description": "Key event log and key state of identifier"}, "404": {"description": "Identifier not found in Key event database"}}}}, "/identifiers": {"get": {"summary": "Retrieve a list of identifiers associated with the agent.", "description": "This endpoint retrieves a list of identifiers associated with the agent. It supports pagination through the \'Range\' header.", "tags": ["Identifier"], "parameters": [{"in": "header", "name": "Range", "schema": {"type": "string"}, "required": false, "description": "The \'Range\' header is used for pagination. The default range is 0-9."}], "responses": {"200": {"description": "Successfully retrieved identifiers."}, "206": {"description": "Successfully retrieved identifiers within the specified range."}}}, "options": {}, "post": {"summary": "Create an identifier.", "description": "This endpoint creates an identifier with the provided inception event, name, and signatures.", "tags": ["Identifier"], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"icp": {"type": "object", "description": "The inception event for the identifier."}, "name": {"type": "string", "description": "The name of the identifier."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures for the inception event."}, "group": {"type": "object", "description": "Multisig group information."}, "salty": {"type": "object", "description": "Salty parameters."}, "randy": {"type": "object", "description": "Randomly generated materials."}, "extern": {"type": "object", "description": "External parameters."}}}}}}, "responses": {"202": {"description": "Identifier creation is in progress. The response is a long running operation."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}}, "/challenges": {"get": {"summary": "Get random list of words for a 2 factor auth challenge", "description": "Get the list of identifiers associated with this agent", "tags": ["Challenge/Response"], "parameters": [{"in": "query", "name": "strength", "schema": {"type": "integer"}, "description": "cryptographic strength of word list", "required": false}], "responses": {"200": {"description": "An array of random words", "content": {"application/json": {"schema": {"description": "Random word list", "type": "object", "properties": {"words": {"type": "array", "description": "random challenge word list", "items": {"type": "string"}}}}}}}}}}, "/contacts": {"get": {"summary": "Get list of contact information associated with remote identifiers", "description": "Get list of contact information associated with remote identifiers. All information is metadata and kept in local storage only", "tags": ["Contacts"], "parameters": [{"in": "query", "name": "group", "schema": {"type": "string"}, "required": false, "description": "field name to group results by"}, {"in": "query", "name": "filter_field", "schema": {"type": "string"}, "description": "field name to search", "required": false}, {"in": "query", "name": "filter_value", "schema": {"type": "string"}, "description": "value to search for", "required": false}], "responses": {"200": {"description": "List of contact information for remote identifiers"}}}}, "/oobi": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/": {"post": {"summary": "Accept KERI events with attachment headers and parse", "description": "Accept KERI events with attachment headers and parse.", "tags": ["Events"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "KERI event message"}}}}, "responses": {"204": {"description": "KEL EXN, QRY, RPY event accepted."}}}, "put": {"summary": "Accept KERI events with attachment headers and parse", "description": "Accept KERI events with attachment headers and parse.", "tags": ["Events"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "KERI event message"}}}}, "responses": {"200": {"description": "Mailbox query response for server sent events"}, "204": {"description": "KEL or EXN event accepted."}}}}, "/notifications": {"get": {"summary": "Get list of notifications for the controller of the agent", "description": "Get list of notifications for the controller of the agent. Notifications will be sorted by creation date/time", "parameters": [{"in": "header", "name": "Range", "schema": {"type": "string"}, "required": false, "description": "size of the result list. Defaults to 25"}], "tags": ["Notifications"], "responses": {"200": {"description": "List of contact information for remote identifiers"}}}}, "/operations/{name}": {"delete": {"summary": "Remove a specific long running operation.", "description": "This endpoint removes a long running operation by its name.", "tags": ["Operation"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The name of the long running operation to remove."}], "responses": {"204": {"description": "Successfully removed the long running operation."}, "404": {"description": "The requested long running operation was not found."}, "500": {"description": "Internal server error. This could be due to an issue with removing the operation."}}}, "get": {"summary": "Retrieve a specific long running operation.", "description": "This endpoint retrieves the status of a long running operation by its name.", "tags": ["Operation"], "parameters": [{"in": "path", "name": "name", "schema": {"type": "string"}, "required": true, "description": "The name of the long running operation to retrieve."}], "responses": {"200": {"description": "Successfully retrieved the status of the long running operation."}, "404": {"description": "The requested long running operation was not found."}}}}, "/oobis/{alias}": {"get": {"summary": "Get OOBI for specific identifier", "description": "Generate OOBI for the identifier of the specified alias and role", "tags": ["OOBIs"], "parameters": [{"in": "path", "name": "alias", "schema": {"type": "string"}, "required": true, "description": "human readable alias for the identifier generate OOBI for"}, {"in": "query", "name": "role", "schema": {"type": "string"}, "required": true, "description": "role for which to generate OOBI"}], "responses": {"200": {"description": "An array of Identifier key state information", "content": {"application/json": {"schema": {"description": "Key state information for current identifiers", "type": "object"}}}}}}}, "/agent/{caid}": {"get": {"summary": "Retrieve key state record of an agent by controller AID.", "description": "This endpoint retrieves the key state record for a given controller of an agent.", "tags": ["Agent"], "parameters": [{"in": "path", "name": "caid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of Controller."}], "responses": {"200": {"description": "Successfully retrieved the key state record."}, "400": {"description": "Bad request. This could be due to an invalid agent or controller configuration."}, "404": {"description": "The requested controller or agent was not found."}}}, "put": {"summary": "Update agent configuration by controller AID.", "description": "This endpoint updates the agent configuration based on the provided request parameters and body.", "tags": ["Agent"], "parameters": [{"in": "path", "name": "caid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of Controller."}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["rot", "sigs", "sxlt", "kyes"], "properties": {"rot": {"type": "object", "description": "The rotation event."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}, "sxlt": {"type": "string", "description": "The salty parameters."}, "keys": {"type": "object", "description": "The keys."}}}}}}, "responses": {"204": {"description": "Successfully updated the agent configuration."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested agent was not found."}, "500": {"description": "Internal server error. This could be due to an issue with updating the agent configuration."}}}}, "/identifiers/{name}": {"get": {"summary": "Retrieve an identifier.", "description": "This endpoint retrieves an identifier by its prefix or human-readable name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}], "responses": {"200": {"description": "Successfully retrieved the identifier details."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Process identifier events.", "description": "This endpoint handles the \'rot\' or \'ixn\' events of an identifier, or the request to resubmit the KEL, based on the provided request.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rot": {"type": "object", "description": "The rotation event details."}, "ixn": {"type": "object", "description": "The interaction event details."}, "submit": {"type": "object", "description": "The request to resubmit event details to witnesses."}}, "oneOf": [{"required": ["rot"]}, {"required": ["ixn"]}, {"required": ["submit"]}]}}}}, "responses": {"200": {"description": "Successfully processed the identifier\'s event."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}, "put": {"summary": "Rename an identifier.", "description": "This endpoint renames an identifier with the provided new name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The current human-readable name of the identifier or its prefix."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string", "description": "The new human-readable name for the identifier."}}, "required": ["name"]}}}}, "responses": {"200": {"description": "Successfully renamed the identifier and returns the updated information."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}}, "/endroles/{aid}": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with an identifier prefix or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier prefix or human-readable name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/escrows/rpy": {"get": {"summary": "Retrieve reply escrows.", "description": "This endpoint retrieves the reply escrows and can filter the collection based on a specific route.", "tags": ["Reply Escrow"], "parameters": [{"in": "query", "name": "route", "schema": {"type": "string"}, "required": false, "description": "The specific route to filter the reply escrow collection."}], "responses": {"200": {"description": "Successfully retrieved the reply escrows."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}}, "/challenges/{name}": {"post": {"summary": "Sign challenge message and forward to peer identifier", "description": "Sign a challenge word list received out of bands and send `exn` peer to peer message to recipient", "tags": ["Challenge/Response"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "Human readable alias or prefix for the identifier to create"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Challenge response", "properties": {"recipient": {"type": "string", "description": "human readable alias recipient identifier to send signed challenge to"}, "words": {"type": "array", "description": "challenge in form of word list", "items": {"type": "string"}}}}}}}, "responses": {"202": {"description": "Success submission of signed challenge/response"}}}}, "/challenges_verify/{source}": {"post": {"summary": "Sign challenge message and forward to peer identifier", "description": "Sign a challenge word list received out of bands and send `exn` peer to peer message to recipient", "tags": ["Challenge/Response"], "parameters": [{"in": "path", "name": "source", "schema": {"type": "string"}, "required": true, "description": "Human readable alias for the identifier to create"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Challenge response", "properties": {"recipient": {"type": "string", "description": "human readable alias recipient identifier to send signed challenge to"}, "words": {"type": "array", "description": "challenge in form of word list", "items": {"type": "string"}}}}}}}, "responses": {"202": {"description": "Success submission of signed challenge/response"}}}, "put": {"summary": "Mark challenge response exn message as signed", "description": "Mark challenge response exn message as signed", "tags": ["Challenge/Response"], "parameters": [{"in": "path", "name": "source", "schema": {"type": "string"}, "required": true, "description": "Human readable alias for the identifier to create"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Challenge response", "properties": {"aid": {"type": "string", "description": "aid of signer of accepted challenge response"}, "said": {"type": "array", "description": "SAID of challenge message signed", "items": {"type": "string"}}}}}}}, "responses": {"202": {"description": "Success submission of signed challenge/response"}}}}, "/contacts/{prefix}": {"delete": {"summary": "Delete contact information associated with remote identifier", "description": "Delete contact information associated with remote identifier", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of contact to delete"}], "responses": {"202": {"description": "Contact information successfully deleted for prefix"}, "404": {"description": "No contact information found for prefix"}}}, "get": {"summary": "Get contact information associated with single remote identifier", "description": "Get contact information associated with single remote identifier. All information is meta-data and kept in local storage only", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of contact to get"}], "responses": {"200": {"description": "Contact information successfully retrieved for prefix"}, "404": {"description": "No contact information found for prefix"}}}, "post": {"summary": "Create new contact information for an identifier", "description": "Creates new information for an identifier, overwriting all existing information for that identifier", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix to add contact metadata to"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Contact information", "type": "object"}}}}, "responses": {"200": {"description": "Updated contact information for remote identifier"}, "400": {"description": "Invalid identifier used to update contact information"}, "404": {"description": "Prefix not found in identifier contact information"}}}, "put": {"summary": "Update provided fields in contact information associated with remote identifier prefix", "description": "Update provided fields in contact information associated with remote identifier prefix. All information is metadata and kept in local storage only", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix to add contact metadata to"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"description": "Contact information", "type": "object"}}}}, "responses": {"200": {"description": "Updated contact information for remote identifier"}, "400": {"description": "Invalid identifier used to update contact information"}, "404": {"description": "Prefix not found in identifier contact information"}}}}, "/oobi/{aid}": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/notifications/{said}": {"delete": {"summary": "Delete notification", "description": "Delete notification", "tags": ["Notifications"], "parameters": [{"in": "path", "name": "said", "schema": {"type": "string"}, "required": true, "description": "qb64 said of note to delete"}], "responses": {"202": {"description": "Notification successfully deleted for prefix"}, "404": {"description": "No notification information found for prefix"}}}, "put": {"summary": "Mark notification as read", "description": "Mark notification as read", "tags": ["Notifications"], "parameters": [{"in": "path", "name": "said", "schema": {"type": "string"}, "required": true, "description": "qb64 said of note to mark as read"}], "responses": {"202": {"description": "Notification successfully marked as read for prefix"}, "404": {"description": "No notification information found for SAID"}}}}, "/identifiers/{name}/events": {"get": {"summary": "Retrieve an identifier.", "description": "This endpoint retrieves an identifier by its prefix or human-readable name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}], "responses": {"200": {"description": "Successfully retrieved the identifier details."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Process identifier events.", "description": "This endpoint handles the \'rot\' or \'ixn\' events of an identifier, or the request to resubmit the KEL, based on the provided request.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rot": {"type": "object", "description": "The rotation event details."}, "ixn": {"type": "object", "description": "The interaction event details."}, "submit": {"type": "object", "description": "The request to resubmit event details to witnesses."}}, "oneOf": [{"required": ["rot"]}, {"required": ["ixn"]}, {"required": ["submit"]}]}}}}, "responses": {"200": {"description": "Successfully processed the identifier\'s event."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}, "put": {"summary": "Rename an identifier.", "description": "This endpoint renames an identifier with the provided new name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The current human-readable name of the identifier or its prefix."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string", "description": "The new human-readable name for the identifier."}}, "required": ["name"]}}}}, "responses": {"200": {"description": "Successfully renamed the identifier and returns the updated information."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/submit": {"get": {"summary": "Retrieve an identifier.", "description": "This endpoint retrieves an identifier by its prefix or human-readable name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}], "responses": {"200": {"description": "Successfully retrieved the identifier details."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Process identifier events.", "description": "This endpoint handles the \'rot\' or \'ixn\' events of an identifier, or the request to resubmit the KEL, based on the provided request.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rot": {"type": "object", "description": "The rotation event details."}, "ixn": {"type": "object", "description": "The interaction event details."}, "submit": {"type": "object", "description": "The request to resubmit event details to witnesses."}}, "oneOf": [{"required": ["rot"]}, {"required": ["ixn"]}, {"required": ["submit"]}]}}}}, "responses": {"200": {"description": "Successfully processed the identifier\'s event."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}}}, "put": {"summary": "Rename an identifier.", "description": "This endpoint renames an identifier with the provided new name.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The current human-readable name of the identifier or its prefix."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string", "description": "The new human-readable name for the identifier."}}, "required": ["name"]}}}}, "responses": {"200": {"description": "Successfully renamed the identifier and returns the updated information."}, "400": {"description": "Bad request. This could be due to a missing or invalid name parameter."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/oobis": {"get": {"summary": "Fetch OOBI URLs of an identifier.", "description": "This endpoint fetches the OOBI URLs for a specific role associated with an identifier.", "tags": ["Identifier"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "query", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The role for which to fetch the OOBI URLs. Can be a witness, controller, agent, or mailbox."}], "responses": {"200": {"description": "Successfully fetched the OOBI URLs. The response body contains the OOBI URLs."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/endroles": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with an identifier prefix or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier prefix or human-readable name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/identifiers/{name}/members": {"get": {"summary": "Fetch group member information.", "description": "This endpoint retrieves the signing and rotation members for a specific group associated with an identifier.", "tags": ["Group Member"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}], "responses": {"200": {"description": "Successfully fetched the group member information."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}}, "/identifiers/{name}/delegation": {"post": {}}, "/endroles/{aid}/{role}": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with an identifier prefix or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier prefix or human-readable name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/contacts/{prefix}/img": {"get": {"summary": "Get contact image for identifer prefix", "description": "Get contact image for identifer prefix", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "required": true, "description": "qb64 identifier prefix of contact image to get"}], "responses": {"200": {"description": "Contact information successfully retrieved for prefix", "content": {"image/jpg": {"schema": {"description": "Image", "type": "binary"}}}}, "404": {"description": "No contact information found for prefix"}}}, "post": {"summary": "Uploads an image to associate with identifier.", "description": "Uploads an image to associate with identifier.", "tags": ["Contacts"], "parameters": [{"in": "path", "name": "prefix", "schema": {"type": "string"}, "description": "identifier prefix to associate image to", "required": true}], "requestBody": {"required": true, "content": {"image/jpg": {"schema": {"type": "string", "format": "binary"}}, "image/png": {"schema": {"type": "string", "format": "binary"}}}}, "responses": {"200": {"description": "Image successfully uploaded"}}}}, "/oobi/{aid}/{role}": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/identifiers/{name}/endroles/{role}": {"get": {"summary": "Retrieve end roles.", "description": "This endpoint retrieves the end roles associated with an identifier prefix or human-readable name. It can also filter the end roles based on a specific role.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The identifier (AID)."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The specific role to filter the end roles."}], "responses": {"200": {"description": "Successfully retrieved the end roles. The response body contains the end roles."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "The requested identifier was not found."}}}, "post": {"summary": "Create an end role.", "description": "This endpoint creates an end role associated with a given identifier prefix or human-readable name.", "tags": ["End Role"], "parameters": [{"in": "path", "name": "name or prefix", "schema": {"type": "string"}, "required": true, "description": "The human-readable name of the identifier or its prefix."}, {"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "Not supported for POST. If provided, a 404 is returned."}], "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"rpy": {"type": "object", "description": "The reply object."}, "sigs": {"type": "array", "items": {"type": "string"}, "description": "The signatures."}}}}}}, "responses": {"202": {"description": "Accepted. The end role creation is in progress."}, "400": {"description": "Bad request. This could be due to missing or invalid parameters."}, "404": {"description": "Not found. The requested identifier was not found."}}}}, "/oobi/{aid}/{role}/{eid}": {"get": {"summary": "Retrieve OOBI resource.", "description": "This endpoint retrieves the OOBI resource based on the provided aid, role, and eid.", "tags": ["OOBI Resource"], "parameters": [{"in": "path", "name": "aid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of OOBI."}, {"in": "path", "name": "role", "schema": {"type": "string"}, "required": true, "description": "The requested role for OOBI rpy message."}, {"in": "path", "name": "eid", "schema": {"type": "string"}, "required": true, "description": "The qb64 identifier prefix of participant in role."}], "responses": {"200": {"description": "Successfully retrieved the OOBI resource."}, "400": {"description": "Bad request. This could be due to invalid or missing parameters."}, "404": {"description": "The requested OOBI resource was not found."}}}}, "/identifiers/{name}/endroles/{role}/{eid}": {"delete": {}}}, "info": {"title": "KERIA Interactive Web Interface API", "version": "1.0.1"}, "openapi": "3.1.0"}'