diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..00407f9c --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [zcutlip] diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 2925093f..261cc6be 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,10 +16,10 @@ jobs: strategy: fail-fast: false matrix: - python: ["3.8", "3.9", "3.10", "3.11"] + python: ["3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v4 with: diff --git a/.gitignore b/.gitignore index e2cee662..014fc746 100644 --- a/.gitignore +++ b/.gitignore @@ -97,7 +97,9 @@ celerybeat-schedule *.sage.py # Environments +dot_env_files/.env* .env +.env_secret* .venv env/ venv/ @@ -123,7 +125,9 @@ dmypy.json # Pyre type checker .pyre/ -.vscode +.vscode/* +!/.vscode/settings.json +!/.vscode/launch.json .idea/ # General @@ -161,6 +165,13 @@ Temporary Items /sanitize.cfg # ignore private response-generation configs *private*cfg +/responses_archive # Makefile stamps .*stamp + +# General +.vagrant/ + +# Log files (if you are creating logs in debug mode, uncomment this) +# *.log diff --git a/.init/00_pyonepassword b/.init/00_pyonepassword index 988db369..9345f236 100644 --- a/.init/00_pyonepassword +++ b/.init/00_pyonepassword @@ -65,5 +65,9 @@ then compdef _local_branches deletebranch_pyop pytest_pyop mypy_pyop fi +if [ -f "$_pyonepasswd_src_root/dot_env_files/.env_pyonepassword_test_rw" ]; +then + alias op_sa_rw="\$_pyonepasswd_src_root/scripts/op_env \$_pyonepasswd_src_root/dot_env_files/.env_pyonepassword_test_rw" +fi unset _realhome diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 29b4b4e6..ee310ea5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,17 +1,17 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-json exclude: ^\.vscode\/.*$ - id: check-yaml - id: check-merge-conflict - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 - - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: 'v2.0.2' + - repo: https://github.com/hhatto/autopep8 + rev: 'v2.0.4' hooks: - id: autopep8 - repo: https://github.com/pycqa/isort diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..c129a463 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,149 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": true + }, + { + "name": "sanitize.py", + "type": "python", + "request": "launch", + "program": "scripts/sanitize.py", + "console": "integratedTerminal", + "justMyCode": true, + "args": [ + "./sanitize.cfg" + ] + }, + { + "name": "versions.py", + "type": "python", + "request": "launch", + "program": "examples/versions.py", + "console": "integratedTerminal", + "justMyCode": false + }, + { + "name": "debug op forget", + "type": "python", + "request": "launch", + "program": "ipython_snippets/debug.py", + "console": "integratedTerminal" + }, + { + "name": "load from json", + "type": "python", + "request": "launch", + "program": "ipython_snippets/load_json_item.py", + "console": "integratedTerminal", + "justMyCode": false + }, + { + "name": "new server", + "type": "python", + "request": "launch", + "module": "examples.server" + }, + { + "name": "create_item", + "type": "python", + "request": "launch", + "program": "examples/create_item.py", + "console": "integratedTerminal" + }, + { + "name": "server ssh keys", + "type": "python", + "request": "launch", + "program": "examples/server-ssh-keys.py", + "console": "integratedTerminal", + "args": [ + "Mustafar", + "id_ed25519", + "--vault", + "Machine Credentials", + "--outdir", + "./mustafar-keys" + ] + }, + { + "name": "mock op", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/mop.py", + "console": "integratedTerminal", + "args": [ + "get", + "item", + "Example Login 1", + "--vault", + "Test Data" + ] + }, + { + "name": "Python: example signin, get item", + "type": "python", + "request": "launch", + "program": "examples/example-signin-get-item.py", + "console": "integratedTerminal" + }, + { + "name": "Python: example signin, get document", + "type": "python", + "request": "launch", + "program": "examples/example-signin-get-document.py", + "console": "integratedTerminal" + }, + { + "name": "Python: example signin, signout", + "type": "python", + "request": "launch", + "program": "examples/example-signin-signout.py", + "console": "integratedTerminal" + }, + { + "name": "example-signin-get-vault", + "type": "python", + "request": "launch", + "program": "examples/example-signin-get-vault.py", + "console": "integratedTerminal" + }, + { + "name": "example list items", + "type": "python", + "request": "launch", + "program": "examples/list-items.py", + "console": "integratedTerminal" + }, + { + "name": "create items", + "type": "python", + "request": "launch", + "program": "examples/create-item.py", + "console": "integratedTerminal" + }, + { + "name": "item edit field type", + "type": "python", + "request": "launch", + "program": "examples/debug_item_edit_field_type.py", + "console": "integratedTerminal" + }, + { + "name": "example-service-account", + "type": "python", + "request": "launch", + "program": "examples/example-service-account.py", + "envFile": "${workspaceFolder}/debug_env/svc_acct_env", + "console": "integratedTerminal" + }, + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..983cffcb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,16 @@ +{ + "python.testing.pytestEnabled": true, + "python.testing.unittestEnabled": false, + "files.trimTrailingWhitespace": true, + "files.trimFinalNewlines": true, + "files.associations": { + "00_pyonepassword": "shellscript" + }, + "files.insertFinalNewline": true, + "isort.args": [ + "-m", + "3" + ], + "search.useIgnoreFiles": true, + +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 9657d25e..6539c0fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,58 @@ All notable changes to this project will be documented in this file. +## [4.0.0] 2023-11-06 + +### Added +- Item editing (gh-143): + - `OP.item_edit_add_password_field()` + - `OP.item_edit_add_url_field()` + - `OP.item_edit_add_text_field()` + - `OP.item_edit_set_password()` + - `OP.item_edit_set_url_field()` + - `OP.item_edit_set_text_field()` + - `OP.item_edit_delete_field()` + - `OP.item_edit_favorite()` + - `OP.item_edit_generate_password()` + - `OP.item_edit_tags()` + - `OP.item_edit_title()` + - `OP.item_edit_url()` + +- `OPAbstractItem.field_value_by_section_label()` (gh-144) + - replacement for poorly named `field_value_by_section_title()` + +- Support for `op` new `whoami` behavior version 2.20.0 (gh-146) + - new `whoami` dict + - On `OP()` initialization, accomodate `whoami` failure when the token hasn't been used recently + +### Changed +- Added Python 3.12 support (gh-152) +- Removed Python 3.8 support (gh-152) +- Ensure all methods for section lookup by label raise `OPSectionNotFound` if no section is found matching the given label (gh-144) +- Ensure all methods for field lookup by label raise `OPFieldNotFound` if no field is found matching the given label (gh-144) + +### Deprecated + +- `OPAbstractItem.field_value_by_section_title()` (gh-144) + - call `OPAbstractItem.field_value_by_section_label()` instead + +### Removed + +- Deprecated kwargs to `OP()`: (gh-161) + - `use_existing_session` (replaced by `existing_auth`) + - `account_shorthand` (replaced by `account`) +- Deprecated exception `OPNotSignedInException` class (gh-161) + - replaced with `OPAuthenticationException` + +### Documentation +- Documented item editing in `docs/item-editing.md` +- Added set of item editing examples under `examples/item_editing` + +### Misc +- Updated testing configuration in conjuncton with refactored `mock-op` +- Add `FUNDING.yml` +- Have `setup.py` automatically convert relative URLs in `long_description` to absolute GitHub URLs so they work on PyPI + ## [3.12.1] 2023-06-26 ### Fixed diff --git a/Makefile b/Makefile index 3ffb3eb0..15cb74b4 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,10 @@ COV_STAMP=.cov_stamp TOX_STAMP=.tox_stamp HTML_REPORT_STAMP=".html_report_stamp" -PYONEPASSWORD_SRC_FILES=$(shell find ./pyonepassword -name \*\.py -print) +# find all *.py and *.json files under pyonepassword +PYONEPASSWORD_SRC_FILES=$(shell find ./pyonepassword -name \*\.py -print -o -name \*\.json -print) +# find all regular files under tests excluding *.pyc, and reports/ +# this should include *.py, *.json, *.txt plus files without extensions PYONEPASSWORD_TEST_FILES=$(shell find tests -name \*\.pyc -prune -o -name reports -prune -o -type f -print) all: diff --git a/README.md b/README.md index 30e6e14e..73892c24 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A Python API to sign into and query a 1Password account using the `op` command. ## Requirements -- Python >= 3.8 +- Python >= 3.9 - 1Password command-line tool >= 2.0.0 - see [1Password Developer Documentation](https://developer.1password.com/docs/cli) - Internet connectivity to 1Password.com @@ -144,7 +144,7 @@ If you want to fully automate connecting to and querying a 1Password account, th All of these methods return objects types as described above. Also, `item_get()` returns the appropriate object type for the item, such as `OPLoginItem` or `OPSecureNoteItem`, as long as `pyonepassword` has a class for the returned item type. -> *Note*: In some cases the `op` command may return items that don't conform to the expected structure. When this happens, the item dictionary will fail to validate, an exception will be raised. There is API for relaxing item validation, globally, on a per-class basis, or a per-item basis. See [ITEM_VALIDATION.md](ITEM_VALIDATION.md) for more information. +> *Note*: In some cases the `op` command may return items that don't conform to the expected structure. When this happens, the item dictionary will fail to validate, an exception will be raised. There is API for relaxing item validation, globally, on a per-class basis, or a per-item basis. See [item-validation.md](docs/item-validation.md) for more information. ### Sign-in and item retrieval @@ -341,8 +341,16 @@ def main(): ### Item Creation -For details on creating new items in a 1Password vault, see [ITEM_CREATION.md](ITEM_CREATION.md) +For details on creating new items in a 1Password vault, see [item-creation.md](docs/item-creation.md) +Also see the examles in [examples/item_creation](examples/item_creation/) + + +### Item Editing + +For details on editing existing items in a 1Password vault, see [item-editing.md](docs/item-editing.md) + +Also see the examles in [examples/item_editing](examples/item_editing/) ### More Examples diff --git a/docker_testing/build.sh b/docker_testing/build.sh index 3c87881f..7e6f5e8c 100755 --- a/docker_testing/build.sh +++ b/docker_testing/build.sh @@ -2,7 +2,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py38.Dockerfile -t docker_py38 || exit docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py39.Dockerfile -t docker_py39 || exit docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py310.Dockerfile -t docker_py310 || exit docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py311.Dockerfile -t docker_py311 || exit +docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py312.Dockerfile -t docker_py312 || exit diff --git a/docker_testing/clean.sh b/docker_testing/clean.sh index 6b363e30..64787cfa 100755 --- a/docker_testing/clean.sh +++ b/docker_testing/clean.sh @@ -1,4 +1,6 @@ #!/bin/sh -docker image rm docker_py39 docker_py38 docker_py310 docker_py311 +# keep unused docker image names so we can ensure they get removed +# this should not be an error +docker image rm docker_py38 docker_py39 docker_py310 docker_py311 docker_py312 rm -rf .tox-docker diff --git a/docker_testing/docker/py38.Dockerfile b/docker_testing/docker/py312.Dockerfile similarity index 90% rename from docker_testing/docker/py38.Dockerfile rename to docker_testing/docker/py312.Dockerfile index 2745a1d8..e76042aa 100644 --- a/docker_testing/docker/py38.Dockerfile +++ b/docker_testing/docker/py312.Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.8 +FROM python:3.12 RUN useradd -ms /bin/bash unpriv @@ -14,6 +14,6 @@ ENV TESTDIR=/usr/src/testdir # PYVER_FACTOR gets passed to: # tox run -f $PYVER_FACTOR # so e.g., all py311-{something,something-else} envs get run -ENV PYVER_FACTOR=py38 +ENV PYVER_FACTOR=py312 COPY test.sh /test.sh CMD [ "/test.sh" ] diff --git a/docker_testing/run-individual.sh b/docker_testing/run-individual.sh index 00de3a00..af35c771 100755 --- a/docker_testing/run-individual.sh +++ b/docker_testing/run-individual.sh @@ -19,11 +19,7 @@ trap handle_sig INT container="" -if [ "$1" = "py38" ]; -then - container="docker_py38" - shift -elif [ "$1" = "py39" ]; +if [ "$1" = "py39" ]; then container="docker_py39" shift @@ -35,16 +31,20 @@ elif [ "$1" = "py311" ]; then container="docker_py311" shift +elif [ "$1" = "py312" ]; +then + container="docker_py312" + shift fi if [ -z "$container" ]; then - quit "Speciy py38, py39, py310, or py311" 1 + quit "Specify py39, py310, py311, or py312" 1 fi ret=0 -set -x + docker run --rm -it -v "$(pwd):/usr/src/testdir" "$container" /test.sh "$@" ret="$(($?+ret))"; diff --git a/docker_testing/run.sh b/docker_testing/run.sh index b89a5b10..a744abe6 100755 --- a/docker_testing/run.sh +++ b/docker_testing/run.sh @@ -22,13 +22,13 @@ trap handle_sig INT ret=0 -docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py38 /test.sh "$@" -ret="$(($?+ret))" docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py39 /test.sh "$@" ret="$(($?+ret))" docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py310 /test.sh "$@" ret="$(($?+ret))" docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py311 /test.sh "$@" ret="$(($?+ret))" +docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py312 /test.sh "$@" +ret="$(($?+ret))" exit "$ret" diff --git a/docs/AUTHENTICATION.md b/docs/authentication.md similarity index 100% rename from docs/AUTHENTICATION.md rename to docs/authentication.md diff --git a/docs/ITEM_CREATION.md b/docs/item-creation.md similarity index 100% rename from docs/ITEM_CREATION.md rename to docs/item-creation.md diff --git a/docs/item-editing.md b/docs/item-editing.md new file mode 100644 index 00000000..85904613 --- /dev/null +++ b/docs/item-editing.md @@ -0,0 +1,79 @@ +# PYONEPASSWORD ITEM EDITING + +As of version 4.0.0, `pyonepassword` supports in-place item editing. There is API to match the operations supported by the `op item edit` command. This file describes the API as well as its restrictions and limitations. It is recommended to consult `op item edit --help` for any restrictions in addition those enforced by `pyonepassword` described here. + +All of the methods described below are instance methods on the `pyonepassword.OP` class. + +The supported operations break down into two groups: operations that work with arbitrary item fields (and optionally sections), and ones that do not. The first group described are the non-field editing operations, followed by the field editing operations. + + +## Non-field Editing Operations + +The following item editing methods do not operate on arbitrary sections and fields: + +- `OP.item_edit_favorite()` +- `OP.item_edit_generate_password()` +- `OP.item_edit_title()` +- `OP.item_edit_tags()` +- `OP.item_edit_url()` + +> **Note**: Technically `OP.item_edit_generate_password()` operates on a field, but it only works on the built-in "password" field of Login and Password items. + + +## Field Editing Operations + +There are three categories of field-editing operations: + +- Setting a value on an existing field + - Including changing a field's type. E.g., from "text" to "URL" +- Adding a new field, and optionally a section +- Deleting a field + +In all cases, an `item get` operation is first peformed in order to validate the presense or absence of the field being edited. There are different sets of restrictions depending on whether a field is being added, an existing field being assigned a new value, or a field is being deleted. Those restrictions are dicussed below. + + +### Existing Field Value Setting + +If an existing field is being assigned a new value, the original item is retrieved and checked that the requested field/section pairing exist. Any of the following conditions are considered an error: +- A field with the specified label is not found +- If provided, a section with the specified label is not found +- No section is specified, and no matching fields are found that *have no* associated section + +If the existing field is a password field, and setting a new value would change it to some other field type, the `password_downgrade=True` kwarg must be passed. + +*SECURITY NOTE*: The `OP.item_edit_set_password()` method will include the provided password in cleartext as a command line argument to the `op` command. On most platforms, the arguments, including the password, will be visible to other processes, including processes owned by other users. In order to use this operaton, this insecurity must be acknowledged by passing the `insecure_operation=True` kwarg + +The following methods operate on arbitrary fields and sections, provided they already exist: + +- `OP.item_edit_set_password()` +- `OP.item_edit_set_text_field()` +- `OP.item_edit_set_url_field()` + + +### Adding New Fields + +If a new field is being added, the original item is retrieved and checked that the requested field/section pairing *do not* exist. Any of the following conditions are considered an error: +- Ambiguous match: + - one or more fields match the field label and no section label was specified +- Explicit match: + - one or more field/section pairings exist that match the field label & section label + +The following methods will add arbitrary fields and optionally sections, provided they do not already exist: + +- `OP.item_edit_add_text_field()` +- `OP.item_edit_add_password_field()` +- `OP.item_edit_add_url_field()` + + +### Deleting Fields + +When deleting a field, if the field is associated with a section, and the section has no remaining fields, the section will also be deleted. + +Deleting fields has the same restrictions as setting values on existing fields. The original item is retrieved and checked that the requested (field, seciton) pairing exist. Any of the following conditions are considered an error: +- A field with the specified label is not found +- If provided, a section with the specified label is not found +- No section is specified, and no matching fields are found that *have no* associated section + +The following method will delete arbitary fields and optionally sections, provided they already exist: + +- `OP.item_edit_delete_field()` diff --git a/docs/ITEM_VALIDATION.md b/docs/item-validation.md similarity index 100% rename from docs/ITEM_VALIDATION.md rename to docs/item-validation.md diff --git a/examples/item_editing/01-item-edit-existing-field.py b/examples/item_editing/01-item-edit-existing-field.py new file mode 100644 index 00000000..c871ba7e --- /dev/null +++ b/examples/item_editing/01-item-edit-existing-field.py @@ -0,0 +1,21 @@ +from pyonepassword import OP + + +def do_set_text_field(op: OP): + item = "Example Login Item 101" + section_label = "Section 01" + field_label = "Field 01" + field_value = "new text for field 01 " + vault = "Test Data 2" + # item_edit_set_url_field and item_edit_set_password are similar + op.item_edit_set_text_field(item, + field_value, + field_label, + section_label=section_label, + vault=vault) + + +if __name__ == "__main__": + # see README.md for sign-in process + op: OP = OP() + do_set_text_field(op) diff --git a/examples/item_editing/02-item-edit-add-field.py b/examples/item_editing/02-item-edit-add-field.py new file mode 100644 index 00000000..49df380d --- /dev/null +++ b/examples/item_editing/02-item-edit-add-field.py @@ -0,0 +1,21 @@ +from pyonepassword import OP + + +def do_set_text_field(op: OP): + item = "Example Login Item 103" + section_label = "Section 01" + field_label = "New Field 01" + field_value = "new text for field 01 " + vault = "Test Data 2" + # item_edit_add_url_field() and item_edit_add_password_field() are similar + op.item_edit_add_text_field(item, + field_value, + field_label, + section_label=section_label, + vault=vault) + + +if __name__ == "__main__": + # see README.md for sign-in process + op: OP = OP() + do_set_text_field(op) diff --git a/examples/item_editing/03-item-edit-non-field-properties.py b/examples/item_editing/03-item-edit-non-field-properties.py new file mode 100644 index 00000000..16d5f18a --- /dev/null +++ b/examples/item_editing/03-item-edit-non-field-properties.py @@ -0,0 +1,45 @@ +from pyonepassword import OP + + +def edit_non_field_properites(op: OP): + """ + You can edit/set the following non-field properties: + - favorite (set/unset) + - tags (You can set, remove, or add to an item's et of tags) + - autofill URL property for Login items (this does not set URLs on arbitrary fields) + - generate new password for Login or Password items (this does not generate passwords for arbitrary fields) + """ + + item = "Example Login Item 104" + new_item_label = "New Login Item 104" + favorite = True + tags = ["tag_1", "tag_2"] + autofill_url = "https://new-url/login.html" + vault = "Test Data 2" + + # Toggle item favorite flag + op.item_edit_favorite(item, + favorite, + vault=vault) + + # Set or replace item's list of tags + op.item_edit_tags(item, + tags, + append_tags=False, + vault=vault) + + # for Login items, set the website/URL property + op.item_edit_url(item, + autofill_url, + vault=vault) + + # set new item titel + op.item_edit_title(item, + new_item_label, + vault=vault) + + +if __name__ == "__main__": + # see README.md for sign-in process + op: OP = OP() + edit_non_field_properites(op) diff --git a/examples/item_editing/04-item-edit-password-field-restrictions.py b/examples/item_editing/04-item-edit-password-field-restrictions.py new file mode 100644 index 00000000..ffca6077 --- /dev/null +++ b/examples/item_editing/04-item-edit-password-field-restrictions.py @@ -0,0 +1,101 @@ +import sys + +import dotenv + +from pyonepassword import OP +from pyonepassword.api.object_types import OPLoginItem +from pyonepassword.py_op_exceptions import ( # these are intentionally not exported as API + OPInsecureOperationException, + OPPasswordFieldDowngradeException +) + + +def set_password_field(op: OP): + """ + Demonstrate requirement to pass insecure_operation=True + when assigning a new value to a password field + """ + item = "Example Login Item 101" + field_label = "password" + field_value = "really great new password" + vault = "Test Data 2" + + try: + op.item_edit_set_password(item, + field_value, + field_label=field_label, + vault=vault) + except OPInsecureOperationException: + # exception raised because we didn't pass insecure_operation=True + pass + + # must acknowledge insecurity of passing password text as a CLI argument + op.item_edit_set_password(item, + field_value, + field_label=field_label, + vault=vault, + insecure_operation=True) + + +def add_password_field(op: OP): + """ + Demonstrate requirement to pass insecure_operation=True + when adding a new password field + """ + item_label = "Example Login Item 102" + + vault = "Test Data 2" + item: OPLoginItem = op.item_get(item_label, vault=vault) + orig_password = item.password + + field_label = "archived password 01" + section_label = "Archived Passwords" + + # just as with setting existing password fields, when adding a password field + # we must acknowledge insecurity of passing password text as a CLI argument + op.item_edit_add_password_field(item_label, + orig_password, + field_label, + section_label=section_label, + vault=vault, + insecure_operation=True) + + +def change_password_field_to_text(op: OP): + """ + Demonstrate requirement to pass password_downgrade=True + when converting a password field to another type of field + """ + item_label = "Example Login Item 30" + section_label = "Section 01" + field_label = "Change me to Text" + new_field_value = "No longer a password" + vault = "Test Data 2" + + try: + op.item_edit_set_text_field(item_label, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + except OPPasswordFieldDowngradeException as e: + print(e) + + # We have to acknowledge downgrade and that this is not + # an accidental unmasking of a password + op.item_edit_set_text_field(item_label, + new_field_value, + field_label, + section_label=section_label, + vault=vault, + password_downgrade=True) + + +if __name__ == "__main__": + if len(sys.argv) > 1: + dotenv.load_dotenv(sys.argv[1]) + # see README.md for sign-in process + op: OP = OP() + # set_password_field(op) + # add_password_field(op) + change_password_field_to_text(op) diff --git a/item-editing-todo.md b/item-editing-todo.md new file mode 100644 index 00000000..9dafca28 --- /dev/null +++ b/item-editing-todo.md @@ -0,0 +1,31 @@ + +github issue: [143](https://github.com/zcutlip/pyonepassword/issues/143) + +- [x] `OP.item_edit_generate_password()` + - [x] implemented + - [x] tested +- [x] `OP.item_edit_set_password()` + - [x] implemented + - [x] tested +- [x] `OP.item_edit_set_title()` + - [x] implemented + - [x] tested +- [x] `OP.item_edit_set_favorite()` + - [x] implemented + - [x] tested +- [x] `OP.item_edit_set_tags()` + - [x] implemented + - [x] tested +- [x] `OP.item_edit_set_url()` + - [x] implemented + - [x] tested +- [x] Set field types: + - [x] password + - [x] implemented + - [x] tested + - [ ] text + - [ ] implemented + - [ ] tested + - [ ] url + - [ ] implemented + - [ ] tested diff --git a/pyonepassword/__about__.py b/pyonepassword/__about__.py index bdec9742..c99b0192 100644 --- a/pyonepassword/__about__.py +++ b/pyonepassword/__about__.py @@ -1,5 +1,5 @@ __title__ = "pyonepassword" -__version__ = "3.12.1" +__version__ = "4.0.0" __summary__ = "A python API to query a 1Password account using the 'op' command-line tool" """ diff --git a/pyonepassword/_datetime.py b/pyonepassword/_datetime.py index f473fab9..314bc581 100644 --- a/pyonepassword/_datetime.py +++ b/pyonepassword/_datetime.py @@ -1,3 +1,4 @@ +import re from datetime import datetime @@ -12,13 +13,13 @@ def fromisoformat_z(date_string: str) -> datetime: if date_string.endswith('Z'): _str = date_string.rstrip('Z') _str += "+00:00" - elif date_string.endswith("+00:00"): + elif re.match(r".*[+-]\d{2}:\d{2}$", date_string): # We shouldn't ever get this, but we also shouldn't blow up on it, # so work with it if it happens _str = date_string else: # Mirror the ValueError that datetime.fromisoformat() raises raise ValueError( - f"Invalid Z-terminated isoformat string: '{date_string}'") + f"Invalid TZ terminated isoformat string: '{date_string}'") datetime_obj = datetime.fromisoformat(_str) return datetime_obj diff --git a/pyonepassword/_field_assignment.py b/pyonepassword/_field_assignment.py new file mode 100644 index 00000000..a48ccb27 --- /dev/null +++ b/pyonepassword/_field_assignment.py @@ -0,0 +1,116 @@ +import re +from enum import Enum + + +class OPFieldTypeEnum(Enum): + PASSWORD = "password" + TEXT = "text" + URL = "url" + DELETE = "delete" + + +class _OPFieldAssignment(str): + FIELD_TYPE: OPFieldTypeEnum = None + + def __new__(cls, field_label: str, value: str, * args, section_label: str = None, **kwargs): + if cls.FIELD_TYPE is None: + raise TypeError( + f"{cls.__name__} must be extended and FIELD_TYPE set") + assignment_str = "" + field_label = cls._field_assignment_escape(field_label) + field_type_string = cls.FIELD_TYPE.value + if section_label: + section_label = cls._field_assignment_escape(section_label) + assignment_str = f"{section_label}." + + assignment_str += f"{field_label}[{field_type_string}]" + + assignment_str = cls._process_value_str(assignment_str, value) + + return super().__new__(cls, assignment_str) + + @classmethod + def _process_value_str(cls, assignment_str, value): + # HACK: We need to override this in OPFieldAssignmentDelete + # so we can raise an exception is an actual value is passed in + + # intentionally not using string formatting to assign value + # in some cases value will be a RedactedString, so concatenation + # will prevent it from self-redacting + assignment_str += "=" + value + return assignment_str + + @classmethod + def _field_assignment_escape(cls, input_string): + + pattern = r"([.=\\])" + repl = r"\\\1" + escaped_string = re.sub(pattern, repl, input_string) + return escaped_string + + +class OPFieldAssignmentPassword(_OPFieldAssignment): + FIELD_TYPE = OPFieldTypeEnum.PASSWORD + + def __init__(self, *args, **kwargs): + super().__init__() + redacted = self._redact() + self._redacted_assignment = redacted + + def __str__(self): + # NOTE: this is only intended to affect printing/logging of this string + # It DOES NOT make `op item edit` operations more secure. The cleartext password assignment + # is still passed as an argument and visible to other processes + return self._redacted_assignment + + def _redact(self): + lhs, rhs = self.rsplit("=", maxsplit=1) + mask = "*" * len(rhs) + + # introduce an intentional syntax error here + # in case we try to use this redacted string as the actual + # assignment during execution + # This should generate an error + # we don't want to accidentaly set someone's password + # to "*************" + # this is an equals emoji rather than an equals sign + redacted = f"{lhs}🟰{mask}" + return redacted + + +class OPFieldAssignmentText(_OPFieldAssignment): + FIELD_TYPE = OPFieldTypeEnum.TEXT + + +class OPFieldAssignmentURL(_OPFieldAssignment): + FIELD_TYPE = OPFieldTypeEnum.URL + + +class OPFieldAssignmentDelete(_OPFieldAssignment): + FIELD_TYPE = OPFieldTypeEnum.DELETE + + def __new__(cls, field_label: str, *args, section_label: str = None, **kwargs): + # pass None in for value arg + value = None + obj = super().__new__(cls, field_label, value, *args, + section_label=section_label, **kwargs) + return obj + + @classmethod + def _process_value_str(cls, assignment_str, _value): + # This is kind of a hack + # "delete" assignment strings can't have a value + # so we're overriding this method + # and raising an exception if we were passed a value + if _value: + raise ValueError( + "Field assignment value not allowed for OPFieldAssignmentDelete") + return assignment_str + + +FIELD_TYPE_MAP = { + OPFieldTypeEnum.DELETE: OPFieldAssignmentDelete, + OPFieldTypeEnum.PASSWORD: OPFieldAssignmentPassword, + OPFieldTypeEnum.TEXT: OPFieldAssignmentText, + OPFieldTypeEnum.URL: OPFieldAssignmentURL, +} diff --git a/pyonepassword/_op_cli_argv.py b/pyonepassword/_op_cli_argv.py index c80b016b..033ef934 100644 --- a/pyonepassword/_op_cli_argv.py +++ b/pyonepassword/_op_cli_argv.py @@ -1,6 +1,7 @@ import shlex -from typing import List, Optional, Union +from typing import List, Optional, Sequence, Union +from ._field_assignment import FIELD_TYPE_MAP, OPFieldTypeEnum from ._svc_account import OPSvcAcctSupportCode, OPSvcAcctSupportRegistry from .op_items._new_item import OPNewItemMixin from .op_items.password_recipe import OPPasswordRecipe @@ -357,6 +358,125 @@ def item_create_argv(cls, op_exe, "create", sub_cmd_args=item_create_args) return argv + @classmethod + def item_edit_generic_argv(cls, + op_exe: str, + item_identifier: str, + item_edit_args: Sequence[str], + vault: Optional[str] = None): + + # We have to type the item_edit_args param as a Sequence + # not a list because Lists are invariant, and mypy prevents + # us from passing in a subypte like List[SubTypeOfStr] + # + # However, mypy complains if we work with item_edit_args as if + # it's a list without first making it a list, + # hence the list(item_edit_args) + # https://mypy.readthedocs.io/en/latest/generics.html#variance-of-generic-types + # and also: + # https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Arrays + item_edit_args = [item_identifier] + list(item_edit_args) + + if vault: + item_edit_args.extend(["--vault", vault]) + + argv = cls.item_generic_argv( + op_exe, "edit", sub_cmd_args=item_edit_args) + return argv + + @classmethod + def item_edit_set_field_value(cls, + op_exe: str, + item_identifier: str, + field_type: OPFieldTypeEnum, + value: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None): + + field_type_cls = FIELD_TYPE_MAP[field_type] + # this is a hack because OPFieldAssignmentDelete doesn't + # accept a value arg, but the rest require it + if value is not None: + args = [field_label, value] + else: + args = [field_label] + + field_assignment = field_type_cls(*args, section_label=section_label) + + item_edit_args = [field_assignment] + + argv = cls.item_edit_generic_argv( + op_exe, item_identifier, item_edit_args, vault=vault) + return argv + + @classmethod + def item_edit_favorite(cls, + op_exe: str, + item_identifier: str, + favorite: bool, + vault: Optional[str] = None): + title_arg = "true" if favorite else "false" + + item_edit_args = [f"--favorite={title_arg}"] + + argv = cls.item_edit_generic_argv( + op_exe, item_identifier, item_edit_args, vault=vault) + + return argv + + @classmethod + def item_edit_generate_password_argv(cls, + op_exe, + item_identifier: str, + password_recipe: OPPasswordRecipe, + vault: Optional[str] = None): + item_edit_args = [f"--generate-password={password_recipe}"] + + argv = cls.item_edit_generic_argv( + op_exe, item_identifier, item_edit_args, vault=vault) + + return argv + + @classmethod + def item_edit_tags(cls, + op_exe: str, + item_identifier: str, + tags: List[str], + vault: Optional[str] = None): + + tag_arg = ",".join(tags) + item_edit_args = ["--tags", tag_arg] + argv = cls.item_edit_generic_argv( + op_exe, item_identifier, item_edit_args, vault=vault) + + return argv + + @classmethod + def item_edit_title(cls, + op_exe: str, + item_identifier: str, + item_title: str, + vault: Optional[str] = None): + item_edit_args = ["--title", f"{item_title}"] + argv = cls.item_edit_generic_argv( + op_exe, item_identifier, item_edit_args, vault=vault) + + return argv + + @classmethod + def item_edit_url(cls, + op_exe: str, + item_identifier: str, + url: str, + vault: Optional[str] = None): + + item_edit_args = ["--url", f"{url}"] + argv = cls.item_edit_generic_argv( + op_exe, item_identifier, item_edit_args, vault=vault) + + return argv + @classmethod def item_delete_argv(cls, op_exe: str, diff --git a/pyonepassword/_py_op_commands.py b/pyonepassword/_py_op_commands.py index 36180a57..587f4442 100644 --- a/pyonepassword/_py_op_commands.py +++ b/pyonepassword/_py_op_commands.py @@ -1,10 +1,15 @@ """ Description: A module that maps methods to to `op` commands and subcommands """ +from __future__ import annotations + import enum import logging from os import environ -from typing import Dict, Mapping, Optional, Union +from typing import TYPE_CHECKING, Dict, List, Mapping, Optional, Union + +if TYPE_CHECKING: # pragma: no coverage + from pyonepassword._field_assignment import OPFieldTypeEnum from ._op_cli_argv import _OPArgv from ._op_cli_config import OPCLIConfig @@ -21,6 +26,7 @@ MINIMUM_SERVICE_ACCOUNT_VERSION, OPCLIVersion ) +from .op_items.password_recipe import OPPasswordRecipe from .py_op_exceptions import ( OPAuthenticationException, OPCmdFailedException, @@ -31,6 +37,7 @@ OPGroupListException, OPItemCreateException, OPItemDeleteException, + OPItemEditException, OPItemGetException, OPItemListException, OPSigninException, @@ -65,7 +72,8 @@ class _OPCommandInterface(_OPCLIExecute): NO_ACTIVE_SESSION_FOUND_TEXT = "no active session found for account" NO_SESSION_TOKEN_FOUND_TEXT = "could not find session token for account" ACCT_IS_NOT_SIGNED_IN_TEXT = "account is not signed in" - MALFORMED_SVC_ACCT_TEXT = "failed to DecodeSACCredentials" + SVC_ACCT_TOKEN_MALFORMED_TEXT = "failed to DecodeSACCredentials" + SVC_ACCT_TOKEN_NOT_AUTH_TXT = "service account token set, but not authenticated yet" OP_SVC_ACCOUNT_ENV_VAR = "OP_SERVICE_ACCOUNT_TOKEN" OP_PATH = 'op' # let subprocess find 'op' in the system path @@ -101,10 +109,6 @@ def __init__(self, # that got initialized to None or False self._gather_facts() - # Coerce existing_auth to an Enum in case it was passed in as a legacy bool - # False -> ExistingAuthFlag.NONE, True -> ExistingAuthFlag.AVAILABLE - existing_auth = ExistingAuthEnum(existing_auth) - # part of exception message in case incompatible authentication parameters # are provided auth_pref_source = "preference passed as argument" @@ -496,37 +500,84 @@ def _vault_list_argv(self, group_name_or_id=None, user_name_or_id=None): return vault_list_argv @classmethod - def _whoami(cls, op_path, env: Dict[str, str] = None, account: str = None) -> OPAccount: + def _item_template_list_special(cls, op_path, env: Dict[str, str] = None): + if not env: + env = dict(environ) + # special "template list" class method we can use for testing authentication + argv = _OPArgv.item_template_list_argv(op_path) + template_list_json = cls._run( + argv, capture_stdout=True, decode="utf-8", env=env) + return template_list_json + + @classmethod + def _whoami_base(cls, op_path, env: Dict[str, str] = None, account: str = None): if not env: env = dict(environ) argv = _OPArgv.whoami_argv(op_path, account=account) - try: - account_json = cls._run( - argv, capture_stdout=True, decode="utf-8", env=env) - except OPCmdFailedException as ocfe: - # scrape error message about not being signed in + account_json = cls._run( + argv, capture_stdout=True, decode="utf-8", env=env) + return account_json - if cls.MALFORMED_SVC_ACCT_TEXT in ocfe.err_output: - # OP_SERVICE_ACCOUNT_TOKEN got set to something malformed - # so raise a specific exception for that - raise OPCmdMalformedSvcAcctTokenException.from_opexception( - ocfe) # pragma: no cover - # Although we could simulate this for testing, the tests - # wouldn't be meaningful, because they wouldn't be tied to - # an actual malformed token - # disabling testing coverage + @classmethod + def _whoami_svc_account(cls, op_path, env: Dict[str, str] = None): + # whoami behaves differently under certain circumstances if OP_SERVICE_ACCOUNT_TOKEN + # is set, and we need to handle this situations differently + # They include: + # - service account env variable is set, but token is malformed + # - on op >= 2.20.0, service account token is set, but not yet "authenticated" + account_json = None + attempts = 0 + max_attempts = 2 + while account_json is None: + # try once, and if necessary try "item template list" to authenticate + # then try at most one more time + attempts += 1 + try: + account_json = cls._whoami_base(op_path, env=env) + except OPCmdFailedException as ocfe: + if attempts < max_attempts and cls.SVC_ACCT_TOKEN_NOT_AUTH_TXT in ocfe.err_output: + # Trigger a service account authenticated session (v 2.20.0 and later) + cls._item_template_list_special(op_path, env=env) + continue + elif cls.SVC_ACCT_TOKEN_MALFORMED_TEXT in ocfe.err_output: # pragma: no cover + # OP_SERVICE_ACCOUNT_TOKEN got set to something malformed + # so raise a specific exception for that + raise OPCmdMalformedSvcAcctTokenException.from_opexception( + ocfe) + # Although we could simulate this for testing, the tests + # wouldn't be meaningful, because they wouldn't be tied to + # an actual malformed token + # disabling testing coverage + else: + raise # pragma: no cover + + return account_json + + @classmethod + def _whoami(cls, op_path, env: Dict[str, str] = None, account: str = None) -> OPAccount: + # outer/normal whoami method + # if a service account var is set, this method will call + # _whoami_svc_account(), which will call _whoami_base() + # otherwise, this method calls _whoami_base() + + try: + if cls.svc_account_env_var_set(): + account_json = cls._whoami_svc_account(op_path, env=env) else: - raise OPWhoAmiException.from_opexception(ocfe) + account_json = cls._whoami_base( + op_path, env=env, account=account) + except OPCmdFailedException as ocfe: + raise OPWhoAmiException.from_opexception(ocfe) account_obj = OPAccount(account_json) return account_obj def _item_get(self, item_name_or_id, vault=None, fields=None, include_archive=False, decode="utf-8"): - get_item_argv = self._item_get_argv( + item_get_argv = self._item_get_argv( item_name_or_id, vault=vault, fields=fields, include_archive=include_archive) try: output = self._run_with_auth_check( - self.op_path, self._account_identifier, get_item_argv, capture_stdout=True, decode=decode) + self.op_path, self._account_identifier, item_get_argv, capture_stdout=True, decode=decode) except OPCmdFailedException as ocfe: raise OPItemGetException.from_opexception(ocfe) from ocfe @@ -598,10 +649,13 @@ def _document_get(self, raise OPDocumentGetException.from_opexception(ocfe) from ocfe if self._cli_version <= DOCUMENT_BYTES_BUG_VERSION: # pragma: no cover - # op v2.x appends an erroneous \x0a ('\n') byte to document bytes + # op versions 2.0.0 - 2.2.0 append an erroneous \x0a ('\n') byte to document bytes # trim it off if its present if document_bytes[-1] == 0x0a: document_bytes = document_bytes[:-1] + else: + # this shouldn't happen but maybe an edge case? + pass return document_bytes @@ -699,12 +753,28 @@ def _account_forget(cls, account: str, op_path=None): # pragma: no cover cls._run(argv) def _item_list_argv(self, categories=[], include_archive=False, tags=[], vault=None): + # default lists to the categories & list kwargs + # get initialized at module load + # so its the same list object on every call to this funciton + # This really isn't what we want, so the easiest + # mitigation is to just make a copy of whatever list was passed in + # or of the default kwarg if nothing was passed in + categories = list(categories) + tags = list(tags) vault_arg = vault if vault else self.vault list_items_argv = _OPArgv.item_list_argv(self.op_path, categories=categories, include_archive=include_archive, tags=tags, vault=vault_arg) return list_items_argv def _item_list(self, categories=[], include_archive=False, tags=[], vault=None, decode="utf-8"): + # default lists to the categories & list kwargs + # get initialized at module load + # so its the same list object on every call to this funciton + # This really isn't what we want, so the easiest + # mitigation is to just make a copy of whatever list was passed in + # or of the default kwarg if nothing was passed in + categories = list(categories) + tags = list(tags) argv = self._item_list_argv( categories=categories, include_archive=include_archive, tags=tags, vault=vault) try: @@ -716,10 +786,88 @@ def _item_list(self, categories=[], include_archive=False, tags=[], vault=None, def _item_create_argv(self, item, password_recipe, vault): vault_arg = vault if vault else self.vault - create_item_argv = _OPArgv.item_create_argv( + item_create_argv = _OPArgv.item_create_argv( self.op_path, item, password_recipe=password_recipe, vault=vault_arg ) - return create_item_argv + return item_create_argv + + def _item_edit_set_field_value_argv(self, + item_identifier: str, + field_type: OPFieldTypeEnum, + value: str, + field_label: str, + section_label: Optional[str], + vault: Optional[str]): + vault_arg = vault if vault else self.vault + item_edit_argv = _OPArgv.item_edit_set_field_value(self.op_path, + item_identifier, + field_type, + value, + field_label=field_label, + section_label=section_label, + vault=vault_arg) + return item_edit_argv + + def _item_edit_favorite_argv(self, + item_identifier: str, + favorite: bool, + vault: Optional[str]): + vault_arg = vault if vault else self.vault + + item_edit_argv = _OPArgv.item_edit_favorite(self.op_path, + item_identifier, + favorite, + vault=vault_arg) + return item_edit_argv + + def _item_edit_generate_password_argv(self, + item_identifier: str, + password_recipe: OPPasswordRecipe, + vault: Optional[str]): + + vault_arg = vault if vault else self.vault + item_edit_argv = _OPArgv.item_edit_generate_password_argv(self.op_path, + item_identifier, + password_recipe, + vault=vault_arg) + return item_edit_argv + + def _item_edit_tags_argv(self, + item_identifier: str, + tags: List[str], + vault: Optional[str]): + vault_arg = vault if vault else self.vault + + item_edit_argv = _OPArgv.item_edit_tags(self.op_path, + item_identifier, + tags, + vault=vault_arg) + + return item_edit_argv + + def _item_edit_title_argv(self, + item_identifier: str, + item_title: str, + vault: Optional[str]): + vault_arg = vault if vault else self.vault + + item_edit_argv = _OPArgv.item_edit_title(self.op_path, + item_identifier, + item_title, + vault=vault_arg) + return item_edit_argv + + def _item_edit_url_argv(self, + item_identifier: str, + url: str, + vault: Optional[str]): + vault_arg = vault if vault else self.vault + + item_edit_argv = _OPArgv.item_edit_url(self.op_path, + item_identifier, + url, + vault=vault_arg) + return item_edit_argv def _item_create(self, item, vault, password_recipe, decode="utf-8"): argv = self._item_create_argv(item, password_recipe, vault) @@ -730,3 +878,84 @@ def _item_create(self, item, vault, password_recipe, decode="utf-8"): raise OPItemCreateException.from_opexception(e) return output + + def _item_edit_run(self, argv: _OPArgv, decode: str): + try: + output = self._run_with_auth_check( + self.op_path, self._account_identifier, argv, capture_stdout=True, decode=decode) + except OPCmdFailedException as e: + raise OPItemEditException.from_opexception(e) + + return output + + def _item_edit_set_field_value(self, + item_identifier: str, + field_type: OPFieldTypeEnum, + value: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None, + decode: str = "utf-8") -> str: + argv = self._item_edit_set_field_value_argv(item_identifier, + field_type, + value, + field_label=field_label, + section_label=section_label, + vault=vault) + output = self._item_edit_run(argv, decode) + return output + + def _item_edit_favorite(self, + item_identifier: str, + favorite: bool, + vault: Optional[str] = None, + decode: str = "utf-8"): + argv = self._item_edit_favorite_argv( + item_identifier, favorite, vault=vault) + + output = self._item_edit_run(argv, decode) + return output + + def _item_edit_generate_password(self, + item_identifier: str, + password_recipe: OPPasswordRecipe, + vault=None, + decode="utf-8") -> str: + argv = self._item_edit_generate_password_argv( + item_identifier, password_recipe, vault) + + output = self._item_edit_run(argv, decode) + return output + + def _item_edit_tags(self, + item_identifier: str, + tags: List[str], + vault: Optional[str] = None, + decode: str = "utf-8"): + argv = self._item_edit_tags_argv( + item_identifier, tags, vault=vault) + + output = self._item_edit_run(argv, decode) + return output + + def _item_edit_title(self, + item_identifier: str, + item_title: str, + vault: Optional[str] = None, + decode: str = "utf-8"): + argv = self._item_edit_title_argv( + item_identifier, item_title, vault=vault) + + output = self._item_edit_run(argv, decode) + return output + + def _item_edit_url(self, + item_identifier: str, + url: str, + vault: Optional[str] = None, + decode: str = "utf-8"): + argv = self._item_edit_url_argv( + item_identifier, url, vault=vault) + + output = self._item_edit_run(argv, decode) + return output diff --git a/pyonepassword/account.py b/pyonepassword/account.py index bf47d904..d39c2f57 100644 --- a/pyonepassword/account.py +++ b/pyonepassword/account.py @@ -37,15 +37,13 @@ def account_uuid(self) -> str: def shorthand(self) -> Union[str, None]: return self.get("shorthand") - # TODO: Not sure what to do here - # the 'op whoami' dicts when signed in normally - # vs. when using a service account - # are really different - # but neither self-describe (e.g. with an account type or similar) - # so for now, just check if this has a ServiceAccountType key def is_service_account(self) -> bool: svc_acct = False if self.get("ServiceAccountType"): + # op --version < 2.20.0 + svc_acct = True # pragma: no coverage + elif self.get("user_type") == "SERVICE_ACCOUNT": + # op --version >= 2.20.0 svc_acct = True # pragma: no coverage return svc_acct diff --git a/pyonepassword/api/exceptions.py b/pyonepassword/api/exceptions.py index b6c3f101..9ac2fecc 100644 --- a/pyonepassword/api/exceptions.py +++ b/pyonepassword/api/exceptions.py @@ -37,6 +37,7 @@ OPInvalidItemException, OPItemDeleteException, OPItemDeleteMultipleException, + OPItemEditException, OPItemGetException, OPItemListException, OPNotFoundException, @@ -75,6 +76,7 @@ "OPInvalidVaultListException", "OPItemDeleteException", "OPItemDeleteMultipleException", + "OPItemEditException", "OPItemFieldCollisionException", "OPItemGetException", "OPItemListException", diff --git a/pyonepassword/api/object_types.py b/pyonepassword/api/object_types.py index 748f6756..f66147ba 100644 --- a/pyonepassword/api/object_types.py +++ b/pyonepassword/api/object_types.py @@ -13,7 +13,8 @@ from ..op_items.fields_sections.item_field import ( OPConcealedField, OPStringField, - OPTOTPField + OPTOTPField, + OPURLField ) from ..op_items.fields_sections.item_field_base import OPItemField from ..op_items.fields_sections.item_section import OPSection @@ -66,6 +67,7 @@ "OPConcealedField", "OPStringField", "OPTOTPField", + "OPURLField", "OPItemField", "OPSection", "OPLoginItem", diff --git a/pyonepassword/data/svc_acct_commands/item.json b/pyonepassword/data/svc_acct_commands/item.json index 4e6af231..88f44abe 100644 --- a/pyonepassword/data/svc_acct_commands/item.json +++ b/pyonepassword/data/svc_acct_commands/item.json @@ -34,6 +34,11 @@ "--vault" ], "prohibited_options": [] + }, + "edit": { + "has_arg": true, + "required_options":[], + "prohibited_options": [] } } } diff --git a/pyonepassword/logging.py b/pyonepassword/logging.py index af995609..419b91d8 100644 --- a/pyonepassword/logging.py +++ b/pyonepassword/logging.py @@ -12,3 +12,8 @@ def console_logger(name: str, level: int): logger.addHandler(ch) return logger + + +def console_debug_logger(name: str): + logger = console_logger(name, DEBUG) + return logger diff --git a/pyonepassword/op_items/_new_field_registry.py b/pyonepassword/op_items/_new_field_registry.py index b2c02e1d..38b26fda 100644 --- a/pyonepassword/op_items/_new_field_registry.py +++ b/pyonepassword/op_items/_new_field_registry.py @@ -8,8 +8,8 @@ from .fields_sections.item_field_base import OPItemField from .uuid import OPUniqueIdentifierBase32, is_uuid -if TYPE_CHECKING: - from .fields_sections.item_section import OPSection # pragma: no coverage +if TYPE_CHECKING: # pragma: no coverage + from .fields_sections.item_section import OPSection class OPUnknownFieldTypeException(Exception): diff --git a/pyonepassword/op_items/_new_item.py b/pyonepassword/op_items/_new_item.py index 2b4f5083..fa93d78b 100644 --- a/pyonepassword/op_items/_new_item.py +++ b/pyonepassword/op_items/_new_item.py @@ -1,6 +1,8 @@ import json import os +import shutil import tempfile +from pathlib import Path from typing import Dict, List, Optional from ..py_op_exceptions import OPInvalidItemException @@ -13,6 +15,8 @@ from .template_directory import OPTemplateDirectory from .uuid import OPUniqueIdentifierBase32, is_uuid +TEMPLATE_COPY_DST_ENV_VAR = "PYOP_NEW_ITEM_TEMPLATE_CP_DST" + class OPNewItemDataCollisionException(Exception): pass @@ -236,6 +240,11 @@ def secure_tempfile(self, encoding="utf8") -> str: self._temp_files.append(temp.name) json.dump(self, temp) temp.close() + template_dest_dir = os.environ.get(TEMPLATE_COPY_DST_ENV_VAR, None) + if template_dest_dir: + # _copy_template() does no error handling + # only call if we were given a template copy destination + self._copy_template(temp.name, template_dest_dir) return temp.name def supports_passwords(self) -> bool: @@ -248,6 +257,20 @@ def supports_passwords(self) -> bool: """ return self.PASSWORDS_SUPPORTED + def _copy_template(self, template_src, template_dest_dir): + """ + Optionally make a backup copy of the new item template + if PYOP_NEW_ITEM_TEMPLATE_CP_DST environment variable is set + for debugging/troubleshooting + + This method intentionally does minimal error handling. It should only be called + for troublehooting purposes and any errors creating the destination or copying the source + should be fatal errors + """ + template_dest_dir = Path(template_dest_dir) + template_dest_dir.mkdir(parents=True, exist_ok=True) + shutil.copy2(template_src, template_dest_dir) + def __del__(self): # if we blow up during object initialization diff --git a/pyonepassword/op_items/fields_sections/_new_fields.py b/pyonepassword/op_items/fields_sections/_new_fields.py index 38bafa59..cf4a260f 100644 --- a/pyonepassword/op_items/fields_sections/_new_fields.py +++ b/pyonepassword/op_items/fields_sections/_new_fields.py @@ -193,7 +193,7 @@ def __init__(self, field_label: str, value: Union[str, int], field_id: str = Non value = str(value) else: # if we were passed any other object type this is an error - raise ValueError( + raise TypeError( f"Invalid value for port: \"{value}\". Must be int or str") # NOTE: we're not going to enforce valid, non-negative port ranges diff --git a/pyonepassword/op_items/fields_sections/item_field.py b/pyonepassword/op_items/fields_sections/item_field.py index ea4efb68..9b05a962 100644 --- a/pyonepassword/op_items/fields_sections/item_field.py +++ b/pyonepassword/op_items/fields_sections/item_field.py @@ -13,7 +13,7 @@ class OPConcealedField(OPItemField): @op_register_item_field_type -class OPTOTPField(OPStringField): +class OPTOTPField(OPItemField): FIELD_TYPE = "OTP" @property @@ -23,3 +23,8 @@ def totp_secret(self) -> str: @property def totp(self) -> str: return self["totp"] + + +@op_register_item_field_type +class OPURLField(OPItemField): + FIELD_TYPE = "URL" diff --git a/pyonepassword/op_items/fields_sections/item_field_base.py b/pyonepassword/op_items/fields_sections/item_field_base.py index d9637643..7295c50e 100644 --- a/pyonepassword/op_items/fields_sections/item_field_base.py +++ b/pyonepassword/op_items/fields_sections/item_field_base.py @@ -2,19 +2,46 @@ class OPItemField(dict): + """ + Object type representing a field dictionary in a 1Password item + """ FIELD_TYPE: Union[str, None] = None def __init__(self, field_dict): + """ + Initialize an OPItemField object + + Parameters + ---------- + field_dict : Dict[str, Any] + The field dictionary found inside an item dictionary + """ super().__init__(field_dict) @property def field_id(self) -> str: + """ + Property corresponding the the "id" element of a field object. + This is the unique (within a given item object) identifier of the field, and not + the user-visible label + + Returns + ------- + str + The unique Field ID string + """ return self["id"] @property def label(self) -> str: """ - Returns the field label as assigned and seen in the 1Password UI + Property corresponding to the "label" element of a field object. + This is the field label as assigned and seen in the 1Password UI + + Returns + ------- + str + The label string """ return self["label"] @@ -36,18 +63,53 @@ def field_type(self) -> str: @property def reference(self) -> Union[str, None]: + """ + Property corresponding to the "reference" element of a field object. + This is the 'op://' URI allowing this field to be referenced directly by 'op' + + Returns + ------- + Union[str, None] + The reference URI string + """ return self.get("reference") @property def purpose(self) -> str: + """ + Property corresponding to the "purpose" element of a field object. + This value identifies the type of field, e.g., "PASSWORD," or "USERNAME" + + Returns + ------- + str + The purpose string + """ return self["purpose"] @property def entropy(self) -> Union[float, None]: + """ + Property corresponding to the "entropy" element of a field object + This is typicaly associated with password field types + + Returns + ------- + Union[float, None] + The entropy value + """ return self.get("entropy") @property def section_id(self) -> Union[str, None]: + """ + The unique identifier of the section this field is associated with, if any + + Returns + ------- + Union[str, None] + The section ID + """ section_id = None section = self.get("section") if section: diff --git a/pyonepassword/op_items/fields_sections/item_section.py b/pyonepassword/op_items/fields_sections/item_section.py index 9dcc00e3..ff83f126 100644 --- a/pyonepassword/op_items/fields_sections/item_section.py +++ b/pyonepassword/op_items/fields_sections/item_section.py @@ -2,6 +2,7 @@ from typing import List, Union from ...py_op_exceptions import OPInvalidItemException +from ..field_registry import OPItemFieldFactory from .item_field_base import OPItemField @@ -13,8 +14,24 @@ class OPSectionCollisionException(Exception): pass +class OPFieldNotFoundException(Exception): + pass + + class OPSection(dict): + """ + Object type representing a section dictionary in a 1Password item + """ + def __init__(self, section_dict): + """ + Initialize an OPSection object + + Parameters + ---------- + section_dict : Dict[str, Any] + The section dictionary found inside an item dictionary + """ super().__init__(section_dict) # shadow fields map makes it easy to detect collisions # by looking up a field's ID to see if it's already been registered @@ -24,7 +41,7 @@ def __init__(self, section_dict): def section_id(self) -> str: """ Returns the section ID which may or may not be related to - the user-visible title. + the user-visible label It may be a lower-case transformation, like 'additional passwords' Or it may be something completely opaque, like 'Section_967FEBAC931841BCBD2DD7CFE0B8DC82' @@ -41,6 +58,14 @@ def label(self) -> str: @property def fields(self) -> List[OPItemField]: + """ + Property representing the list of OPItemField objects associated with this section + + Returns + ------- + List[OPItemField] + The list of field objects + """ field_list = self.setdefault("fields", []) return field_list @@ -49,7 +74,7 @@ def register_field(self, field_dict: Union[OPItemField, dict], relaxed_validatio # make a copy of the field so we don't end up with a circular reference field = copy.copy(field_dict) else: - field = OPItemField(field_dict) + field = OPItemFieldFactory.item_field(field_dict) try: field_id = field.field_id @@ -79,10 +104,27 @@ def register_field(self, field_dict: Union[OPItemField, dict], relaxed_validatio self._shadow_fields[field_id] = field self.fields.append(field) - def fields_by_label(self, label, case_sensitive=True) -> List[OPItemField]: + def fields_by_label(self, label: str, case_sensitive: bool = True) -> List[OPItemField]: """ - Returns all fields in a section matching the given label. - Fields are not required to have unique labels, so there may be more than one match. + Returns a list of one or more fields matching the given label + + Note: Field labels are not guaranteed to be unique, so more than one field may be returned + Parameters + ---------- + label : str + The user-visible label string to search for + case_sensitive : bool, optional + Match field labels case-sensitively, by default True + + Returns + ------- + List[OPItemField] + The list of matching fields + + Raises + ------ + OPFieldNotFoundException + If no matching fields are found """ matching_fields = [] f: OPItemField @@ -93,12 +135,33 @@ def fields_by_label(self, label, case_sensitive=True) -> List[OPItemField]: label = label.lower() if f_label == label: matching_fields.append(f) + if not matching_fields: + raise OPFieldNotFoundException( + f"No fields found by label '{label}'") return matching_fields - def first_field_by_label(self, label: str, case_sensitive=True): + def first_field_by_label(self, label: str, case_sensitive: bool = True): """ - Convenience function for when you're certain there's only one field - by a given label, or don't really care for whatever reason + Convenience function to return the first matching field + + Note: field labels are not guaranteed to be unique, or in a particular order, so there may + be more than one match, in which case the first is returned + + Parameters + ---------- + label : str + The user-visible label string to search for + case_sensitive : bool, optional + Match field labels case-insensitively, by default True + + Returns + ------- + OPItemField + The matching field + Raises + ------ + OPFieldNotFoundException + If no matching fields are found """ fields = self.fields_by_label(label, case_sensitive=case_sensitive) f = fields[0] diff --git a/pyonepassword/op_items/item_types/_item_base.py b/pyonepassword/op_items/item_types/_item_base.py index 5baa9fd2..1b12196f 100644 --- a/pyonepassword/op_items/item_types/_item_base.py +++ b/pyonepassword/op_items/item_types/_item_base.py @@ -1,10 +1,12 @@ from typing import Dict, List, Optional, Union from ..._abc_meta import enforcedmethod +from ..._py_op_deprecation import deprecated from ...py_op_exceptions import OPInvalidItemException from ..field_registry import OPItemFieldFactory from ..fields_sections.item_field_base import OPItemField from ..fields_sections.item_section import ( + OPFieldNotFoundException, OPItemFieldCollisionException, OPSection, OPSectionCollisionException @@ -17,10 +19,6 @@ class OPSectionNotFoundException(Exception): pass -class OPFieldNotFoundException(Exception): - pass - - class OPAbstractItem(OPAbstractItemDescriptor): CATEGORY: Optional[str] = None FROM_TEMPLATE = False @@ -61,10 +59,28 @@ def relaxed_validation(self) -> bool: relaxed = get_relaxed_validation(item_class=self.__class__) return relaxed - def sections_by_label(self, label, case_sensitive=True) -> List[OPSection]: + def sections_by_label(self, section_label: str, case_sensitive: bool = True) -> List[OPSection]: """ - Returns a list of zero or more sections matching the given title. - Sections are not required to have unique titles, so there may be more than one match. + Returns a list of one or more sections matching the given label. + + Note: Sections are not required to have unique labels, so there may be more than one match. + + Parameters + ---------- + section_label : str + The user-visible label string to search for + case_sensitive : bool, optional + Match section labels case-sensitively, by default True + + Returns + ------- + List[OPSection] + The list of matching sections + + Raises + ------ + OPSectionNotFoundException + If no sections are found matching the given label """ matching_sections = [] sect: OPSection @@ -72,10 +88,13 @@ def sections_by_label(self, label, case_sensitive=True) -> List[OPSection]: s_label = sect.label if not case_sensitive: s_label = s_label.lower() - label = label.lower() - if s_label == label: + section_label = section_label.lower() + if s_label == section_label: matching_sections.append(sect) + if not matching_sections: + raise OPSectionNotFoundException( + f"No sections found with label '{section_label}'") return matching_sections def section_by_id(self, section_id) -> OPSection: @@ -87,20 +106,46 @@ def section_by_id(self, section_id) -> OPSection: return section - def first_section_by_label(self, label, case_sensitive=True) -> Optional[OPSection]: - sections = self.sections_by_label(label, case_sensitive=case_sensitive) + def first_section_by_label(self, section_label, case_sensitive=True) -> Optional[OPSection]: + """ + Convenience function to return the first matching section + + Note: Sections are not required to have unique labels, so there may be more than one match. + + Parameters + ---------- + label : str + The user-visible label string to search for + case_sensitive : bool, optional + Match section labels case-insensitively, by default True + + Returns + ------- + OPSection + The matching section + Raises + ------ + OPSectionNotFoundException + If no matching sections are found + """ + sections = self.sections_by_label( + section_label, case_sensitive=case_sensitive) section = None if sections: section = sections[0] return section - def field_value_by_section_title(self, section_title: str, field_label: str): - section = self.first_section_by_label(section_title) + def field_value_by_section_label(self, section_label: str, field_label: str): + section = self.first_section_by_label(section_label) value = None if section is not None: value = self._field_value_from_section(section, field_label) return value + @deprecated("use item.field_value_by_section_label") + def field_value_by_section_title(self, section_title: str, field_label: str): + return self.field_value_by_section_label(section_title, field_label) # pragma: no coverage + def field_by_id(self, field_id) -> OPItemField: try: field = self._field_map[field_id] @@ -110,6 +155,27 @@ def field_by_id(self, field_id) -> OPItemField: return field def fields_by_label(self, field_label: str, case_sensitive=True) -> List[OPItemField]: + """ + Returns a list of one or more fields matching the given label + + Note: Field labels are not guaranteed to be unique, so more than one field may be returned + Parameters + ---------- + label : str + The user-visible label string to search for + case_sensitive : bool, optional + Match field labels case-sensitively, by default True + + Returns + ------- + List[OPItemField] + The list of matching fields + + Raises + ------ + OPFieldNotFoundException + If no matching fields are found + """ fields = [] f: OPItemField for _, f in self._field_map.items(): @@ -120,9 +186,34 @@ def fields_by_label(self, field_label: str, case_sensitive=True) -> List[OPItemF if f_label == field_label: fields.append(f) + if not fields: + raise OPFieldNotFoundException( + f"No fields found by label '{field_label}'") return fields def first_field_by_label(self, field_label: str, case_sensitive=True) -> OPItemField: + """ + Convenience function to return the first matching field + + Note: field labels are not guaranteed to be unique, or in a particular order, so there may + be more than one match, in which case the first is returned + + Parameters + ---------- + label : str + The user-visible label string to search for + case_sensitive : bool, optional + Match field labels case-insensitively, by default True + + Returns + ------- + OPItemField + The matching field + Raises + ------ + OPFieldNotFoundException + If no matching fields are found + """ fields = self.fields_by_label( field_label, case_sensitive=case_sensitive) f = fields[0] diff --git a/pyonepassword/op_items/item_types/login.py b/pyonepassword/op_items/item_types/login.py index 87ec67aa..ddb49607 100644 --- a/pyonepassword/op_items/item_types/login.py +++ b/pyonepassword/op_items/item_types/login.py @@ -97,12 +97,12 @@ def __init__(self, item_dict_or_json): self._primary_url = primary_url @property - def username(self): + def username(self) -> str: username = self.field_value_by_id("username") return username @property - def password(self): + def password(self) -> str: password = self.field_value_by_id("password") return password diff --git a/pyonepassword/op_items/item_types/server.py b/pyonepassword/op_items/item_types/server.py index ae3c38a6..5906afb6 100644 --- a/pyonepassword/op_items/item_types/server.py +++ b/pyonepassword/op_items/item_types/server.py @@ -41,19 +41,19 @@ def url(self) -> Optional[str]: @property def admin_console_password(self) -> Optional[str]: - password = self.field_value_by_section_title( + password = self.field_value_by_section_label( "Admin Console", "console password") return password @property def admin_console_username(self) -> Optional[str]: - username = self.field_value_by_section_title( + username = self.field_value_by_section_label( "Admin Console", "admin console username") return username @property def admin_console_url(self) -> Optional[str]: - url = self.field_value_by_section_title( + url = self.field_value_by_section_label( "Admin Console", "admin console URL") return url @@ -69,7 +69,7 @@ def hosting_provider_name(self) -> Optional[str]: """ # Note: the actual field ID and label are "name" # so we look it up by section to be sure - return self.field_value_by_section_title("Hosting Provider", "name") + return self.field_value_by_section_label("Hosting Provider", "name") @property def hosting_provider_website(self) -> Optional[str]: @@ -83,7 +83,7 @@ def hosting_provider_website(self) -> Optional[str]: """ # Note: the actual field ID and label are "name" # so we look it up by section to be sure - return self.field_value_by_section_title("Hosting Provider", "website") + return self.field_value_by_section_label("Hosting Provider", "website") @property def support_contact_url(self) -> Optional[str]: diff --git a/pyonepassword/op_items/password_recipe.py b/pyonepassword/op_items/password_recipe.py index 4c3a3753..0f6f8dd2 100644 --- a/pyonepassword/op_items/password_recipe.py +++ b/pyonepassword/op_items/password_recipe.py @@ -3,7 +3,50 @@ class OPInvalidPasswordRecipeException(Exception): class OPPasswordRecipe: + """ + Class for generating an 'op' password recipe string + + From 'op' help text: + + You can customize the password with a password recipe. Specify the + password length and which character types to use in a comma-separated + list. Ingredients are: + + - 'letters' for uppercase and lowercase letters + - 'digits' for numbers + - 'symbols' for special characters ('!@.-_*') + - '1' - '64' for password length + + """ + MIN_PASSWD_LEN = 1 + MAX_PASSWD_LEN = 64 + def __init__(self, length: int = 20, letters=True, digits=True, symbols=True): + """ + Create a OPPasswordRecipe object for passing to the 'op' command for password generation + + Parameters + ---------- + length : int, optional + Length of the password to generate, by default 20 + letters : bool, optional + generated password should include letters, by default True + digits : bool, optional + generated password should include digits, by default True + symbols : bool, optional + generated password should include symbols, by default True + + Raises + ------ + OPInvalidPasswordRecipeException + If: + - The specified length is outside the range (1-64) accepted by the 'op' command + - If at least one of letters, digits, or symbols is not requested + """ + if length < self.MIN_PASSWD_LEN or length > self.MAX_PASSWD_LEN: + raise OPInvalidPasswordRecipeException( + f"Invalid password length: {length}") + recipe_parts = [str(length)] if True not in [letters, digits, symbols]: @@ -23,6 +66,52 @@ def __str__(self) -> str: recipe_str = ",".join(self.recipe) return recipe_str + @classmethod + def from_string(cls, password_recipe: str): + """ + Class method for transforming a password recipe string into a OPPasswordRecipe object + + Primarily for validating password recipe strings + + Parameters + ---------- + password_recipe : str + The password recipe string to parse and validate + + Raises + ------ + OPInvalidPasswordRecipeException + If: + - The recipe contains a component not recognized by 'op' + - The recipe is not valid per OPPasswordRecipe's initializer (see constructor docstring) + """ + letters = False + digits = False + symbols = False + + parts = password_recipe.split(",") + + # password length will be validated in __init__() + try: + passwd_len = int(parts.pop(0)) + except ValueError: + raise OPInvalidPasswordRecipeException( + "Recipe must start with password length in the range 1-64") + + for part in parts: + if part == "letters": + letters = True + elif part == "digits": + digits = True + elif part == "symbols": + symbols = True + else: + raise OPInvalidPasswordRecipeException( + f"Invalid password recipe component: {part}") + recipe = cls(length=passwd_len, letters=letters, + digits=digits, symbols=symbols) + return recipe + LETTERS_DIGITS_SYMBOLS_20 = OPPasswordRecipe() LETTERS_DIGITS_25 = OPPasswordRecipe(length=25, symbols=False) diff --git a/pyonepassword/py_op_exceptions.py b/pyonepassword/py_op_exceptions.py index d9d0745e..60e3e1ef 100644 --- a/pyonepassword/py_op_exceptions.py +++ b/pyonepassword/py_op_exceptions.py @@ -7,10 +7,8 @@ import warnings from typing import TYPE_CHECKING, List, Optional -from ._py_op_deprecation import deprecated - -if TYPE_CHECKING: - from .op_items._item_list import OPItemList # pragma: no coverage +if TYPE_CHECKING: # pragma: no coverage + from .op_items._item_list import OPItemList class OPBaseException(Exception): @@ -212,6 +210,13 @@ def __init__(self, stderr_out, returncode): super().__init__(stderr_out, returncode) +class OPItemEditException(OPCmdFailedException): # pragma: no coverage + MSG = "1Password 'item edit' failed." + + def __init__(self, stderr_out, returncode): + super().__init__(stderr_out, returncode) + + class OPWhoAmiException(OPCmdFailedException): MSG = "1Password 'whoami' failed" @@ -244,22 +249,7 @@ def __init__(self, msg): super().__init__(msg) -@deprecated("Use OPAuthenticationException") -class OPNotSignedInException(OPBaseException): - """ - DEPRECATION NOTE: - This exception class is deprecated in favor of OPAuthenticationException - and will be removed in a future version - - Exception indicating the `op` command is not authenticated or is unable to complete - authentication - """ - - def __init__(self, msg): - super().__init__(msg) - - -class OPAuthenticationException(OPNotSignedInException): +class OPAuthenticationException(OPBaseException): # TODO: inherit from OPBaseException once # OPNotSignedInException removed """ @@ -291,6 +281,21 @@ class OPConfigNotFoundException(Exception): class OPInvalidFieldException(OPBaseException): + """ + There was an error decoding the JSON for this field + """ + + def __init__(self, msg): + super().__init__(msg) + + +class OPFieldExistsException(OPBaseException): + """ + When adding a new field during an item edit operation, a field + already exists with the same name associated with the same section + (if a section is specified) + """ + def __init__(self, msg): super().__init__(msg) @@ -300,14 +305,45 @@ def __init__(self, msg): super().__init__(msg) -_deprecated_exceptions = { - OPNotSignedInException.__name__: OPAuthenticationException.__name__ +class OPInsecureOperationException(OPBaseException): + """ + An exception class to prevent inadvertent insecure operations. + + This class should be used in conjuction with an override argument + so that the caller may acknowledge and accept the risk + + e.g., op.item_edit_set_password(item_name, + new_password, + insecure_operation=True) + """ + + def __init__(self, msg): + super().__init__(msg) + + +class OPPasswordFieldDowngradeException(OPBaseException): + """ + When setting a field value during an item edit operation and the existing field + if of type CONCEALED, and the new value would be some other type + + e.g., setting a passsword field to a string or URL field + """ + + def __init__(self, msg): + super().__init__(msg) + + +_deprecated_exceptions = { # type: ignore + # (mypy is satisifed when this dict is populated, but com) complains when it's empty + # Leaving this here but commented as an example how to + # deprecate Exceptions + # OPNotSignedInException.__name__: OPAuthenticationException.__name__ } # replace OPNotSignedInException with _OPNotSignedInException # in order to trigger deprecation warnings -_OPNotSignedInException = OPNotSignedInException -del OPNotSignedInException +# _OPNotSignedInException = OPNotSignedInException +# del OPNotSignedInException def __getattr__(name: str): diff --git a/pyonepassword/pyonepassword.py b/pyonepassword/pyonepassword.py index d1e80391..b8946697 100644 --- a/pyonepassword/pyonepassword.py +++ b/pyonepassword/pyonepassword.py @@ -1,19 +1,29 @@ +from __future__ import annotations + import fnmatch import logging from os import environ as env -from typing import List, Optional, Type, Union +from typing import TYPE_CHECKING, List, Optional, Type, Union + +if TYPE_CHECKING: # pragma: no coverage + from .op_items.fields_sections.item_field import OPItemField +from ._field_assignment import OPFieldTypeEnum from ._py_op_commands import ( EXISTING_AUTH_IGNORE, ExistingAuthEnum, _OPCommandInterface ) -from ._py_op_deprecation import deprecated_kwargs from .account import OPAccountList from .op_items._item_list import OPItemList from .op_items._item_type_registry import OPItemFactory from .op_items._new_item import OPNewItemMixin -from .op_items.item_types._item_base import OPAbstractItem +from .op_items.fields_sections.item_field import OPConcealedField +from .op_items.fields_sections.item_section import OPFieldNotFoundException +from .op_items.item_types._item_base import ( + OPAbstractItem, + OPSectionNotFoundException +) from .op_items.item_types.generic_item import ( _OPGenericItem, _OPGenericItemRelaxedValidation @@ -36,15 +46,19 @@ OPCmdFailedException, OPDocumentDeleteException, OPDocumentGetException, + OPFieldExistsException, OPForgetException, + OPInsecureOperationException, OPInvalidDocumentException, OPInvalidItemException, OPItemDeleteException, OPItemDeleteMultipleException, OPItemGetException, OPItemListException, + OPPasswordFieldDowngradeException, OPSignoutException ) +from .string import RedactedString from .version import PyOPAboutMixin @@ -52,14 +66,11 @@ class OP(_OPCommandInterface, PyOPAboutMixin): """ Class for logging into and querying a 1Password account via the 'op' cli command. """ - @deprecated_kwargs(use_existing_session='existing_auth', - account_shorthand='account') + def __init__(self, account: Optional[str] = None, - account_shorthand: Optional[str] = None, password: Optional[str] = None, existing_auth: ExistingAuthEnum = EXISTING_AUTH_IGNORE, - use_existing_session: bool = False, password_prompt: bool = True, vault: Optional[str] = None, op_path: str = 'op', @@ -111,231 +122,111 @@ def __init__(self, existing_auth=existing_auth, password_prompt=password_prompt) - def item_get(self, item_identifier, vault=None, include_archive=False, generic_okay=False, relaxed_validation=False) -> OPAbstractItem: + def document_get(self, document_name_or_id, vault=None, include_archive=False, relaxed_validation=False): """ - Get an 'item' object from a 1Password vault. - The returned object may be any of the item types extending OPAbstractItem. - These currently include: - - OPLoginItem - - OPCreditCardItem - - OPSecureNoteItem - - OPPasswordItem - - OPDocumentItem - - OPServerItem - - OPDatabaseItem - - Note that getting a document item is not the same as getting the document itself. The - item only contains metadata about the document such as filename. + Download a document object from a 1Password vault by name or UUID. Parameters ---------- - item_identifier: str - Name or ID of the item to look up + document_name_or_id : str + The item to look up vault: str, optional - The name or ID of a vault to override the object's default vault, by default None - include_archive: bool, optional - Include items in the Archive, by default False - generic_okay: bool, optional - Instantiate unknown item types as _OPGenericItem rather than raise OPUnknownItemException + The name or ID of a vault to override the object's default vault relaxed_validation: bool, optional Whether to enable relaxed item validation for this query, in order to parse non-conformant data by default False - Note: - If a non-unique item identifier is provided (e.g., item name/title), and there - is more than one item that matches, OPItemGetException will be raised. Check the - error message in OPItemGetException.err_output for details - - Raises - ------ - OPItemGetException - If the lookup fails for any reason during command execution - OPInvalidItemException - If the item JSON fails to decode - OPUnknownItemTypeException - If the item object returned by 1Password isn't a known type and generic_okay is False - OPNotFoundException - If the 1Password command can't be found - Returns - ------- - item: OPAbstractItem - An item object of one of the types listed above - - Service Account Support - ----------------------- - Supported - required keyword arguments: vault - """ - - output = super()._item_get(item_identifier, vault=vault, - decode="utf-8", include_archive=include_archive) - op_item = OPItemFactory.op_item( - output, generic_okay=generic_okay, relaxed_validation=relaxed_validation) - return op_item - - def item_get_totp(self, item_identifier: str, vault=None) -> OPTOTPItem: - """ - Get a TOTP code from the item specified by name or UUID. - - Note: Items in the Archive are ignored by default. To get the TOTP for an - item in the Archive, specify the item by UUID. - - Parameters - ---------- - item_identifier: str - Name or ID of the item to look up - vault: str, optional - The name or ID of a vault to override the object's default vault - - Note: - If a non-unique item identifier is provided (e.g., item name/title), and there - is more than one item that matches, OPItemGetException will be raised. Check the - error message in OPItemGetException.err_output for details - Raises ------ - OPItemGetException - If the lookup fails for any reason during command execution + OPInvalidDocumentException + If the retrieved item isn't a document object or lacks a documents expected attributes + OPDocumentGetException + If document lookup fails for any reason during command execution OPNotFoundException If the 1Password command can't be found Returns ------- - totp_code: str - A string representing the TOTP code + file_name, document bytes: Tuple[str, bytes] + A tuple consisting of the filename and bytes of the specified document Service Account Support ----------------------- Supported required keyword arguments: vault """ - output = super()._item_get_totp(item_identifier, vault=vault, decode="utf-8") - # strip newline - totp = OPTOTPItem(output) - return totp - - def user_get(self, user_name_or_id: str) -> OPUser: - """ - Return the details for the user specified by name or UUID. - - Parameters - ---------- - user_name_or_id: str - Name or ID of the user to look up - Raises - ------ - OPUserGetException - If the lookup fails for any reason during command execution - OPNotFoundException - If the 1Password command can't be found + try: + file_name = self.item_get_filename( + document_name_or_id, vault=vault, include_archive=include_archive, relaxed_validation=relaxed_validation) + except AttributeError as ae: + raise OPInvalidDocumentException( + "Item has no 'fileName' attribute") from ae + except OPCmdFailedException as ocfe: + raise OPDocumentGetException.from_opexception(ocfe) from ocfe - Returns - ------- - user: OPuser - An object representing the details of the requested user + try: + document_bytes = self._document_get(document_name_or_id, + vault=vault, include_archive=include_archive) + except OPCmdFailedException as ocfe: + raise OPDocumentGetException.from_opexception(ocfe) from ocfe - Service Account Support - ----------------------- - Supported - """ - user_json = super()._user_get(user_name_or_id) - user = OPUser(user_json) - return user + return (file_name, document_bytes) - def user_list(self, group_name_or_id=None, vault_name_or_id=None) -> OPUserDescriptorList: + def document_delete(self, document_identifier: str, vault: Optional[str] = None, archive: bool = False, relaxed_validation: bool = False) -> str: """ - Return a list of users in an account. + Delete a document object based on document name or unique identifier Parameters ---------- - group_name_or_id: str - Name or ID of a group to restrict user listing to - vault_name_or_id: str - Name or ID of a vault to restrict user listing to - - Raises - ------ - OPUserListException - If the user list operation for any reason during command execution - OPNotFoundException - If the 1Password command can't be found - + document_identifier : str + Name or identifier of the document to delete + vault : str, optional + The name or ID of a vault to override the default vault, by default None + archive : bool, optional + Whether to archive or permanently delete the item, by default False + relaxed_validation: bool, optional + Whether to enable relaxed item validation for this query, in order to parse non-conformant data + by default False Returns ------- - user: OPUserDescriptorList - An object representing a list of user descriptors - - Service Account Support - ----------------------- - Supported - """ - user_list: Union[str, OPUserDescriptorList] - - user_list = self._user_list( - group_name_or_id=group_name_or_id, vault=vault_name_or_id) - user_list = OPUserDescriptorList(user_list) - return user_list - - def vault_get(self, vault_name_or_id: str) -> OPVault: - """ - Return the details for the vault specified by name or UUID. - - Parameters - ---------- - vault_name_or_id: str - Name or UUID of the vault to look up + document_id: str + Unique identifier of the item deleted Raises ------ - OPVaultGetException - If the lookup fails for any reason during command execution - OPNotFoundException - If the 1Password command can't be found - - Returns - ------- - vault: OPVault - An object representing the details of the requested vault + OPDocumentDeleteException + - If the document to be deleted is not found + - If there is more than one item matching 'document_identifier' + - If the delete operation fails for any other reason Service Account Support ----------------------- Supported - prohibited keyword arguments: group, user - """ - vault_json = super()._vault_get(vault_name_or_id, decode="utf-8") - vault = OPVault(vault_json) - return vault - - def vault_list(self, group_name_or_id=None, user_name_or_id=None) -> OPVaultDescriptorList: + required keyword arguments: vault """ - Return a list of vaults in an account. - Parameters - ---------- - group_name_or_id: str - Name or ID of a group to restrict vault listing to - user_name_or_id: str - Name or ID of a user to restrict vault listing to + # to satisfy mypy + generic_item_class: Type[_OPGenericItem] + if relaxed_validation: + generic_item_class = _OPGenericItemRelaxedValidation + else: + generic_item_class = _OPGenericItem - Raises - ------ - OPVaultListException - If the vault list operation for any reason during command execution - OPNotFoundException - If the 1Password command can't be found + try: + output = self._item_get(document_identifier, vault=vault) + item = generic_item_class(output) + except OPItemGetException as e: + raise OPDocumentDeleteException.from_opexception(e) + # we want to return the explicit ID even if we were + # given an document name or other identifier + # that way the caller knows exactly what got deleted + # can match it up with what they expected to be deleted, if desired + document_id = item.unique_id - Returns - ------- - user: OPVaultDescriptorList - An object representing a list of vault descriptors + # 'op document delete' doesn't have any stdout, so we're not + # capturing any here + self._document_delete(document_id, vault=vault, archive=archive) - Service Account Support - ----------------------- - Supported - """ - vault_list_json = super()._vault_list( - group_name_or_id=group_name_or_id, user_name_or_id=user_name_or_id) - vault_list = OPVaultDescriptorList(vault_list_json) - return vault_list + return document_id def group_get(self, group_name_or_id: str) -> OPGroup: """ @@ -362,7 +253,7 @@ def group_get(self, group_name_or_id: str) -> OPGroup: ----------------------- Supported """ - group_json = super()._group_get(group_name_or_id, decode="utf-8") + group_json = self._group_get(group_name_or_id, decode="utf-8") group = OPGroup(group_json) return group @@ -399,13 +290,247 @@ def group_list(self, user_name_or_id=None, vault=None) -> OPGroupDescriptorList: group_list = OPGroupDescriptorList(group_list) return group_list - def item_get_password(self, item_identifier, vault=None, relaxed_validation=False) -> str: + # TODO: Item creation is hard to test in an automated way since it results in changed + # state. There are operations during item creation that expect state to change from + # before to after item creation + # There is ongoing work in mock-op and mock-cli-framework to simulate changed state + # when this is complete these functions need to be tested + # + # For now, ignore testing coverage + def item_create(self, + new_item: OPNewItemMixin, + password_recipe: OPPasswordRecipe = None, + vault: Optional[str] = None): # pragma: no coverage """ - Get the value of the password field from the item specified by name or UUID. + Create a new item in the authenticated 1Password account Parameters ---------- - item_identifier: str + new_item: (OPNewItemMixin, OPAbstractItem) + An object inheriting from OPnewItemMixin and OPAbstractItem representing the populated template + of the new item to create + password_recipe: OPPasswordRecipe + Where appropriate, the password recipe to pass to '--password=' when creating the item + vault: str + Name of the vault to assign the item to + Raises + ------ + OPInvalidItemException + - If new_item does not inherit from OPNewItemMixin + - if password_recipe is provided and new_item does not support passwords + (currently only Login and Password item types support passwords) + OPItemCreateException + If item creation fails for any reason during command execution + + Returns + ------- + op_item: OPAbstractItem + The newly created item object + + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + """ + if not isinstance(new_item, OPNewItemMixin): + raise OPInvalidItemException( + "Attempting to create item using object not from a template") + + # Most items don't support passwords. Only login & password items do + # 'op' will fail if we provide a password recipe when creating an + # an item that doesn't support passwords + if password_recipe and not new_item.supports_passwords(): + raise OPInvalidItemException( + "Password recpipe provided for an item that doesn't support passwords") + result_str = self._item_create( + new_item, password_recipe=password_recipe, vault=vault) + op_item = OPItemFactory.op_item(result_str) + return op_item + + def login_item_create(self, + title: str, + username: str, + password: Union[str, OPPasswordRecipe] = None, + url: Optional[str] = None, + url_label: str = "Website", + tags: Optional[List[str]] = None, + vault: str = None): # pragma: no coverage + """ + Create a new login item in the authenticated 1Password account + + Parameters + ---------- + Title : str + User viewable name of the login item to create + username : str + username string for the new login item + password : Union[str, OPPasswordRecipe], optional + May be one of: + - the literal password string to set for this login item + - a OPPasswordRecipe object that will be provided to '--generate-password=' + If a password string is provided that password will be set for this login item + If an OPPasswordRecipe object is provided, it will ensure a well-formed password recipe string is provided to '--generate-password=' + url: str, optional + If provided, set to the primary URL of the login item + url_label: str, optional + If provided and a URL is provided, this bcomes the primary URL's label + tags: List[str], optional + A list of tags to apply to the item when creating + vault: str, optional + The vault in which to create the new item + + Raises + ------ + OPInvalidItemException + - If new_item does not inherit from OPNewItemMixin + - if password_recipe is provided and new_item does not support passwords + (currently only Login and Password item types support passwords) + OPItemCreateException + If item creation fails for any reason during command execution + + Returns + ------- + login_item: OPLoginItem + The newly created login item object + + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + """ + if tags is None: + tags = list() + password_recipe = None + + # if password is actually a password recipe, + # set passsword_recipe and set password to None + # that way we don't pass it into OPLoginItemTemplate + # and instead pass it to _item_create() so it gets used on the command line + if isinstance(password, OPPasswordRecipe): + password_recipe = password + password = None + + url_obj = None + if url: + url_obj = OPLoginItemNewPrimaryURL(url, url_label) + + new_item = OPLoginItemTemplate( + title, username, password=password, url=url_obj, tags=tags) + + login_item = self.item_create( + new_item, password_recipe=password_recipe, vault=vault) + return login_item + + def item_get(self, item_identifier, vault=None, include_archive=False, generic_okay=False, relaxed_validation=False) -> OPAbstractItem: + """ + Get an 'item' object from a 1Password vault. + The returned object may be any of the item types extending OPAbstractItem. + These currently include: + - OPLoginItem + - OPCreditCardItem + - OPSecureNoteItem + - OPPasswordItem + - OPDocumentItem + - OPServerItem + - OPDatabaseItem + + Note that getting a document item is not the same as getting the document itself. The + item only contains metadata about the document such as filename. + + Parameters + ---------- + item_identifier: str + Name or ID of the item to look up + vault: str, optional + The name or ID of a vault to override the object's default vault, by default None + include_archive: bool, optional + Include items in the Archive, by default False + generic_okay: bool, optional + Instantiate unknown item types as _OPGenericItem rather than raise OPUnknownItemException + relaxed_validation: bool, optional + Whether to enable relaxed item validation for this query, in order to parse non-conformant data + by default False + Note: + If a non-unique item identifier is provided (e.g., item name/title), and there + is more than one item that matches, OPItemGetException will be raised. Check the + error message in OPItemGetException.err_output for details + + Raises + ------ + OPItemGetException + If the lookup fails for any reason during command execution + OPInvalidItemException + If the item JSON fails to decode + OPUnknownItemTypeException + If the item object returned by 1Password isn't a known type and generic_okay is False + OPNotFoundException + If the 1Password command can't be found + Returns + ------- + item: OPAbstractItem + An item object of one of the types listed above + + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + """ + + output = self._item_get(item_identifier, vault=vault, + decode="utf-8", include_archive=include_archive) + op_item = OPItemFactory.op_item( + output, generic_okay=generic_okay, relaxed_validation=relaxed_validation) + return op_item + + def item_get_totp(self, item_identifier: str, vault=None) -> OPTOTPItem: + """ + Get a TOTP code from the item specified by name or UUID. + + Note: Items in the Archive are ignored by default. To get the TOTP for an + item in the Archive, specify the item by UUID. + + Parameters + ---------- + item_identifier: str + Name or ID of the item to look up + vault: str, optional + The name or ID of a vault to override the object's default vault + + Note: + If a non-unique item identifier is provided (e.g., item name/title), and there + is more than one item that matches, OPItemGetException will be raised. Check the + error message in OPItemGetException.err_output for details + + Raises + ------ + OPItemGetException + If the lookup fails for any reason during command execution + OPNotFoundException + If the 1Password command can't be found + + Returns + ------- + totp_code: str + A string representing the TOTP code + + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + """ + output = self._item_get_totp( + item_identifier, vault=vault, decode="utf-8") + # strip newline + totp = OPTOTPItem(output) + return totp + + def item_get_password(self, item_identifier, vault=None, relaxed_validation=False) -> str: + """ + Get the value of the password field from the item specified by name or UUID. + + Parameters + ---------- + item_identifier: str The item to look up vault: str, optional The name or ID of a vault to override the object's default vault @@ -495,292 +620,711 @@ def item_get_filename(self, item_identifier, vault=None, include_archive=False, return file_name - def document_get(self, document_name_or_id, vault=None, include_archive=False, relaxed_validation=False): + def item_edit_add_password_field(self, + item_identifier: str, + password: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None, + insecure_operation: bool = False): """ - Download a document object from a 1Password vault by name or UUID. + Add new concealed/passwrod field and optionally a new section to an item Parameters ---------- - document_name_or_id : str - The item to look up + item_identifier: str + The item to edit + value: str + The password value to set + field_label: str + The human readable label of the field to create + section_label: str, optional + If provided, the human readable section label the field is associated with. + It will be created if it doesn't exist vault: str, optional - The name or ID of a vault to override the object's default vault - relaxed_validation: bool, optional - Whether to enable relaxed item validation for this query, in order to parse non-conformant data - by default False + The name or ID of a vault containing the item to edit + Overrides the OP object's default vault, if set + insecure_operation: bool + Caller acknowledgement of the insecure nature of this operation + by default, False + Raises ------ - OPInvalidDocumentException - If the retrieved item isn't a document object or lacks a documents expected attributes - OPDocumentGetException - If document lookup fails for any reason during command execution - OPNotFoundException - If the 1Password command can't be found - + OPItemGetException + If the item lookup fails for any reason + OPFieldExistsException + If the field to be added already existss + OPItemEditException + If the item edit operation fails for any reason Returns ------- - file_name, document bytes: Tuple[str, bytes] - A tuple consisting of the filename and bytes of the specified document + op_item: OPAbstractItem + The edited version of the item + + NOTE: an 'item_get()` operation first is performed in order to validate + the field name and, if provided, section name + + NOTE: The following scenarios are an error + - An ambiguous existing field match: + one or more fields match the field label and no section label was specified + - An explicit existing field match: + one or more field/section pairings exist that match the field label & section label Service Account Support ----------------------- Supported required keyword arguments: vault """ - try: - file_name = self.item_get_filename( - document_name_or_id, vault=vault, include_archive=include_archive, relaxed_validation=relaxed_validation) - except AttributeError as ae: - raise OPInvalidDocumentException( - "Item has no 'fileName' attribute") from ae - except OPCmdFailedException as ocfe: - raise OPDocumentGetException.from_opexception(ocfe) from ocfe - try: - document_bytes = super()._document_get(document_name_or_id, - vault=vault, include_archive=include_archive) - except OPCmdFailedException as ocfe: - raise OPDocumentGetException.from_opexception(ocfe) from ocfe - - return (file_name, document_bytes) + password = RedactedString(password, unmask_len=0) + field_type = OPFieldTypeEnum.PASSWORD + op_item = self._item_edit_set_field(item_identifier, + field_type, + field_label, + section_label, + password, + vault, + password_downgrade=False, + insecure_operation=insecure_operation, + create_field=True) + return op_item - def document_delete(self, document_identifier: str, vault: Optional[str] = None, archive: bool = False, relaxed_validation: bool = False) -> str: + def item_edit_add_url_field(self, + item_identifier: str, + url: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None): """ - Delete a document object based on document name or unique identifier + Add new URL field and optionally a new section to an item + + NOTE: This method differs from item_edit_url(). This method adds a URL item field + whereas item_edit_url() sets the URL property, which is not a field at all, on a login item Parameters ---------- - document_identifier : str - Name or identifier of the document to delete - vault : str, optional - The name or ID of a vault to override the default vault, by default None - archive : bool, optional - Whether to archive or permanently delete the item, by default False - relaxed_validation: bool, optional - Whether to enable relaxed item validation for this query, in order to parse non-conformant data - by default False + item_identifier: str + The item to edit + url: str + The URL value to set + field_label: str + The human readable label of the field to create + section_label: str, optional + If provided, the human readable section label the field is associated with. + It will be created if it doesn't exist + vault: str, optional + The name or ID of a vault containing the item to edit + Overrides the OP object's default vault, if set + + Raises + ------ + OPItemGetException + If the item lookup fails for any reason + OPFieldExistsException + If the field to be added already existss + OPItemEditException + If the item edit operation fails for any reason Returns ------- - document_id: str - Unique identifier of the item deleted + op_item: OPAbstractItem + The edited version of the item + + NOTE: an 'item_get()` operation first is performed in order to validate + the field name and, if provided, section name + + + NOTE: The following scenarios are an error + - An ambiguous existing field match: + one or more fields match the field label and no section label was specified + - An explicit existing field match: + one or more field/section pairings exist that match the field label & section label + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + """ + password = RedactedString(url, unmask_len=0) + field_type = OPFieldTypeEnum.URL + op_item = self._item_edit_set_field(item_identifier, + field_type, + field_label, + section_label, + password, + vault, + password_downgrade=False, + insecure_operation=False, + create_field=True) + return op_item + + def item_edit_add_text_field(self, + item_identifier: str, + value: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None): + """ + Add new text field and optionally a new section to an item + + Parameters + ---------- + item_identifier: str + The item to edit + value: str + The text value to set + field_label: str + The human readable label of the field to create + section_label: str, optional + If provided, the human readable section label the field is associated with. + It will be created if it doesn't exist + vault: str, optional + The name or ID of a vault containing the item to edit + Overrides the OP object's default vault, if set Raises ------ - OPDocumentDeleteException - - If the document to be deleted is not found - - If there is more than one item matching 'document_identifier' - - If the delete operation fails for any other reason + OPItemGetException + If the item lookup fails for any reason + OPFieldExistsException + If the field to be added already existss + OPItemEditException + If the item edit operation fails for any reason + Returns + ------- + op_item: OPAbstractItem + The edited version of the item + NOTE: an 'item_get()` operation first is performed in order to validate + the field name and, if provided, section name + + + NOTE: The following scenarios are an error + - An ambiguous existing field match: + one or more fields match the field label and no section label was specified + - An explicit existing field match: + one or more field/section pairings exist that match the field label & section label Service Account Support ----------------------- Supported required keyword arguments: vault """ + field_type = OPFieldTypeEnum.TEXT + op_item = self._item_edit_set_field(item_identifier, + field_type, + field_label, + section_label, + value, + vault, + password_downgrade=False, + insecure_operation=False, + create_field=True) + return op_item - # to satisfy mypy - generic_item_class: Type[_OPGenericItem] - if relaxed_validation: - generic_item_class = _OPGenericItemRelaxedValidation - else: - generic_item_class = _OPGenericItem + def item_edit_set_password(self, + item_identifier: str, + password: str, + field_label: str = "password", + section_label: Optional[str] = None, + vault: Optional[str] = None, + insecure_operation: bool = False,): + """ + Assign a new password for an existing item - try: - output = super()._item_get(document_identifier, vault=vault) - item = generic_item_class(output) - except OPItemGetException as e: - raise OPDocumentDeleteException.from_opexception(e) - # we want to return the explicit ID even if we were - # given an document name or other identifier - # that way the caller knows exactly what got deleted - # can match it up with what they expected to be deleted, if desired - document_id = item.unique_id + SECURITY NOTE: This operation will include the provided password in cleartext as a command line argument + to the 'op' command. On most platforms, the arguments, including the password, will be visible to other + processes, including processes owned by other users + In order to use this operaton, this insecurity must be acknowledged by passing the insecure_operation=True kwarg - # 'op document delete' doesn't have any stdout, so we're not - # capturing any here - self._document_delete(document_id, vault=vault, archive=archive) + Parameters + ---------- + item_identifier: str + The item to edit + password: str + The password value to set + field_label: str + The human readable label of the field to edit + by default "password" + section_label: str, optional + If provided, the human readable section label the field is associated with + vault: str, optional + The name or ID of a vault containing the item to edit + Overrides the OP object's default vault, if set + insecure_operation: bool + Caller acknowledgement of the insecure nature of this operation + by default, False - return document_id + Raises + ------ + OPItemGetException + If the item lookup fails for any reason + OPSectionNotFoundException + If a section label is specified but can't be looked up on the item object + OPFieldNotFoundException + If the field label can't be looked up on the item object + OPItemEditException + If the item edit operation fails for any reason + OPInsecureOperationException + If the caller does not pass insecure_operation=True, failing to acknowledge the + insecure nature of this operation + Returns + ------- + op_item: OPAbstractItem + The edited version of the item + + Note: an 'item_get()` operation first is performed in order to validate + the field name and, if provided, section name - def item_list(self, categories=[], include_archive=False, tags=[], title_glob=None, vault=None, generic_okay=True) -> OPItemList: + Service Account Support + ----------------------- + Supported + required keyword arguments: vault """ - Return a list of items in an account. + + # TODO: look up item and validate section and field + password = RedactedString(password, unmask_len=0) + field_type = OPFieldTypeEnum.PASSWORD + op_item = self._item_edit_set_field(item_identifier, + field_type, + field_label, + section_label, + password, + vault, + password_downgrade=False, + insecure_operation=insecure_operation, + create_field=False) + return op_item + + def item_edit_set_url_field(self, + item_identifier: str, + url: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None, + password_downgrade: bool = False): + """ + Set a new value on an existing item's URL field + + NOTE: This method differs from item_edit_url(). This method sets a URL value on an + existing item field whereas item_edit_url() sets the URL property, which is not a + field at all, on a login item Parameters ---------- - categories: List[str], optional - A list of category names to restrict list to - include_archive: bool, optional - Include items in the Archive in the list - tags: List[str], optional - A list of tags to restrict list to - title_glob: bool, optional - a shell-style glob pattern to match against item titles. If provided, - resulting list will include only matching items - by default None + item_identifier: str + The item to edit + url: str + The URL value to set + field_label: str + The human readable label of the field to edit + section_label: str, optional + If provided, the human readable section label the field is associated with vault: str, optional - The name or ID of a vault to override the object's default vault - generic_okay: bool, optional - Instantiate unknown item types as _OPGenericItem rather than raise OPUnknownItemException + The name or ID of a vault containing the item to edit + Overrides the OP object's default vault, if set + password_downgrade: bool + Whether and existing concealed (i.e., password) field should be downgraded to a non-password + field. + If the existing field IS concealed and this value is false, an exception will be raised Raises ------ - OPItemListException - If the user list operation for any reason during command execution - OPUnknownItemTypeException - If thelist returned by 1Password contains one or more item descriptors - that aren't a known type and generic_okay is False - OPNotFoundException - If the 1Password command can't be found + OPItemGetException + If the item lookup fails for any reason + OPSectionNotFoundException + If a section label is specified but can't be looked up on the item object + OPFieldNotFoundException + If the field label can't be looked up on the item object + OPPasswordFieldDowngradeException + If the field is a concealed field and password_downgrade is False + OPItemEditException + If the item edit operation fails for any reason + Returns + ------- + op_item: OPAbstractItem + The edited version of the item + + Note: an 'item_get()` operation first is performed in order to validate + the field name and, if provided, section name + + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + + NOTE: Neither 1Password nor pyonepassword perform any validation on the URL + string. It may be virtually any string. + + """ + + # If section or field not found, will raise + # OPSectionNotFoundException, or + # OPFieldNotFoundException + + field_type = OPFieldTypeEnum.URL + op_item = self._item_edit_set_field(item_identifier, + field_type, + field_label, + section_label, + url, + vault, + password_downgrade, + insecure_operation=False, + create_field=False) + return op_item + + def item_edit_set_text_field(self, + item_identifier: str, + value: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None, + password_downgrade: bool = False): + """ + Set a new value on an existing item's text field + + Parameters + ---------- + item_identifier: str + The item to edit + value: str + The text value to set + field_label: str + The human readable label of the field to edit + section_label: str, optional + If provided, the human readable section label the field is associated with + vault: str, optional + The name or ID of a vault containing the item to edit + Overrides the OP object's default vault, if set + password_downgrade: bool + Whether and existing concealed (i.e., password) field should be downgraded to a non-password + field. + If the existing field IS concealed and this value is false, an exception will be raised + + Raises + ------ + OPItemGetException + If the item lookup fails for any reason + OPSectionNotFoundException + If a section label is specified but can't be looked up on the item object + OPFieldNotFoundException + If the field label can't be looked up on the item object + OPPasswordFieldDowngradeException + If the field is a concealed field and password_downgrade is False + OPItemEditException + If the item edit operation fails for any reason + Returns + ------- + op_item: OPAbstractItem + The edited version of the item + + Note: an 'item_get()` operation first is performed in order to validate + the field name and, if provided, section name + + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + """ + + # If section or field not found, will raise + # OPSectionNotFoundException, or + # OPFieldNotFoundException + + field_type = OPFieldTypeEnum.TEXT + op_item = self._item_edit_set_field(item_identifier, + field_type, + field_label, + section_label, + value, + vault, + password_downgrade, + insecure_operation=True, + create_field=False) + return op_item + + def item_edit_delete_field(self, + item_identifier: str, + field_label: str, + section_label: Optional[str] = None, + vault: Optional[str] = None): + """ + Delete a field, and optionally a section from an item + + If a section is specified, and it has no remaining fields after + the edit operation, the section will be removed as well + + Parameters + ---------- + item_identifier: str + The item to edit + field_label: str + The human readable label of the field to delete + section_label: str, optional + If provided, the human readable section label the field is associated with + vault: str, optional + The name or ID of a vault containing the item to edit + Overrides the OP object's default vault, if set + Raises + ------ + OPItemGetException + If the item lookup fails for any reason + OPSectionNotFoundException + If a section label is specified but can't be looked up on the item object + OPFieldNotFoundException + If the field label can't be looked up on the item object + OPItemEditException + If the item edit operation fails for any reason Returns ------- - user: OPUserDescriptorList - An object representing a list of user descriptors + op_item: OPAbstractItem + The edited version of the item + + Note: an 'item_get()` operation first is performed in order to validate + the field name and, if provided, section name Service Account Support ----------------------- Supported + required keyword arguments: vault + """ - item_list_json = self._item_list( - categories, include_archive, tags, vault) - item_list = OPItemList(item_list_json, generic_okay=generic_okay) - if title_glob: - _list = [] - for obj in item_list: - if fnmatch.fnmatch(obj.title, title_glob): - _list.append(obj) - item_list = OPItemList(_list) - return item_list + # If section or field not found, will raise + # OPSectionNotFoundException, or + # OPFieldNotFoundException + + VALUE_NONE = None + PASSWORD_DOWNGRADE_IGNORE = True + INSECURE_OPERATION = False + field_type = OPFieldTypeEnum.DELETE + op_item = self._item_edit_set_field(item_identifier, + field_type, + field_label, + section_label, + VALUE_NONE, + vault, + PASSWORD_DOWNGRADE_IGNORE, + INSECURE_OPERATION, + create_field=False) + return op_item - # TODO: Item creation is hard to test in an automated way since it results in changed - # state. There are operations during item creation that expect state to change from - # before to after item creation - # There is ongoing work in mock-op and mock-cli-framework to simulate changed state - # when this is complete these functions need to be tested - # - # For now, ignore testing coverage - def item_create(self, - new_item: OPNewItemMixin, - password_recipe: OPPasswordRecipe = None, - vault: Optional[str] = None): # pragma: no coverage + def item_edit_favorite(self, + item_identifier: str, + favorite: bool, + vault: Optional[str] = None): """ - Create a new item in the authenticated 1Password account + Set or unset an item's 'favorite' status Parameters ---------- - new_item: (OPNewItemMixin, OPAbstractItem) - An object inheriting from OPnewItemMixin and OPAbstractItem representing the populated template - of the new item to create + item_identifier: str + The item to edit + favorite: bool + Whether to set or unset the item's favorite status + vault: str, optional + The name or ID of a vault containing the item to edit. + Overrides the OP object's default vault, if set + + Raises + ------ + OPItemEditException + If the item edit operation fails for any reason + + Returns + ------- + op_item: OPAbstractItem + The edited version of the item + + Service Account Support + ----------------------- + Supported + """ + result_str = self._item_edit_favorite(item_identifier, + favorite, + vault=vault) + op_item = OPItemFactory.op_item(result_str, generic_okay=True) + + return op_item + + def item_edit_generate_password(self, + item_identifier: str, + password_recipe: OPPasswordRecipe, + vault: Optional[str] = None): + """ + Generate and assign a new password for an existing item + + Parameters + ---------- + item_identifier: str + The item to edit password_recipe: OPPasswordRecipe - Where appropriate, the password recipe to pass to '--password=' when creating the item - vault: str - Name of the vault to assign the item to + The password recipe to apply when generating a new passwod + vault: str, optional + The name or ID of a vault containing the item to edit. + Overrides the OP object's default vault, if set + Raises ------ - OPInvalidItemException - - If new_item does not inherit from OPNewItemMixin - - if password_recipe is provided and new_item does not support passwords - (currently only Login and Password item types support passwords) - OPItemCreateException - If item creation fails for any reason during command execution + OPItemEditException + If the item edit operation fails for any reason + + Returns + ------- + op_item: OPAbstractItem + The edited version of the item + + Service Account Support + ----------------------- + Supported + """ + + result_str = self._item_edit_generate_password(item_identifier, + password_recipe, + vault) + op_item = OPItemFactory.op_item(result_str, generic_okay=True) + return op_item + + def item_edit_tags(self, + item_identifier: str, + tags: List[str], + append_tags: bool = False, + vault: Optional[str] = None) -> OPAbstractItem: + """ + Replace, append, or remove an item's tags + + Parameters + ---------- + item_identifier: str + The item to edit + tags: List[str] + The list of tags to assign to the item + append_tags: bool + Append to the existing list of tags or replace the existing list + by default True + vault: str, optional + The name or ID of a vault containing the item to edit. + Overrides the OP object's default vault, if set + + Raises + ------ + OPItemEditException + If the item edit operation fails for any reason + + Returns + ------- + op_item: OPAbstractItem + The edited version of the item + + Note: an 'item_get()` operation first is performed in order to obtain the + existing set of tags + + Service Account Support + ----------------------- + Supported + required keyword arguments: vault + """ + item = self.item_get(item_identifier, vault=vault) + if append_tags: + existing_tags = item.tags + for tag in tags: + if tag not in existing_tags: + # although op item tags *sort of* behave as a set + # they are technically a list and preserve order + # so lets go to the trouble to also preserve order + # and not append any duplicates + existing_tags.append(tag) + tags = existing_tags + else: + item = None + + result_str = self._item_edit_tags(item_identifier, + tags, + vault=vault) + op_item = OPItemFactory.op_item(result_str, generic_okay=True) + + return op_item + + def item_edit_title(self, + item_identifier: str, + item_title: str, + vault: Optional[str] = None): + """ + Assign a new title for an existing item + + Parameters + ---------- + item_identifier: str + The item to edit + item_title: str + The new title to assign to the item + vault: str, optional + The name or ID of a vault containing the item to edit. + Overrides the OP object's default vault, if set + + Raises + ------ + OPItemEditException + If the item edit operation fails for any reason Returns ------- op_item: OPAbstractItem - The newly created item object + The edited version of the item Service Account Support ----------------------- Supported - required keyword arguments: vault + required keyword arguments: vault """ - if not isinstance(new_item, OPNewItemMixin): - raise OPInvalidItemException( - "Attempting to create item using object not from a template") + self.item_get(item_identifier, + vault=vault) + result_str = self._item_edit_title(item_identifier, + item_title, + vault=vault) + op_item = OPItemFactory.op_item(result_str, generic_okay=True) - # Most items don't support passwords. Only login & password items do - # 'op' will fail if we provide a password recipe when creating an - # an item that doesn't support passwords - if password_recipe and not new_item.supports_passwords(): - raise OPInvalidItemException( - "Password recpipe provided for an item that doesn't support passwords") - result_str = super()._item_create( - new_item, password_recipe=password_recipe, vault=vault) - op_item = OPItemFactory.op_item(result_str) return op_item - def login_item_create(self, - title: str, - username: str, - password: Union[str, OPPasswordRecipe] = None, - url: Optional[str] = None, - url_label: str = "Website", - tags: List[str] = [], - vault: str = None): # pragma: no coverage + def item_edit_url(self, + item_identifier: str, + url: str, + vault: Optional[str] = None): """ - Create a new login item in the authenticated 1Password account + Set the URL associated with an existing item + + NOTE: This method differs from item_edit_set_url_field(). This method sets the URL + property on a login item and does not set values on any item fields Parameters ---------- - Title : str - User viewable name of the login item to create - username : str - username string for the new login item - password : Union[str, OPPasswordRecipe], optional - May be one of: - - the literal password string to set for this login item - - a OPPasswordRecipe object that will be provided to '--generate-password=' - If a password string is provided that password will be set for this login item - If an OPPasswordRecipe object is provided, it will ensure a well-formed password recipe string is provided to '--generate-password=' - url: str, optional - If provided, set to the primary URL of the login item - url_label: str, optional - If provided and a URL is provided, this bcomes the primary URL's label - tags: List[str], optional - A list of tags to apply to the item when creating - vault: str, optionsl - The vault in which to create the new item + item_identifier: str + The item to edit + url: str + The new URL to assign to the item + vault: str, optional + The name or ID of a vault containing the item to edit. + Overrides the OP object's default vault, if set Raises ------ - OPInvalidItemException - - If new_item does not inherit from OPNewItemMixin - - if password_recipe is provided and new_item does not support passwords - (currently only Login and Password item types support passwords) - OPItemCreateException - If item creation fails for any reason during command execution + OPItemEditException + If the item edit operation fails for any reason Returns ------- - login_item: OPLoginItem - The newly created login item object + op_item: OPAbstractItem + The edited version of the item Service Account Support ----------------------- Supported - required keyword arguments: vault """ - password_recipe = None - - # if password is actually a password recipe, - # set passsword_recipe and set password to None - # that way we don't pass it into OPLoginItemTemplate - # and instead pass it to _item_create() so it gets used on the command line - if isinstance(password, OPPasswordRecipe): - password_recipe = password - password = None - - url_obj = None - if url: - url_obj = OPLoginItemNewPrimaryURL(url, url_label) - - new_item = OPLoginItemTemplate( - title, username, password=password, url=url_obj, tags=tags) + result_str = self._item_edit_url(item_identifier, + url, + vault=vault) + op_item = OPItemFactory.op_item(result_str, generic_okay=True) - login_item = self.item_create( - new_item, password_recipe=password_recipe, vault=vault) - return login_item + return op_item def item_delete(self, item_identifier: str, vault: Optional[str] = None, archive: bool = False, relaxed_validation=False) -> str: """ @@ -828,7 +1372,7 @@ def item_delete(self, item_identifier: str, vault: Optional[str] = None, archive generic_item_class = _OPGenericItem try: - output = super()._item_get(item_identifier, vault=vault) + output = self._item_get(item_identifier, vault=vault) item = generic_item_class(output) except OPItemGetException as e: raise OPItemDeleteException.from_opexception(e) @@ -846,11 +1390,11 @@ def item_delete(self, item_identifier: str, vault: Optional[str] = None, archive def item_delete_multiple(self, vault, - categories=[], - include_archive=False, - tags=[], - archive=False, - title_glob=None, + categories: Optional[List[str]] = None, + include_archive: bool = False, + tags: Optional[List[str]] = None, + archive: bool = False, + title_glob: str = None, batch_size=25): """ Delete multiple items at once from a specific vault. This may take place across @@ -870,7 +1414,7 @@ def item_delete_multiple(self, by default False tags: List[str], optional A list of tags to restrict batch deletion to - title_glob: bool, optional + title_glob: str, optional a shell-style glob pattern to match against item titles for deleting by default None batch_size: int, optional @@ -899,6 +1443,11 @@ def item_delete_multiple(self, Supported required keyword arguments: vault """ + if tags is None: + tags = list() + if categories is None: + categories = list() + # track deleted items as we delete them so we can return # that list to the caller deleted_items = OPItemList([]) @@ -934,6 +1483,193 @@ def item_delete_multiple(self, return deleted_items + def item_list(self, + categories: Optional[List[str]] = None, + include_archive: bool = False, + tags: Optional[List[str]] = None, + title_glob: str = None, + vault: str = None, + generic_okay: bool = True) -> OPItemList: + """ + Return a list of items in an account. + + Parameters + ---------- + categories: List[str], optional + A list of category names to restrict list to + include_archive: bool, optional + Include items in the Archive in the list + tags: List[str], optional + A list of tags to restrict list to + title_glob: str, optional + a shell-style glob pattern to match against item titles. If provided, + resulting list will include only matching items + by default None + vault: str, optional + The name or ID of a vault to override the object's default vault + generic_okay: bool, optional + Instantiate unknown item types as _OPGenericItem rather than raise OPUnknownItemException + + Raises + ------ + OPItemListException + If the user list operation for any reason during command execution + OPUnknownItemTypeException + If thelist returned by 1Password contains one or more item descriptors + that aren't a known type and generic_okay is False + OPNotFoundException + If the 1Password command can't be found + + Returns + ------- + user: OPUserDescriptorList + An object representing a list of user descriptors + + Service Account Support + ----------------------- + Supported + """ + if tags is None: + tags = list() + if categories is None: + categories = list() + + item_list_json = self._item_list( + categories, include_archive, tags, vault) + item_list = OPItemList(item_list_json, generic_okay=generic_okay) + + if title_glob: + _list = [] + for obj in item_list: + if fnmatch.fnmatch(obj.title, title_glob): + _list.append(obj) + item_list = OPItemList(_list) + return item_list + + def user_get(self, user_name_or_id: str) -> OPUser: + """ + Return the details for the user specified by name or UUID. + + Parameters + ---------- + user_name_or_id: str + Name or ID of the user to look up + Raises + ------ + OPUserGetException + If the lookup fails for any reason during command execution + OPNotFoundException + If the 1Password command can't be found + + Returns + ------- + user: OPuser + An object representing the details of the requested user + + Service Account Support + ----------------------- + Supported + """ + user_json = self._user_get(user_name_or_id) + user = OPUser(user_json) + return user + + def user_list(self, group_name_or_id=None, vault_name_or_id=None) -> OPUserDescriptorList: + """ + Return a list of users in an account. + + Parameters + ---------- + group_name_or_id: str + Name or ID of a group to restrict user listing to + vault_name_or_id: str + Name or ID of a vault to restrict user listing to + + Raises + ------ + OPUserListException + If the user list operation for any reason during command execution + OPNotFoundException + If the 1Password command can't be found + + Returns + ------- + user: OPUserDescriptorList + An object representing a list of user descriptors + + Service Account Support + ----------------------- + Supported + """ + user_list: Union[str, OPUserDescriptorList] + + user_list = self._user_list( + group_name_or_id=group_name_or_id, vault=vault_name_or_id) + user_list = OPUserDescriptorList(user_list) + return user_list + + def vault_get(self, vault_name_or_id: str) -> OPVault: + """ + Return the details for the vault specified by name or UUID. + + Parameters + ---------- + vault_name_or_id: str + Name or UUID of the vault to look up + + Raises + ------ + OPVaultGetException + If the lookup fails for any reason during command execution + OPNotFoundException + If the 1Password command can't be found + + Returns + ------- + vault: OPVault + An object representing the details of the requested vault + + Service Account Support + ----------------------- + Supported + prohibited keyword arguments: group, user + """ + vault_json = self._vault_get(vault_name_or_id, decode="utf-8") + vault = OPVault(vault_json) + return vault + + def vault_list(self, group_name_or_id=None, user_name_or_id=None) -> OPVaultDescriptorList: + """ + Return a list of vaults in an account. + + Parameters + ---------- + group_name_or_id: str + Name or ID of a group to restrict vault listing to + user_name_or_id: str + Name or ID of a user to restrict vault listing to + + Raises + ------ + OPVaultListException + If the vault list operation for any reason during command execution + OPNotFoundException + If the 1Password command can't be found + + Returns + ------- + user: OPVaultDescriptorList + An object representing a list of vault descriptors + + Service Account Support + ----------------------- + Supported + """ + vault_list_json = self._vault_list( + group_name_or_id=group_name_or_id, user_name_or_id=user_name_or_id) + vault_list = OPVaultDescriptorList(vault_list_json) + return vault_list + def signed_in_accounts(self, decode="utf-8") -> OPAccountList: """ Retrieve a users and accounts set up on this device @@ -947,7 +1683,8 @@ def signed_in_accounts(self, decode="utf-8") -> OPAccountList: ----------------------- Supported """ - account_list_json = super()._signed_in_accounts(self.op_path, decode=decode) + account_list_json = self._signed_in_accounts( + self.op_path, decode=decode) account_list = OPAccountList(account_list_json) return account_list @@ -983,7 +1720,7 @@ def signout(self, forget=False): # pragma: no coverage return try: - super()._signout(account, token, forget=forget) + self._signout(account, token, forget=forget) except OPCmdFailedException as ocfe: raise OPSignoutException.from_opexception(ocfe) from ocfe @@ -1038,3 +1775,190 @@ def _sanitize(self): # pragma: no coverage env.pop(self._sess_var) except KeyError: pass + + def _item_edit_set_field(self, + item_identifier: str, + field_type: OPFieldTypeEnum, + field_label: str, + section_label: str, + value: str, + vault: Optional[str], + password_downgrade: bool, + insecure_operation: bool, + create_field: bool): + """ + Set a new value on an existing item field + + This is intended to be a centralized Section.Field[field_type]=value call site + + It allows us to do validation in a central location, including: + - verifying the item we're trying to edit actually exists + - verifying the field and section we're trying to edit actually exist + - verify we don't accidentally downgrade a password field to some non-protected field + + This also allows us to ensure we relax the following restrictions for item editing: + - generic_okay = True + + The point is that we don't need to remember to do the verification steps + every time we add an item-edit public method + """ + + # if we're assigning a password, caller needs to pass insecure_operation=True + if field_type == OPFieldTypeEnum.PASSWORD and not insecure_operation: + msg = "Password assignment via 'op item edit' is inherently insecure. Pass 'insecure_operation=True' to override. For more information, see https://developer.1password.com/docs/cli/reference/management-commands/item#item-edit" + self.logger.fatal(msg) + raise OPInsecureOperationException(msg) + + # Does the item exist? + # generic_okay: Enable editing of unknown OPItem types + item = self.item_get( + item_identifier, vault=vault, generic_okay=True) + + if not create_field: + # Does the field and, if provided, the section exist? + # Don't accidentally create a new field or section + # if the field or, if provided, section are not found + # OPFieldNotFoundException or OPSectionNotFoundException will + # be raised here + field = self._validate_item_field_exists( + item, field_label, section_label) + + # If the existing field is a password, don't accidentally + # turn it into an unprotected text (or other type) of field + if isinstance(field, OPConcealedField): + if field_type != OPFieldTypeEnum.PASSWORD and not password_downgrade: + msg = "Item edit operation would downgrade field from a password field to a non-password field." + raise OPPasswordFieldDowngradeException(msg) + else: + # We're explicitly creating a new field so let's make sure + # one with this label and section doesn't already exist + # otherwise we'll accidently edit that one instead + # this will raise + self._validate_item_field_does_not_exist( + item, field_label, section_label) + + item_json = self._item_edit_set_field_value(item_identifier, + field_type, + value, + field_label, + section_label=section_label, + vault=vault) + + # generic_okay: Enable editing of unknown OPItem types + # relaxed_validation: Enable editing of non-conforming items + item = OPItemFactory.op_item( + item_json, generic_okay=True) + return item + + def _validate_item_field_exists(self, + item: OPAbstractItem, + field_label: str, + section_label: Optional[str]) -> OPItemField: + # Validate that the field and, if provided, section exist + # It is an error if any: + # - If provided, a section with the given label is not found + # - A field with the given label is not found + # - If no section label is specified, no matching field lacks an attached section + # + # Success if any: + # - If a section label is specified and all of: + # - At least one matching section is found + # - At least one matching field is found field is found + # - At least one (section, field) paring is found among the matching sections and fields + # - If no section label is specified + # - A matching field is found that has no associated section + + field = None + section_ids = set() + if section_label: + # this may raise OPSectionNotFoundException if there is no match + # this is expected. It is up to the caller to handle this + sections = item.sections_by_label(section_label) + for _section in sections: + section_ids.add(_section.section_id) + + # this may raise OPFieldNotfoundException if there is no match + # this is expected. It is up to the caller to handle this + fields = item.fields_by_label(field_label) + + for _field in fields: + if _field.section_id and section_label: + if _field.section_id in section_ids: + # We found a matching field + # it has a section that matches one of the known matching sections + # This is good: at least one (section, field) pairing exists + field = _field + break + elif not _field.section_id and not section_label: + # we found a matching field + # it doesn't have a section and we were told not to look for a section + # This is good: a (, field) pairing exists + field = _field + break + + if not field: + if not section_label: + msg = f"No field found '{field_label}' that lacks a section" + raise OPFieldNotFoundException(msg) + else: + msg = f"Section '{section_label}', field '{field_label}' not found" + raise OPFieldNotFoundException(msg) + return field + + def _validate_item_field_does_not_exist(self, + item: OPAbstractItem, + field_label: str, + section_label: Optional[str]) -> None: + # Raises OPFieldExistsException if: + # - Ambiguous match: one or more fields match the field label and no section label was specified + # - Explicit match: one or more field/section pairings exist that match the field label & section label + # + # Success if any of: + # - No fields matching the field label are found + # - A section label is specified but a matching section is not found + # - A section label is specified and section found, + # but no matching fields found are associated with it + verified = False + if not section_label: + # ensure section label is not an empty string or some other "false" value + section_label = None + while not verified: + section_ids = set() + try: + fields = item.fields_by_label(field_label) + except OPFieldNotFoundException: + # no fields found with the specified label + # this is good: the field does not exist + verified = True + break + + if section_label: + try: + sections = item.sections_by_label(section_label) + for section in sections: + section_ids.add(section.section_id) + except OPSectionNotFoundException: + # we were explicitly given a section to look up and we didn't find it + # so this is good: the (section, field) paring does not exist + verified = True + break + + if fields and not section_label: + # a field exists, and without being explicit about the section + # 'op' may still match the field whether or not it has a section + # this is bad: a field exists and may be ambigously matched + raise OPFieldExistsException( + f"Field \"{field_label}\" exists and no section was specified") + + for field in fields: + if field.section_id in section_ids: + msg = f"Section: \"{section_label}\", " + msg += f"field: \"{field_label}\" already exists" + # we were explicitly given a section to look up and we found it AND the field + # this is bad: at least one (section, field) DOES exist + raise OPFieldExistsException(msg) + + # None of the fields found match any of the sections found + # This is good: a (section, field) paring could not be found + verified = True + break diff --git a/renovate.json b/renovate.json index 598b8469..4cca4f7a 100644 --- a/renovate.json +++ b/renovate.json @@ -5,11 +5,6 @@ ], "baseBranches": ["development"], "packageRules": [ - { - "matchPaths": ["docker_testing/docker/py38.Dockerfile"], - "matchPackageNames":["python"], - "allowedVersions": "3.8" - }, { "matchPaths": ["docker_testing/docker/py39.Dockerfile"], "matchPackageNames":["python"], @@ -21,9 +16,14 @@ "allowedVersions": "3.10" }, { - "matchPaths": ["docker_testing/docker/mypy.Dockerfile"], + "matchPaths": ["docker_testing/docker/py311.Dockerfile"], "matchPackageNames":["python"], - "allowedVersions": "3.10" + "allowedVersions": "3.11" + }, + { + "matchPaths": ["docker_testing/docker/py312.Dockerfile"], + "matchPackageNames":["python"], + "allowedVersions": "3.12" } ] } diff --git a/scripts/archive_op_binary.sh b/scripts/archive_op_binary.sh index a6c6c25f..231a74da 100755 --- a/scripts/archive_op_binary.sh +++ b/scripts/archive_op_binary.sh @@ -4,13 +4,49 @@ _readlink(){ readlink "$1" || echo "$1"; } # Don't shadow the 'realpath' executable which may be installed on # some systems (e.g., via homebrew) -_realpath() { cd "$(dirname "$0")" && _readlink "$(pwd)"/"$(basename "$0")"; } -real_path="$(_realpath "$0")" +_realpath() { _path="$1"; cd "$(dirname "$_path")" && _readlink "$(pwd)"/"$(basename "$_path")"; } + +_realscriptpath() { + _realpath "$0" +} + +real_path="$(_realscriptpath)" SRC_ROOT="$(cd "$(dirname "$real_path")" && dirname "$(pwd)")" # shellcheck source=./functions.sh . "$SRC_ROOT"/scripts/functions.sh OP_BINARY_PATH="$SRC_ROOT/op-binaries" + +# not all 'op' packages install to the same place +# so get the actual location where 'op' is installed +get_real_op_path(){ + _realpath "$(which op)" + +} + +op_path="$(get_real_op_path)" + +# some 'macos' op packages install a universal binary, +# some install an architecture specific binary +op_is_universal_binary(){ + _op="$1" + file "$_op" | grep 'Mach-O universal' >/dev/null + return $? +} + +get_op_arch(){ + _op="$1" + _arch="" + if ! op_is_universal_binary "$_op"; + then + # TODO: This probably only works on macOS + _arch="$(file "$_op" | awk '{print $NF }')" + else + _arch="universal" + fi + echo "$_arch" +} + md5check(){ _file1="$1" _file2="$2" @@ -27,26 +63,63 @@ md5check(){ } get_op_ver(){ - _version="$(/usr/local/bin/op --version)" + _version="$("$op_path" --version)" printf "%s" "$_version" unset _version } + +compress_archives(){ + # op-binaries/2.21.0 + _op_binaries_rel="$(basename "$OP_BINARY_PATH")" + _current_archive="$_op_binaries_rel/$1/" + + # trailing slash on the glob makes sure we only look at directories + # much faster that looping over all files for comparison + for _dir in "$_op_binaries_rel"/*/; + do + if [ -d "$_dir" ] && [ "$_current_archive" != "$_dir" ]; + then + _ver="$(basename "$_dir")" + _tarball="$_op_binaries_rel/$_ver.tar.bz2" + + # tar jcvf op-binaries/2.21.0.tar.bz2 -C op-binaries op-binaries/2.21.0 + tar jcvf "$_tarball" -C "$_op_binaries_rel" "$_ver" || return $? + # rm -r op-binaries/2.21.0 + rm -r "$_dir" || return $? + fi + + done + +} + op_ver="$(get_op_ver)" -if [ ! -d "$OP_BINARY_PATH/$op_ver" ]; +# make "universal" copy separate from arch-specific copy +op_arch="$(get_op_arch "$op_path")" +op_archive_dir="$OP_BINARY_PATH/$op_ver/$op_arch" + +# destination should end up being like +# op-binaries/2.21.0/universal/op, or +# op-binaries/2.21.0/arm64/op, etc. +op_archive_dest="$op_archive_dir/op" + + +if [ ! -d "$op_archive_dir" ]; then - mkdir -p "$OP_BINARY_PATH/$op_ver"; + mkdir -p "$op_archive_dir"; fi -if [ ! -f "$OP_BINARY_PATH/$op_ver/op" ]; +if [ ! -f "$op_archive_dest" ]; then - echo "Archiving" "$(which op)" "to $OP_BINARY_PATH/$op_ver/" - cp "$(which op)" "$OP_BINARY_PATH/$op_ver/op"; + echo "Archiving" "$op_path" "to $op_archive_dir" + cp "$op_path" "$op_archive_dest"; else echo "op $op_ver archive already present" fi echo "Checking hashes" -md5check /usr/local/bin/op "$OP_BINARY_PATH/$op_ver/op" || quit "Hashes don't match for /usr/local/bin/op vs $OP_BINARY_PATH/$op_ver/op" 1 +md5check "$op_path" "$op_archive_dest" || quit "Hashes don't match for $op_path vs $op_archive_dest" 1 echo "Hashes match" +echo "Compressing old binaries and removing originals" +compress_archives "$op_ver" || quit "Compressing archives failed" $? diff --git a/scripts/batch_create.py b/scripts/batch_create.py index d0fba13c..3e927f43 100755 --- a/scripts/batch_create.py +++ b/scripts/batch_create.py @@ -2,6 +2,8 @@ from argparse import ArgumentParser, Namespace from typing import List, Optional +import dotenv + from pyonepassword import OP, logging from pyonepassword.api.constants import LETTERS_DIGITS_SYMBOLS_20 from pyonepassword.api.object_types import ( @@ -52,7 +54,12 @@ def batch_create_parse_args(): parser.add_argument("--username", help="Base username", default="user_") parser.add_argument( "--alternating-tags", help="Comma-separated list of tags to alternate between when creating items") + parser.add_argument( + "--url", help="URL string to associate with the items created") + parser.add_argument( + "--starting-number", help="Starting number of the first item to create", type=int, default=0) parser.add_argument("--category", help="Category of item to create") + parser.add_argument("--env-file", help="Path to a .env file to load") parsed = parser.parse_args() return parsed @@ -65,6 +72,10 @@ def create_items(options: Namespace): vault = options.vault item_name_base = options.name username_base = options.username + url = options.url + start = options.starting_number + if start < 0: + raise Exception("Starting number must be >= 0") category = "login" if options.category: @@ -76,15 +87,17 @@ def create_items(options: Namespace): print(f"creating {count} {category} items in {vault} vault") for i in range(0, count): + item_num = i + start _tags = [] if tags: tagnum = i % len(tags) _tags = tags[tagnum:tagnum + 1] - title = f"{item_name_base} {i:02d}" + title = f"{item_name_base} {item_num:02d}" password = LETTERS_DIGITS_SYMBOLS_20 if category == "login": - username = f"{username_base}{i:02d}" - item_template = OPLoginItemTemplate(title, username, tags=_tags) + username = f"{username_base}{item_num:02d}" + item_template = OPLoginItemTemplate( + title, username, url=url, tags=_tags) elif category == "password": item_template = OPPasswordItemTemplate(title, tags=_tags) else: @@ -95,12 +108,18 @@ def create_items(options: Namespace): def main(): options = batch_create_parse_args() + if options.env_file: + loaded = dotenv.load_dotenv(options.env_file) + if not loaded: + print(f"Failed to load env file {options.env_file}") + return -1 create_items(options) + return 0 if __name__ == "__main__": try: - main() + exit(main()) except KeyboardInterrupt: print("Interruped. terminating") exit(130) diff --git a/scripts/op_env b/scripts/op_env new file mode 100755 index 00000000..d776ffa3 --- /dev/null +++ b/scripts/op_env @@ -0,0 +1,30 @@ +#!/bin/sh -e + +# convenience wrapper for 'op' that sources a .env file and exports service account token + +# usage ./scripts/op_env ./path/to/.env_file [op cli args] +# best used from an alias or shell function set in .init/00_pyonepassword + +env_path="$1" + +if [ ! -f "$env_path" ]; +then + echo "Specify a path to a .env file" + exit 1 +else + shift +fi + +# not necessarily the source, but this satisfies shellcheck +# shellcheck source=../dot_env_files/.env_pyonepassword_test_rw +. "$env_path" + +if [ -z "$OP_SERVICE_ACCOUNT_TOKEN" ]; +then + echo "env file ($env_path) did not contain a OP_SERVICE_ACCOUNT_TOKEN value" + exit 1 +fi + +export OP_SERVICE_ACCOUNT_TOKEN + +op "$@" diff --git a/scripts/response-gen-svc-acct.sh b/scripts/response-gen-svc-acct.sh new file mode 100755 index 00000000..fb89a4b5 --- /dev/null +++ b/scripts/response-gen-svc-acct.sh @@ -0,0 +1,18 @@ +#!/bin/sh -e + +_readlink(){ readlink "$1" || echo "$1"; } + +# Don't shadow the 'realpath' executable which may be installed on +# some systems (e.g., via homebrew) +_realpath() { _path="$1"; cd "$(dirname "$_path")" && _readlink "$(pwd)"/"$(basename "$_path")"; } + +_realscriptpath() { + _realpath "$0" +} + +real_path="$(_realscriptpath)" +SRC_ROOT="$(cd "$(dirname "$real_path")" && dirname "$(pwd)")" + +export RESP_GEN_DOT_ENV_FILE="$SRC_ROOT"/dot_env_files/.env_pyonepassword_test_rw + +response-generator "$@" diff --git a/scripts/sanitize.py b/scripts/sanitize.py old mode 100644 new mode 100755 index 80f556c5..501a9b4f --- a/scripts/sanitize.py +++ b/scripts/sanitize.py @@ -1,13 +1,88 @@ +#!/usr/bin/env python3 + import fnmatch +import hashlib import json import os import re +import shutil from argparse import ArgumentParser from configparser import ConfigParser from pathlib import Path from typing import Dict -WHITELIST = ["*/output", "*.txt", "*.json", "*.py"] +WHITELIST = ["*/output", "*.txt", "*.json", "*.py", "*/input/**"] + + +def digest_file(file_path): + data = open(file_path, "rb").read() + digest = None + # ignore input if None or if empty string + if data: + if isinstance(data, str): + data = data.encode() + hash = hashlib.md5(data) + digest = hash.hexdigest() + return digest + + +class InputHashes: + """ + A class to track changes to input data to 'mock-op' so that response + directories can be updated allowing responses to be looked up by + the input's new hash + + This addresses the problem where this script santizes mock-op output that + would later be used as input to another mock-op invocation. + + If the previous command's output has changed the hash of the next command's + input will have changed as well, and can't be located in the response + directory by its hash + """ + INPUT_FILE_BASENAME = "input.bin" + + def __init__(self): + self._input_paths = {} + self._updated_hashes = {} + + def add_input_path(self, input_path): + input_path = Path(input_path) + if input_path.name == self.INPUT_FILE_BASENAME: + original_hash = digest_file(input_path) + parent_base = input_path.parent.name + if parent_base == original_hash: + print( + f"Adding input file: {input_path}, hash: {original_hash}") + self._input_paths[input_path] = {"orig_hash": original_hash} + + def update_input_paths(self): + for key, pathdict in self._input_paths.items(): + input_path = Path(key) + file_base = input_path.name + parent = input_path.parent + parent_base = input_path.parent.name + containing_path = parent.parent + + orig_hash = pathdict["orig_hash"] + if orig_hash != parent_base: + continue + + new_hash = digest_file(input_path) + if new_hash == orig_hash: + continue + new_path = Path(containing_path, new_hash, file_base) + new_parent = new_path.parent + new_parent.mkdir(parents=True, exist_ok=True) + print(f"moving: {input_path}") + print(f"to: {new_path}") + shutil.move(input_path, new_path) + parent.rmdir() + + self._updated_hashes[orig_hash] = new_hash + + @property + def updated_hashes(self) -> Dict[str, str]: + return self._updated_hashes class TextFile: @@ -109,7 +184,7 @@ def _sanitize_list(self, list_obj: list, sanitization_map: Dict[str, str]): return new_list -def _santize_single(filepath, sanitization_map, whitelist): +def _santize_single(filepath, sanitization_map, whitelist, input_hashes=None): changed = False considered = False for pattern in whitelist: @@ -120,12 +195,14 @@ def _santize_single(filepath, sanitization_map, whitelist): else: textfile = TextFile(filepath, sanitization_map) considered = True + if input_hashes: + input_hashes.add_input_path(filepath) changed = textfile.sanitize() break return (considered, changed) -def sanitize_files(sanitize_path, sanitization_map): +def sanitize_files(sanitize_path, sanitization_map, input_hashes=None): changed_count = 0 file_count = 0 sanitize_path = Path(sanitize_path) @@ -143,7 +220,7 @@ def sanitize_files(sanitize_path, sanitization_map): for file in files: filepath = Path(root, file) considered, changed = _santize_single( - filepath, sanitization_map, local_whitelist) + filepath, sanitization_map, local_whitelist, input_hashes=input_hashes) if considered: file_count += 1 if changed: @@ -176,7 +253,18 @@ def main(): print(f"Sanitizing: {sanitize_path}") replacement_map = dict(config['replacements']) - sanitize_files(sanitize_path, replacement_map) + input_hashes = InputHashes() + sanitize_files(sanitize_path, replacement_map, input_hashes=input_hashes) + + # calculate new hashes of all 'input.bin' files and move them to their new directories + # and track all old_hash:new_hash pairs in a dictionary + input_hashes.update_input_paths() + + # Run the sanitization again, this time with the {old_hash:new_hash} + # map for any changed input files + # If any changed, this should result in the corresponding response directory JSON + # files being updated accordingly. + sanitize_files(sanitize_path, input_hashes.updated_hashes) if __name__ == "__main__": diff --git a/setup.py b/setup.py index 0390d34f..2ee47725 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ import os +import re from setuptools import find_packages, setup from setuptools.command.egg_info import egg_info @@ -21,6 +22,22 @@ def project_path(): with open(os.path.join(proj_path, "README.md"), "r") as fp: long_description = fp.read() +GITHUB_URL = "https://github.com/zcutlip/pyonepassword" +# links on PyPI should have absolute URLs +# this awful regex looks for [any text](any url), making sure there's no 'http:' +# in the url part +# it then inserts https://github.com/zcutlip/pyonepassword/blobl/main/ +# after between the '(' and the relative URL +# believe it or not this also works with directories such as examples/item_editing/ +# Github redirects from blob/main/ to tree/main/ in this case +# source: https://github.com/pypa/readme_renderer/issues/163#issuecomment-1679601106 +long_description = re.sub( + r"(\[[^\]]+\]\()((?!https?:)[^\)]+)(\))", + lambda m: m.group(1) + GITHUB_URL + "/blob/main/" + + m.group(2) + m.group(3), + long_description, +) + packages = find_packages( where=".", include=["pyonepassword", "pyonepassword.*"]) @@ -52,12 +69,8 @@ def run(self): url="https://github.com/zcutlip/pyonepassword", packages=packages, - # We need python3.9 in order to use importlib.resources.files in templates.py - python_requires='>=3.8', + python_requires='>=3.9', install_requires=[ - # importlib.resources.files requires python >=3.9 - # if python 3.8, need to install 3rd importlib-resources - "importlib-resources>=5.2.0; python_version<'3.9'", "python-singleton-metaclasses" ], package_data={'pyonepassword': ['data/**', 'py.typed']}, diff --git a/submodules/repo-mgmt-scripts b/submodules/repo-mgmt-scripts index 36d92ffd..3de3d8a6 160000 --- a/submodules/repo-mgmt-scripts +++ b/submodules/repo-mgmt-scripts @@ -1 +1 @@ -Subproject commit 36d92ffda7c661cfc007c04507c25898dfd94705 +Subproject commit 3de3d8a675460a536ae106adcbd2995b7c8ae449 diff --git a/svc_account_todo.md b/svc_account_todo.md deleted file mode 100644 index c1a6677f..00000000 --- a/svc_account_todo.md +++ /dev/null @@ -1,40 +0,0 @@ -# TODO Items for Service Account Support - -github issue: [38](https://github.com/zcutlip/pyonepassword/issues/38) - -- [x] verify op operations requiring a vault to be specified have a vault kwarg (see below re: supported/unsupported operations) -- [ ] test the following cases - - [x] simulate valid service account token & permitted operation - * This is done in `test_svc_acct_support/test_svc_acct_primary_api.py` - - [x] simulate valid service account token, but non-permitted operation (e.g., create, but svc acct is read-only) - * This is done in `test_svc_acct_support/test_svc_acct_primary_api.py` - - [ ] service account token is corrupted (normal svc account token but with characters missing or replaced) - * it may not be practical to simulate this in a way that actually tests how we handle `op`'s behavior - - [ ] service account token is completely invalid (e.g., "foo") - * it may not be practical to simulate this in a way that actually tests how we handle `op`'s behavior - - [x] service account token is valid - * This is done in `test_svc_acct_support/test_svc_acct_primary_api.py` - - [x] simulate a service account token having been revoked - - [x] simulate a valid service account token, but non-permitted vault -- [x] raise meaningful exception if caller attempts an operation not supported by service accounts - * supported/unsupported operations break down into the following categories: - * operation is supported unconditionally, e.g., `op item list` - * operation is supported but has one or more mandatory options, e.g., `op item get` requires `--vault` - * operation is supported but has one or more prohibited options, e.g., `op vault list` can't be used with `--user` or `--group` - * operation is not supported - - [x] System for checking if an operation and its options are/are not supported *before* executing the command - - [x] This is done via `OPSvcAcctSupportRegistry` and the JSON registry under `pyonepassword/data/svc_acct_commands` -- [x] proper behavior if caller to `OP()` provides a password or other parameter not compatible with service accounts - - [x] Probably raise an exception since caller may be confused about proper API use, or not realize they have a service account token set - * Now raising OPAuthenticationException if existing_auth == EXISTING_AUTH_REQD and password != None - - [x] Test above behavior -- [ ] Document service account support - - [x] API docstrings - - [x] README or other .md doc - - [ ] example code in `examples` -- [x] Minimum version check -- [x] Name all service account related classes and other symbols consistently - * SvcAcct? - * SvcAccount? - * ServiceAcct? -- [ ] delete this list when everything above is done diff --git a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-1.cfg b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-1.cfg index e7aaad8b..62396068 100644 --- a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-1.cfg +++ b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-1.cfg @@ -1,8 +1,9 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op/responses-item-delete-multiple response-path = responses-1 input-path = input response-dir-file = response-directory-1.json +state-config = ./tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-1.json [cli-version] type = cli-version @@ -39,7 +40,7 @@ enabled = false type = item-delete-multiple tags = tag_1 vault = Test Data 3 -changes_state = true +changes-state = true enabled = false [item-list-test-data-3-password] @@ -52,5 +53,5 @@ vault = Test Data 3 type = item-delete-multiple categories = password vault = Test Data 3 -changes_state = true +changes-state = true # enabled = false diff --git a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-2.cfg b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-2.cfg index b1dd3796..da3431ac 100644 --- a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-2.cfg +++ b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-2.cfg @@ -1,8 +1,9 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op/responses-item-delete-multiple response-path = responses-2 input-path = input response-dir-file = response-directory-2.json +state-config = ./tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-1.json [cli-version] type = cli-version diff --git a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-3.cfg b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-3.cfg index b0103c7e..5ba598bd 100644 --- a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-3.cfg +++ b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-3.cfg @@ -1,8 +1,9 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op/responses-item-delete-multiple response-path = responses-3 input-path = input response-dir-file = response-directory-3.json +state-config = ./tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-2.json [cli-version] type = cli-version @@ -42,5 +43,5 @@ enabled = true type = item-delete-multiple title-glob = Example Login Item *2 vault = Test Data 3 -changes_state = true +changes-state = true enabled = true diff --git a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-4.cfg b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-4.cfg index 65df8013..9456a0d7 100644 --- a/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-4.cfg +++ b/tests/config/mock-op/response-generation/item-delete-multiple/response-generation-4.cfg @@ -1,8 +1,9 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op/responses-item-delete-multiple response-path = responses-4 input-path = input response-dir-file = response-directory-4.json +state-config = ./tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-2.json [cli-version] type = cli-version diff --git a/tests/config/mock-op/response-generation/item-edit/response-generation-item-edit-1.cfg b/tests/config/mock-op/response-generation/item-edit/response-generation-item-edit-1.cfg new file mode 100644 index 00000000..0459ce1c --- /dev/null +++ b/tests/config/mock-op/response-generation/item-edit/response-generation-item-edit-1.cfg @@ -0,0 +1,594 @@ +[MAIN] +config-path = ./tests/config/mock-op/responses-item-edit +response-path = responses-1 +input-path = input +response-dir-file = response-directory-1.json +state-iteration = 0 +state-config = ./tests/config/mock-op/responses-item-edit/item-edit-state-config.json +# Be sure to set RESP_GEN_DOT_ENV_FILE=path/to/.env_corrupt_svc_account +# to have response-generator load the service account token +existing-auth = required + +[cli-version] +type = cli-version +enabled = false + +[list-signed-in-accounts] +type = account-list +enabled = false + +[whoami] +type = whoami +enabled = false + +[item-get-example-login-00] +# OP.item_edit_set_password() peforms an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 00 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-00-set-password] +type=item-edit +subtype=set-password +item-identifier = Example Login Item 00 +field-label = password +password = new password +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-01] +# OP.item_edit_generate_password() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +type=item-get +item-identifier = Example Login Item 01 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-01-generate-password] +type=item-edit +subtype=generate-password +item-identifier = Example Login Item 01 +password-recipe = 20,letters,digits +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-02] +# OP.item_edit_title() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +type=item-get +item-identifier = Example Login Item 02 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-02-set-title] +type=item-edit +subtype=set-title +item-identifier = Example Login Item 02 +item-title = Example Login Item 02 (New Title) +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-03] +# OP.item_edit_set_password() peforms an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 03 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-03-set-password] +type=item-edit +subtype=set-password +item-identifier = Example Login Item 03 +section-label = Example Section +field-label = password in a section +password = new password in a section +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-04] +# OP.item_edit_favorite() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +# +# for item_edit_favorite +# favorite should be false in this response before +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 04 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-04-set-favorite] +# set the favorite flag on this item to true +type=item-edit +subtype=set-favorite +item-identifier = Example Login Item 04 +item-favorite = true +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-05] +# OP.item_edit_favorite() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +# +# for item_edit_favorite +# favorite should be true in this response before +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 05 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-05-set-favorite] +# set the favorite flag on this item to false +type=item-edit +subtype=set-favorite +item-identifier = Example Login Item 05 +item-favorite = false +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-06] +# OP.item_edit_tags() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +# +# for item_edit_tags +# tags should be [tag_1, tag_2] in this response before +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 06 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-06-set-tags] +# set the new set of tags on this item +type=item-edit +subtype=set-tags +item-identifier = Example Login Item 06 +tags=tag_3,tag_4,tag_5 +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-07] +# OP.item_edit_tags() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +# +# for item_edit_tags +# +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 07 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-07-set-tags] +# set a new set of tags on this item +type=item-edit +subtype=set-tags +item-identifier = Example Login Item 07 +tags= tag_1,tag_2,tag_3 +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-08] +# OP.item_edit_tags() peforms an item_get() first +# so we need to support a get operation on the unedited item +# +# for item_edit_tags +# +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 08 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-08-set-tags] +# set a new set of tags on this item +type=item-edit +subtype=set-tags +item-identifier = Example Login Item 08 +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-08a] +# OP.item_edit_tags() peforms an item_get() first +# so we need to support a get operation on the unedited item +# +# for item_edit_tags +# +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 08a +vault = Test Data 2 +enabled = false + +[item-edit-example-login-08a-set-tags] +# set a new set of tags on this item +type=item-edit +subtype=set-tags +item-identifier = Example Login Item 08a +# these tags overlap with the original tags +tags = tag_3,tag_4,tag_5 +append-tags = True +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-09] +# OP.item_edit_url() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +# +# for item_edit_set_url +# +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 09 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-09-set-url] +# set a new URL on this item +type=item-edit +subtype=set-url +item-identifier = Example Login Item 09 +url = https://item-09-url.com/login.html +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-10] +# OP.item_edit_url() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +# +# for item_edit_set_url +# +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 10 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-10-set-url] +# set a new URL on this item +type=item-edit +subtype=set-url +item-identifier = Example Login Item 10 +url = https://item-10-url.com/login.html +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-11] +# OP.item_edit_url() does not require this +# but our test cases to explicitly perform an item_get() on the +# unmodified item, so we need this +# +# for item_edit_set_url +# +# the item-edit operation below +type=item-get +item-identifier = Example Login Item 11 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-11-set-url] +# set a new URL on this item using "--url" +type=item-edit +subtype=set-url +item-identifier = Example Login Item 11 +url = https://item-11-url.com/login.html +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-12] +# OP.item_edit_set_text_field() performs an item_get() first +# so we need to support a get operation on the unedited item +# +item-identifier = Example Login Item 12 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-12-set-field-text] +# set a new text field value on this item using field assignment syntax +type=item-edit +subtype=set-field-text +item-identifier = Example Login Item 12 +field-label = Text Field 01 +section-label = Section 01 +value = new text field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-13] +# OP.item_edit_set_url_field() performs an item_get() first +# so we need to support a get operation on the unedited item +# +type=item-get +item-identifier = Example Login Item 13 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-13-set-field-url] +# set a new url field value on this item using field assignment syntax +type=item-edit +subtype=set-field-url +item-identifier = Example Login Item 13 +field-label = URL Field 01 +section-label = Section 01 +value = https://new-url.com/login.html +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-14] +# OP.item_edit_set_text_field() performs an item_get() first +# so we need to support a get operation on the unedited item +# +type = item-get +item-identifier = Example Login Item 14 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-14-set-field-text] +# set a new text field value on this item using field assignment syntax +type=item-edit +subtype=set-field-text +item-identifier = Example Login Item 14 +field-label = Password to Text 01 +section-label = Section 01 +value = new text field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-15] +# OP.item_edit_set_url_field() performs an item_get() first +# so we need to support a get operation on the unedited item +# +type=item-get +item-identifier = Example Login Item 15 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-15-set-field-url] +# set a new url field value on this item using field assignment syntax +# the field's type should change from text to URL +type=item-edit +subtype=set-field-url +item-identifier = Example Login Item 15 +field-label = Text field to be updated to URL 01 +section-label = Section 01 +value = https://new-url.com/login.html +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-16] +# This is an item with two sections and two text fields +# It is for a test case to set a mismatched section and field +type=item-get +item-identifier = Example Login Item 16 +vault = Test Data 2 +enabled = false + +[item-get-example-login-17] +# OP.item_edit_add_text_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 17 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-17-add-text-field] +# add a new section and text field on this item using field assignment syntax +type=item-edit +subtype=add-text-field +item-identifier = Example Login Item 17 +field-label = Text Field 01 +section-label = Section 01 +value = new text field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-17a] +# OP.item_edit_add_text_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 17a +vault = Test Data 2 +enabled = false + +[item-edit-example-login-17a-add-text-field] +# add a new section and text field on this item using field assignment syntax +# item has an existing text field with the same label, but different section +type=item-edit +subtype=add-text-field +item-identifier = Example Login Item 17a +field-label = Text Field 01 +section-label = Section 01 +value = new text field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-17b] +# OP.item_edit_add_text_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 17b +vault = Test Data 2 +enabled = false + +[item-edit-example-login-17b-add-text-field] +# add a new section and text field on this item using field assignment syntax +# item has an existing section with the same label, but a text field with a different label +type=item-edit +subtype=add-text-field +item-identifier = Example Login Item 17b +field-label = Text Field 01 +section-label = Section 01 +value = new text field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-17c] +# OP.item_edit_add_text_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 17c +vault = Test Data 2 +enabled = false + +[item-edit-example-login-17c-add-text-field] +# add a new section and text field on this item using field assignment syntax +# item has an existing section with the same label, +# and a text field with the same label, +# but the text field is associated with a different section +type=item-edit +subtype=add-text-field +item-identifier = Example Login Item 17c +field-label = Text Field 01 +section-label = Section 01 +value = new text field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-17d] +# OP.item_edit_add_text_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 17d +vault = Test Data 2 +enabled = false + +[item-edit-example-login-17d-add-text-field] +# item starts out with no sections or fields +# add a new text field with no section on this item using field assignment syntax +type=item-edit +subtype=add-text-field +item-identifier = Example Login Item 17d +field-label = Text Field With no Section 01 +value = new text field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-18] +# OP.item_edit_add_password_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 18 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-18-add-password-field] +# add a new section and text field on this item using field assignment syntax +type=item-edit +subtype=add-password-field +item-identifier = Example Login Item 18 +field-label = Password Field 01 +section-label = Section 01 +password = new password field value +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-19] +# this item has two sections with identically named fields +# this is to test adding a field with an ambiguous name match +# this should error and the item not modified +type=item-get +item-identifier = Example Login Item 19 +vault = Test Data 2 +enabled = false + +[item-get-example-login-20] +# this item has a sections with a field +# this is to test adding a field/section pair that +# exactly matches the existing section and field +# this should error and the item not modified +type=item-get +item-identifier = Example Login Item 20 +vault = Test Data 2 +enabled = false + +[item-get-example-login-21a] +# OP.item_edit_delete_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 21a +vault = Test Data 2 +enabled = false + +[item-edit-example-login-21a-delete-field] +# delete a section and text field from this item using field assignment syntax +type=item-edit +subtype=delete-field +item-identifier = Example Login Item 21a +field-label = Text Field 01 +section-label = Section 01 +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-21b] +# OP.item_edit_delete_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 21b +vault = Test Data 2 +enabled = false + +[item-edit-example-login-21b-delete-field] +# delete a text field from this item using field assignment syntax +type=item-edit +subtype=delete-field +item-identifier = Example Login Item 21b +field-label = Text Field 01 +vault = Test Data 2 +changes-state = true +enabled = false + +[item-get-example-login-23] +# OP.item_edit_add_password_field() performs an item_get() first +# so we need to support a get operation on the unedited item +type=item-get +item-identifier = Example Login Item 23 +vault = Test Data 2 +enabled = false + +[item-edit-example-login-23-add-url-field] +# add a new section and URL field on this item using field assignment syntax +type=item-edit +subtype=add-url-field +item-identifier = Example Login Item 23 +field-label = URL Field 01 +section-label = Section 01 +value = https://new-url-field.com/ +vault = Test Data 2 +changes-state = true +enabled = false diff --git a/tests/config/mock-op/response-generation/item-edit/response-generation-item-edit-2.cfg b/tests/config/mock-op/response-generation/item-edit/response-generation-item-edit-2.cfg new file mode 100644 index 00000000..9669a5fe --- /dev/null +++ b/tests/config/mock-op/response-generation/item-edit/response-generation-item-edit-2.cfg @@ -0,0 +1,265 @@ +[MAIN] +config-path = ./tests/config/mock-op/responses-item-edit +response-path = responses-2 +input-path = input +response-dir-file = response-directory-2.json +state-iteration = 1 +state-config = ./tests/config/mock-op/responses-item-edit/item-edit-state-config.json +# Be sure to set RESP_GEN_DOT_ENV_FILE=path/to/.env_corrupt_svc_account +# to have response-generator load the service account token +existing-auth = required + +[cli-version] +type = cli-version +enabled = false + +[list-signed-in-accounts] +type = account-list +enabled = false + +[whoami] +type = whoami +enabled = false + +[item-get-example-login-00] +type=item-get +item-identifier = Example Login Item 00 +vault = Test Data 2 +enabled = false + +[item-get-example-login-01] +type=item-get +item-identifier = Example Login Item 01 +vault = Test Data 2 +enabled = false + +[item-get-example-login-02] +type=item-get +item-identifier = Example Login Item 02 (New Title) +vault = Test Data 2 +enabled = false + +[item-get-example-login-03] +type=item-get +item-identifier = Example Login Item 03 +vault = Test Data 2 +enabled = false + +[item-get-example-login-04] +# for item_edit_favorite +# favorite should be true in this response +type=item-get +item-identifier = Example Login Item 04 +vault = Test Data 2 +enabled = false + +[item-get-example-login-05] +# for item_edit_favorite +# favorite should be false in this test +type=item-get +item-identifier = Example Login Item 05 +vault = Test Data 2 +enabled = false + +[item-get-example-login-06] +# for item_edit_tags +# tags should be [tag_3, tag_4, tag_5] +type=item-get +item-identifier = Example Login Item 06 +vault = Test Data 2 +enabled = false + +[item-get-example-login-07] +# for item_edit_tags +# tags should be [tag_1, tag_2, tag_3] +type=item-get +item-identifier = Example Login Item 07 +vault = Test Data 2 +enabled = false + +[item-get-example-login-08] +# for item_edit_tags +# tags should be an empty list +type=item-get +item-identifier = Example Login Item 08 +vault = Test Data 2 +enabled = false + +[item-get-example-login-08a] +# for item_edit_tags +# tags should be an empty list +type=item-get +item-identifier = Example Login Item 08a +vault = Test Data 2 +enabled = False + +[item-get-example-login-09] +# for item_edit_set_url +# url should be https://item-09-url.com/login.html +type=item-get +item-identifier = Example Login Item 09 +vault = Test Data 2 +enabled = false + +[item-get-example-login-10] +# for item_edit_set_url +# url should be https://item-10-url.com/login.html +type=item-get +item-identifier = Example Login Item 10 +vault = Test Data 2 +enabled = false + +[item-get-example-login-11] +# for item_edit_set_url +# should have two urls +# - https://item-11-url.com/login.html +# - https://second-website.com/login +type=item-get +item-identifier = Example Login Item 11 +vault = Test Data 2 +enabled = false + +[item-get-example-login-12] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - Text Field 01: +# - "new text field value" +type=item-get +item-identifier = Example Login Item 12 +vault = Test Data 2 +enabled = false + +[item-get-example-login-13] +# for item_edit_set_url_field +# should have url field: +# Section 01 +# - URL Field 01: +# - https://new-url.com/login.html +type=item-get +item-identifier = Example Login Item 13 +vault = Test Data 2 +enabled = false + +[item-get-example-login-14] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - Text Field 01: +# - "new text field value" +type=item-get +item-identifier = Example Login Item 14 +vault = Test Data 2 +enabled = false + +[item-get-example-login-15] +# for item_edit_set_url_field +# should have url field: +# Section 01 +# - Text field to be updated to URL 01: +# - https://new-url.com/login.html +type=item-get +item-identifier = Example Login Item 15 +vault = Test Data 2 +enabled = false + +# There is no need for example login 16 +# it doesn't get modified, and is only used to test error handling + +[item-get-example-login-17] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - Text Field 01: +# - "new text field value" +type=item-get +item-identifier = Example Login Item 17 +vault = Test Data 2 +enabled = false + +[item-get-example-login-17a] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - Text Field 01: +# - "new text field value" +type=item-get +item-identifier = Example Login Item 17a +vault = Test Data 2 +enabled = false + +[item-get-example-login-17b] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - Text Field 01: +# - "new text field value" +type=item-get +item-identifier = Example Login Item 17b +vault = Test Data 2 +enabled = false + +[item-get-example-login-17c] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - Text Field 01: +# - "new text field value" +type=item-get +item-identifier = Example Login Item 17c +vault = Test Data 2 +enabled = false + +[item-get-example-login-17d] +# for item_edit_set_text_field +# should have text field: +# - Text Field With no Section 01: +# - "new text field value" +type=item-get +item-identifier = Example Login Item 17d +vault = Test Data 2 +enabled = false + +[item-get-example-login-18] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - Password Field 01: +# - "new password field value" +type=item-get +item-identifier = Example Login Item 18 +vault = Test Data 2 +enabled = false + +[item-get-example-login-21a] +# for item_edit_delete_field +# The following section/field should have been deleted: +# Section 01 +# - Text Field 01: +# - "example text 01" +type=item-get +item-identifier = Example Login Item 21a +vault = Test Data 2 +enabled = false + +[item-get-example-login-21b] +# for item_edit_delete_field +# The following section/field should have been deleted: +# Section 01 +# - Text Field 01: +# - "example text 01" +type=item-get +item-identifier = Example Login Item 21b +vault = Test Data 2 +enabled = false + +[item-get-example-login-23] +# for item_edit_set_text_field +# should have text field: +# Section 01 +# - URL Field 01: +# - "https://new-url-field.com/" +type=item-get +item-identifier = Example Login Item 23 +vault = Test Data 2 +enabled = false diff --git a/tests/config/mock-op/response-generation/response-generation-alternate.cfg b/tests/config/mock-op/response-generation/response-generation-alternate.cfg index 3ba1b434..0f55d699 100644 --- a/tests/config/mock-op/response-generation/response-generation-alternate.cfg +++ b/tests/config/mock-op/response-generation/response-generation-alternate.cfg @@ -1,4 +1,4 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op response-path = alternate-responses response-dir-file = alternate-response-directory.json diff --git a/tests/config/mock-op/response-generation/response-generation-svc-acct-corrupt-token.cfg b/tests/config/mock-op/response-generation/response-generation-svc-acct-corrupt-token.cfg index 061ddb95..28e90f2b 100644 --- a/tests/config/mock-op/response-generation/response-generation-svc-acct-corrupt-token.cfg +++ b/tests/config/mock-op/response-generation/response-generation-svc-acct-corrupt-token.cfg @@ -1,5 +1,5 @@ # this is for capturing/simulating 'op' behavior whith a corrupt service account token -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op response-path = responses-svc-acct-corrupt response-dir-file = svc-acct-corrupt-response-directory.json @@ -21,7 +21,7 @@ enabled = true [item-get-example-login-1-vault-test-data] type=item-get -item_identifier = Example Login 1 +item-identifier = Example Login 1 vault = Test Data enabled = false diff --git a/tests/config/mock-op/response-generation/response-generation-svc-acct-revoked-token.cfg b/tests/config/mock-op/response-generation/response-generation-svc-acct-revoked-token.cfg index 0d2bc0f1..99b4e205 100644 --- a/tests/config/mock-op/response-generation/response-generation-svc-acct-revoked-token.cfg +++ b/tests/config/mock-op/response-generation/response-generation-svc-acct-revoked-token.cfg @@ -1,4 +1,4 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op response-path = responses-svc-acct-revoked-token response-dir-file = svc-acct-revoked-token-directory.json @@ -14,7 +14,7 @@ type = account-list [item-get-example-login-1-vault-test-data] type=item-get -item_identifier = Example Login 1 +item-identifier = Example Login 1 vault = Test Data expected-return = 1 diff --git a/tests/config/mock-op/response-generation/response-generation-svc-acct.cfg b/tests/config/mock-op/response-generation/response-generation-svc-acct.cfg index b4a04776..5179ceaf 100644 --- a/tests/config/mock-op/response-generation/response-generation-svc-acct.cfg +++ b/tests/config/mock-op/response-generation/response-generation-svc-acct.cfg @@ -1,4 +1,4 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op response-path = responses-svc-acct response-dir-file = svc-acct-response-directory.json @@ -17,14 +17,14 @@ type = account-list [item-get-example-login-1-vault-test-data] type=item-get -item_identifier = Example Login 1 +item-identifier = Example Login 1 vault = Test Data [item-get-example-login-1-vault-local] # attempt to get an item from a vault # this service account isn't authorized for type=item-get -item_identifier = Example Login 1 +item-identifier = Example Login 1 vault = Local expected-return = 1 diff --git a/tests/config/mock-op/response-generation/response-generation-unauth.cfg b/tests/config/mock-op/response-generation/response-generation-unauth.cfg index f2e8de85..d72f7ce7 100644 --- a/tests/config/mock-op/response-generation/response-generation-unauth.cfg +++ b/tests/config/mock-op/response-generation/response-generation-unauth.cfg @@ -1,4 +1,4 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op response-path = responses-unauth response-dir-file = unauth-response-directory.json diff --git a/tests/config/mock-op/response-generation/response-generation.cfg b/tests/config/mock-op/response-generation/response-generation.cfg index a4be2aa7..3aa5f84b 100644 --- a/tests/config/mock-op/response-generation/response-generation.cfg +++ b/tests/config/mock-op/response-generation/response-generation.cfg @@ -1,4 +1,4 @@ -[DEFAULT] +[MAIN] config-path = ./tests/config/mock-op response-path = responses input-path = input @@ -14,54 +14,54 @@ enabled = false [item-get-example-login-1-vault-test-data] type=item-get -item_identifier = Example Login 1 +item-identifier = Example Login 1 vault = Test Data [item-get-example-login-2-vault-test-data] type=item-get -item_identifier = Example Login 2 +item-identifier = Example Login 2 vault = Test Data [item-get-by-uuid-example-login-2] type=item-get -item_identifier = nok7367v4vbsfgg2fczwu4ei44 +item-identifier = nok7367v4vbsfgg2fczwu4ei44 [item-get-example-login-vault-test-data-2] type = item-get -item_identifier = Example Login +item-identifier = Example Login vault = Test Data 2 [item-get-invalid-item] type = item-get -item_identifier = Invalid Item +item-identifier = Invalid Item enabled = false expected-return = 1 [document-get-spongebob-image] type = document-get vault=Test Data -item_identifier = Example Login 2 - 1200px-SpongeBob_SquarePants_character.svg.png.webp +item-identifier = Example Login 2 - 1200px-SpongeBob_SquarePants_character.svg.png.webp [document-get-wrong-vault] type = document-get vault=Test Data -item_identifier = Error Success +item-identifier = Error Success enabled = false expected-return = 1 [document-get-invalid] type = document-get -item_identifier = Invalid Document +item-identifier = Invalid Document enabled = false expected-return = 1 [document-get-missing-bytes] type = document-get -item_identifier = Example Attached File 2 +item-identifier = Example Attached File 2 ; simulate failure to fetch document object after success in ; fetching document details, e.g., filename -item_identifier_alternate = Example Attached File 2 - No Such File +item-identifier_alternate = Example Attached File 2 - No Such File enabled = false expected-return = 0 expected-return-2 = 1 @@ -69,23 +69,23 @@ expected-return-2 = 1 [item-get-not-a-document] ; get a non document item for later use in document_get() type = item-get -item_identifier = Not A Document +item-identifier = Not A Document [item-get-login-with-totp] type = item-get-totp vault = Test Data -item_identifier = Login With TOTP +item-identifier = Login With TOTP enabled = false [item-get-invalid-totp] type = item-get-totp vault = Test Data -item_identifier = Invalid TOTP Login +item-identifier = Invalid TOTP Login expected-return = 1 [item-get-example-identity] type = item-get -item_identifier = Example Identity +item-identifier = Example Identity enabled = True [vault-get-test-data] @@ -203,19 +203,19 @@ expected-return = 1 [item-get-example-deleteme] type = item-get vault = Test Data -item_identifier = Delete Me Unique +item-identifier = Delete Me Unique enabled = false [item-delete-example-deleteme] type = item-delete vault = Test Data -item_identifier = gtxrpmywczl5agvlpwhpbsdale +item-identifier = gtxrpmywczl5agvlpwhpbsdale enabled = false [item-get-nonexistant-item] type = item-get vault = Test Data -item_identifier = non-existent-item +item-identifier = non-existent-item enabled = true expected-return = 1 @@ -232,47 +232,47 @@ expected-return = 1 [item-delete-nonexistant-item] type = item-delete vault = Test Data -item_identifier = non-existent-item +item-identifier = non-existent-item enabled = true expected-return = 1 [item-get-archive-example-deleteme] type = item-get vault = Test Data -item_identifier = Delete and Archive Me +item-identifier = Delete and Archive Me enabled = false [item-get-archive-example-deleteme-include-archive] type = item-get include_archive = True -item_identifier = Delete and Archive Me +item-identifier = Delete and Archive Me enabled = true [item-delete-archive-example-deleteme] type = item-delete vault = Test Data -item_identifier = wedfvavlwt7byc3zbif53u7omi +item-identifier = wedfvavlwt7byc3zbif53u7omi archive = True enabled = false [item-delete-duplicate-titles] type = item-delete vault = Test Data -item_identifier = Delete Me +item-identifier = Delete Me expected-return = 1 [item-get-duplicate-titles] ; item_delete() first calls item_get() type = item-get vault = Test Data -item_identifier = Delete Me +item-identifier = Delete Me expected-return = 1 enabled = false [item-get-example-document-to-delete] type = item-get vault = Test Data -item_identifier = delete this document +item-identifier = delete this document enabled = false @@ -285,7 +285,7 @@ enabled = false [item-get-example-document-to-archive] type = item-get vault = Test Data -item_identifier = delete and archive this document +item-identifier = delete and archive this document enabled = true [document-archive-example] @@ -299,14 +299,14 @@ enabled = true type = item-get vault = Test Data include_archive = true -item_identifier = delete and archive this document +item-identifier = delete and archive this document enabled = true [document-get-example-document-include-archive] type = document-get vault = Test Data include_archive = true -item_identifier = delete and archive this document +item-identifier = delete and archive this document [document-delete-duplicates] ; documen_delete() fails on item_get(document_name) @@ -315,13 +315,13 @@ item_identifier = delete and archive this document ; - document_delete() type = item-get vault = Test Data -item_identifier = delete this duplicate document +item-identifier = delete this duplicate document expected-return = 1 [item-get-login-section-collision] type = item-get vault = Test Data -item_identifier = Login Item Section Collisions +item-identifier = Login Item Section Collisions [item-list-batch-delete] ; item_delete_multiple() diff --git a/tests/config/mock-op/response-generation/svc-acct-not-yet-auth/response-generation-svc-acct-not-yet-auth-1.cfg b/tests/config/mock-op/response-generation/svc-acct-not-yet-auth/response-generation-svc-acct-not-yet-auth-1.cfg new file mode 100644 index 00000000..0fcfaa83 --- /dev/null +++ b/tests/config/mock-op/response-generation/svc-acct-not-yet-auth/response-generation-svc-acct-not-yet-auth-1.cfg @@ -0,0 +1,30 @@ +[MAIN] +config-path = ./tests/config/mock-op/responses-svc-acct-not-yet-auth +response-path = responses-1 +response-dir-file = response-directory-1.json +state-iteration = 0 +state-config = ./tests/config/mock-op/responses-svc-acct-not-yet-auth/svc-acct-not-yet-auth-state-config.json +# Be sure to set RESP_GEN_DOT_ENV_FILE=path/to/.env_corrupt_svc_account +# to have response-generator load the service account token +existing-auth = required +skip-global-signin = True + +[cli-version] +type = cli-version +create-instance = False + +[list-signed-in-accounts] +type = account-list +create-instance = False + +[whoami] +# this should fail with the message: +# service account token set, but not authenticated yet +type = whoami +expected-return = 1 +create-instance = False + +[item-template-list] +# this should succeed and cause the 'op whoami' in state-iteration 1 to succeed +type=item-template-list +create-instance = False diff --git a/tests/config/mock-op/response-generation/svc-acct-not-yet-auth/response-generation-svc-acct-not-yet-auth-2.cfg b/tests/config/mock-op/response-generation/svc-acct-not-yet-auth/response-generation-svc-acct-not-yet-auth-2.cfg new file mode 100644 index 00000000..ae2c8607 --- /dev/null +++ b/tests/config/mock-op/response-generation/svc-acct-not-yet-auth/response-generation-svc-acct-not-yet-auth-2.cfg @@ -0,0 +1,26 @@ +[MAIN] +config-path = ./tests/config/mock-op/responses-svc-acct-not-yet-auth +response-path = responses-2 +response-dir-file = response-directory-2.json +state-iteration = 1 +state-config = ./tests/config/mock-op/responses-svc-acct-not-yet-auth/svc-acct-not-yet-auth-state-config.json +# Be sure to set RESP_GEN_DOT_ENV_FILE=path/to/.env_corrupt_svc_account +# to have response-generator load the service account token +existing-auth = required +skip-global-signin = True + +[cli-version] +type = cli-version +create-instance = False + +[list-signed-in-accounts] +type = account-list +create-instance = False + +[whoami] +# this should succeed because at iteration 0, we +# did an 'op item template list' which triggered authentication +# service account token set, but not authenticated yet +type = whoami +expected-return = 0 +create-instance = False diff --git a/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-1.json b/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-1.json index 82b7bf3c..8e240bbd 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-1.json +++ b/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-1.json @@ -1,18 +1,20 @@ { - "iteration": 0, - "max-iterations": 2, - "response-directory-list": [ - "tests/config/mock-op/responses-item-delete-multiple/response-directory-1.json", - "tests/config/mock-op/responses-item-delete-multiple/response-directory-2.json" - ], - "env-list": [ - { - "set_vars": {}, - "pop_vars": [] - }, - { - "set_vars": {}, - "pop_vars": [] - } - ] + "iteration": 0, + "max-iterations": 2, + "state-list": [ + { + "response-directory": "tests/config/mock-op/responses-item-delete-multiple/response-directory-1.json", + "env-vars": { + "set": {}, + "pop": [] + } + }, + { + "response-directory": "tests/config/mock-op/responses-item-delete-multiple/response-directory-2.json", + "env-vars": { + "set": {}, + "pop": [] + } + } + ] } diff --git a/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-2.json b/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-2.json index 002d4fd2..095b0b9e 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-2.json +++ b/tests/config/mock-op/responses-item-delete-multiple/mock-op-state-config-2.json @@ -1,18 +1,20 @@ { - "iteration": 0, - "max-iterations": 2, - "response-directory-list": [ - "tests/config/mock-op/responses-item-delete-multiple/response-directory-3.json", - "tests/config/mock-op/responses-item-delete-multiple/response-directory-4.json" - ], - "env-list": [ - { - "set_vars": {}, - "pop_vars": [] - }, - { - "set_vars": {}, - "pop_vars": [] - } - ] + "iteration": 0, + "max-iterations": 2, + "state-list": [ + { + "response-directory": "tests/config/mock-op/responses-item-delete-multiple/response-directory-3.json", + "env-vars": { + "set": {}, + "pop": [] + } + }, + { + "response-directory": "tests/config/mock-op/responses-item-delete-multiple/response-directory-4.json", + "env-vars": { + "set": {}, + "pop": [] + } + } + ] } diff --git a/tests/config/mock-op/responses-item-delete-multiple/response-directory-1.json b/tests/config/mock-op/responses-item-delete-multiple/response-directory-1.json index a5a28563..fc91d6de 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/response-directory-1.json +++ b/tests/config/mock-op/responses-item-delete-multiple/response-directory-1.json @@ -62,7 +62,7 @@ } }, "commands_with_input": { - "390cd969c240b16c28e49f8e74ca926a": { + "fc4bcec96b5abaca5effb19e02d128a3": { "--format|json|item|delete|-|--vault|Test Data 3": { "exit_status": 0, "stdout": "output", @@ -71,7 +71,7 @@ "changes_state": false } }, - "674e388ad179855330331c2dc866c21d": { + "4e9a7cde972525b611899b999d4c155f": { "--format|json|item|delete|-|--vault|Test Data 3": { "exit_status": 0, "stdout": "output", @@ -80,7 +80,7 @@ "changes_state": true } }, - "a80e7927c2b56d4dffa2ee282eda95b1": { + "c49d5d926ae1f2787e7e3854c18e5ed5": { "--format|json|item|delete|-|--vault|Test Data 3": { "exit_status": 0, "stdout": "output", @@ -89,7 +89,7 @@ "changes_state": false } }, - "7ed951330c499820daf25277617fdfd1": { + "308a7e0293452e7e18bea5e68eb17040": { "--format|json|item|delete|-|--vault|Test Data 3": { "exit_status": 0, "stdout": "output", diff --git a/tests/config/mock-op/responses-item-delete-multiple/response-directory-3.json b/tests/config/mock-op/responses-item-delete-multiple/response-directory-3.json index 6c8cf764..402a6c96 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/response-directory-3.json +++ b/tests/config/mock-op/responses-item-delete-multiple/response-directory-3.json @@ -41,7 +41,7 @@ } }, "commands_with_input": { - "8f8301cb36cbd4065b80ccb4fd3aaffb": { + "ec4aabbc316a739fe93c5c954ea54543": { "--format|json|item|delete|-|--vault|Test Data 3": { "exit_status": 0, "stdout": "output", diff --git a/tests/config/mock-op/responses-item-delete-multiple/response-directory-4.json b/tests/config/mock-op/responses-item-delete-multiple/response-directory-4.json index 7ae97acc..42b47aad 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/response-directory-4.json +++ b/tests/config/mock-op/responses-item-delete-multiple/response-directory-4.json @@ -4,6 +4,13 @@ "input_dir": "input" }, "commands": { + "--account|5GHHPJK5HZC5BAT7WDUXW57G44|--format|json|whoami": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "whoami-account-uuid", + "changes_state": false + }, "--version": { "exit_status": 0, "stdout": "output", @@ -31,13 +38,6 @@ "stderr": "error_output", "name": "item-list-test-data-3-alt-title-glob", "changes_state": false - }, - "--account|5GHHPJK5HZC5BAT7WDUXW57G44|--format|json|whoami": { - "exit_status": 0, - "stdout": "output", - "stderr": "error_output", - "name": "whoami-account-uuid", - "changes_state": false } }, "commands_with_input": {} diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-1/cli-version/output b/tests/config/mock-op/responses-item-delete-multiple/responses-1/cli-version/output index fd7d1759..ef0f38ab 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-1/cli-version/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-1/cli-version/output @@ -1 +1 @@ -2.15.0-beta.03 +2.19.0 diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-password/output b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-password/output index b4e8d0f8..1fb0e4b8 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-password/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-password/output @@ -1,7 +1,7 @@ [ { - "id": "wqmhdc4r4v6bb7zjilaov2ketm", - "title": "Example Password Item 29", + "id": "hdrcyvhdyx7mnkwjkx67knmzmy", + "title": "Example Login Item 04", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -9,13 +9,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:49Z", - "updated_at": "2023-02-25T02:36:49Z", - "additional_information": "Fri Feb 24 18:36:49 PST 2023" + "created_at": "2023-07-08T00:40:13Z", + "updated_at": "2023-07-08T00:40:13Z", + "additional_information": "Fri Jul 7 17:40:12 PDT 2023" }, { - "id": "iamorjg7pvqiqnrtptkppufrxe", - "title": "Example Password Item 06", + "id": "7dmhpxwgak62ob3grkupddvlqm", + "title": "Example Login Item 05", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -23,13 +23,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:28Z", - "updated_at": "2023-02-25T02:36:28Z", - "additional_information": "Fri Feb 24 18:36:27 PST 2023" + "created_at": "2023-07-08T00:40:14Z", + "updated_at": "2023-07-08T00:40:14Z", + "additional_information": "Fri Jul 7 17:40:13 PDT 2023" }, { - "id": "ypfyyjdjqcmpdtdxnojhs5f524", - "title": "Example Password Item 05", + "id": "3x4sbtrvisd2ykpaxkvhzkr5ua", + "title": "Example Login Item 06", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -37,13 +37,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:26Z", - "updated_at": "2023-02-25T02:36:26Z", - "additional_information": "Fri Feb 24 18:36:26 PST 2023" + "created_at": "2023-07-08T00:40:15Z", + "updated_at": "2023-07-08T00:40:15Z", + "additional_information": "Fri Jul 7 17:40:15 PDT 2023" }, { - "id": "3eduga3mp3hvc3cvngdwscsnra", - "title": "Example Password Item 02", + "id": "z6obgfjblqb75grifhwjlcpjyq", + "title": "Example Login Item 07", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -51,13 +51,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:24Z", - "updated_at": "2023-02-25T02:36:24Z", - "additional_information": "Fri Feb 24 18:36:23 PST 2023" + "created_at": "2023-07-08T00:40:16Z", + "updated_at": "2023-07-08T00:40:16Z", + "additional_information": "Fri Jul 7 17:40:16 PDT 2023" }, { - "id": "3lw65upnafxyx3bgjr7vcpec5m", - "title": "Example Password Item 03", + "id": "ziszemmiihz7wrvaeaiyuqn2b4", + "title": "Example Login Item 08", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -65,13 +65,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:25Z", - "updated_at": "2023-02-25T02:36:25Z", - "additional_information": "Fri Feb 24 18:36:24 PST 2023" + "created_at": "2023-07-08T00:40:17Z", + "updated_at": "2023-07-08T00:40:17Z", + "additional_information": "Fri Jul 7 17:40:17 PDT 2023" }, { - "id": "pxvlarlfmri5pcdfqfzes2vcou", - "title": "Example Password Item 00", + "id": "zs3oquihnjp2hu3x56pw6sibem", + "title": "Example Login Item 09", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -79,13 +79,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:22Z", - "updated_at": "2023-02-25T02:36:22Z", - "additional_information": "Fri Feb 24 18:36:21 PST 2023" + "created_at": "2023-07-08T00:40:19Z", + "updated_at": "2023-07-08T00:40:19Z", + "additional_information": "Fri Jul 7 17:40:18 PDT 2023" }, { - "id": "3yn7h4t5wwtdij6if35mo32kpe", - "title": "Example Password Item 01", + "id": "k2kr6li24g72i2ttru6izgw6iu", + "title": "Example Login Item 10", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -93,13 +93,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:23Z", - "updated_at": "2023-02-25T02:36:23Z", - "additional_information": "Fri Feb 24 18:36:22 PST 2023" + "created_at": "2023-07-08T00:40:20Z", + "updated_at": "2023-07-08T00:40:20Z", + "additional_information": "Fri Jul 7 17:40:19 PDT 2023" }, { - "id": "oafezaon22urlgp6xbln5ksl5i", - "title": "Example Password Item 23", + "id": "jz7jgewe6a7yj4kib2frmrr3iu", + "title": "Example Login Item 11", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -107,13 +107,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:44Z", - "updated_at": "2023-02-25T02:36:44Z", - "additional_information": "Fri Feb 24 18:36:43 PST 2023" + "created_at": "2023-07-08T00:40:21Z", + "updated_at": "2023-07-08T00:40:21Z", + "additional_information": "Fri Jul 7 17:40:20 PDT 2023" }, { - "id": "rbryin3vpwyiaxthcgi4bwfrva", - "title": "Example Password Item 18", + "id": "cmvnalgy4qgqmuwfdbczu5j2w4", + "title": "Example Login Item 12", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -121,13 +121,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:39Z", - "updated_at": "2023-02-25T02:36:39Z", - "additional_information": "Fri Feb 24 18:36:39 PST 2023" + "created_at": "2023-07-08T00:40:22Z", + "updated_at": "2023-07-08T00:40:22Z", + "additional_information": "Fri Jul 7 17:40:22 PDT 2023" }, { - "id": "iuqq7aqanhu2u6by6yaxi2ifeu", - "title": "Example Password Item 20", + "id": "p3uedo3ojfcswl2rnltlhy4rm4", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -135,13 +135,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:41Z", - "updated_at": "2023-02-25T02:36:41Z", - "additional_information": "Fri Feb 24 18:36:40 PST 2023" + "created_at": "2023-07-08T00:40:23Z", + "updated_at": "2023-07-08T00:40:23Z", + "additional_information": "Fri Jul 7 17:40:23 PDT 2023" }, { - "id": "3yocw42s6hus6lahdwudobekmy", - "title": "Example Password Item 12", + "id": "drk3swentzknc4wilb3v6h2tvu", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -149,13 +149,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:33Z", - "updated_at": "2023-02-25T02:36:33Z", - "additional_information": "Fri Feb 24 18:36:33 PST 2023" + "created_at": "2023-07-08T00:40:24Z", + "updated_at": "2023-07-08T00:40:24Z", + "additional_information": "Fri Jul 7 17:40:24 PDT 2023" }, { - "id": "hzq2cbgehv7lxk6ppmrs36ilna", - "title": "Example Password Item 04", + "id": "vj6avyeejt6fqplwfsgjm7a3vq", + "title": "Example Login Item 15", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -163,13 +163,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:26Z", - "updated_at": "2023-02-25T02:36:26Z", - "additional_information": "Fri Feb 24 18:36:25 PST 2023" + "created_at": "2023-07-08T00:40:26Z", + "updated_at": "2023-07-08T00:40:26Z", + "additional_information": "Fri Jul 7 17:40:25 PDT 2023" }, { - "id": "4ely7weycrsezqej34tl3cvmuq", - "title": "Example Password Item 21", + "id": "rwfuncth7yl52yz5j7xm3h6hxa", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -177,13 +177,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:42Z", - "updated_at": "2023-02-25T02:36:42Z", - "additional_information": "Fri Feb 24 18:36:41 PST 2023" + "created_at": "2023-07-08T00:40:27Z", + "updated_at": "2023-07-08T00:40:27Z", + "additional_information": "Fri Jul 7 17:40:26 PDT 2023" }, { - "id": "vi7h2mrcwcurpfev5ljap5wp5a", - "title": "Example Password Item 19", + "id": "ozzdhe75ff4mxglyltozgkkbtu", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -191,13 +191,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:40Z", - "updated_at": "2023-02-25T02:36:40Z", - "additional_information": "Fri Feb 24 18:36:39 PST 2023" + "created_at": "2023-07-08T00:40:28Z", + "updated_at": "2023-07-08T00:40:28Z", + "additional_information": "Fri Jul 7 17:40:27 PDT 2023" }, { - "id": "3xn7otghueieeekj7qlwuiamie", - "title": "Example Password Item 22", + "id": "gglasusy7z6a75lwlveb5u3yrq", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -205,13 +205,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:43Z", - "updated_at": "2023-02-25T02:36:43Z", - "additional_information": "Fri Feb 24 18:36:42 PST 2023" + "created_at": "2023-07-08T00:40:29Z", + "updated_at": "2023-07-08T00:40:29Z", + "additional_information": "Fri Jul 7 17:40:28 PDT 2023" }, { - "id": "vwixmqypxtm6qpfkvnxnqpidwi", - "title": "Example Password Item 13", + "id": "h5i6pdoclhp43vbwold6phhnga", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -219,13 +219,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:34Z", - "updated_at": "2023-02-25T02:36:34Z", - "additional_information": "Fri Feb 24 18:36:34 PST 2023" + "created_at": "2023-07-08T00:40:30Z", + "updated_at": "2023-07-08T00:40:30Z", + "additional_information": "Fri Jul 7 17:40:30 PDT 2023" }, { - "id": "6vyjpg4a7qlyqrvjkoerqiqure", - "title": "Example Password Item 09", + "id": "k3eigerhrdjvg34okli7x7dtje", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -233,13 +233,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:30Z", - "updated_at": "2023-02-25T02:36:30Z", - "additional_information": "Fri Feb 24 18:36:30 PST 2023" + "created_at": "2023-07-08T00:40:31Z", + "updated_at": "2023-07-08T00:40:31Z", + "additional_information": "Fri Jul 7 17:40:31 PDT 2023" }, { - "id": "ovjhsuum4f4qhihczg2unyb4oi", - "title": "Example Password Item 15", + "id": "afdklchofkygv624plb54yoj4u", + "title": "Example Login Item 21", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -247,13 +247,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:36Z", - "updated_at": "2023-02-25T02:36:36Z", - "additional_information": "Fri Feb 24 18:36:36 PST 2023" + "created_at": "2023-07-08T00:40:32Z", + "updated_at": "2023-07-08T00:40:32Z", + "additional_information": "Fri Jul 7 17:40:32 PDT 2023" }, { - "id": "6ma422d4ayh5qznwubd2qq7bt4", - "title": "Example Password Item 11", + "id": "rym5zxrmjqol4ywjmuvbgefxde", + "title": "Example Login Item 22", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -261,13 +261,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:32Z", - "updated_at": "2023-02-25T02:36:32Z", - "additional_information": "Fri Feb 24 18:36:32 PST 2023" + "created_at": "2023-07-08T00:40:33Z", + "updated_at": "2023-07-08T00:40:33Z", + "additional_information": "Fri Jul 7 17:40:33 PDT 2023" }, { - "id": "jhp7txdysfpmzrwe7lohq6t7rm", - "title": "Example Password Item 10", + "id": "jxnrei56chdt27kdouhyxbytdy", + "title": "Example Login Item 23", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -275,13 +275,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:31Z", - "updated_at": "2023-02-25T02:36:31Z", - "additional_information": "Fri Feb 24 18:36:31 PST 2023" + "created_at": "2023-07-08T00:40:35Z", + "updated_at": "2023-07-08T00:40:35Z", + "additional_information": "Fri Jul 7 17:40:34 PDT 2023" }, { - "id": "3m7uhfjao4jvu3gwd6nlh2mxzu", - "title": "Example Password Item 26", + "id": "ok66qcg63elbtmcgatg74oqwyq", + "title": "Example Login Item 24", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -289,13 +289,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:46Z", - "updated_at": "2023-02-25T02:36:46Z", - "additional_information": "Fri Feb 24 18:36:46 PST 2023" + "created_at": "2023-07-08T00:40:36Z", + "updated_at": "2023-07-08T00:40:36Z", + "additional_information": "Fri Jul 7 17:40:35 PDT 2023" }, { - "id": "xzghepqdnd74semp23lcn4mezm", - "title": "Example Password Item 16", + "id": "s4rmjaxrhlzvw4usnmy5qubeyi", + "title": "Example Login Item 25", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -303,13 +303,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:37Z", - "updated_at": "2023-02-25T02:36:37Z", - "additional_information": "Fri Feb 24 18:36:37 PST 2023" + "created_at": "2023-07-08T00:40:37Z", + "updated_at": "2023-07-08T00:40:37Z", + "additional_information": "Fri Jul 7 17:40:36 PDT 2023" }, { - "id": "yskax3bk5tovxaf5epqjeyi2a4", - "title": "Example Password Item 27", + "id": "26vogk6mlyvarwfnqfcgbzhli4", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -317,13 +317,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:47Z", - "updated_at": "2023-02-25T02:36:47Z", - "additional_information": "Fri Feb 24 18:36:47 PST 2023" + "created_at": "2023-07-08T00:40:38Z", + "updated_at": "2023-07-08T00:40:38Z", + "additional_information": "Fri Jul 7 17:40:38 PDT 2023" }, { - "id": "v65ldr4zzjwd3fhcweipc45dpm", - "title": "Example Password Item 08", + "id": "ekgqssuk22vjal6k4x3faqs32i", + "title": "Example Login Item 27", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -331,13 +331,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:29Z", - "updated_at": "2023-02-25T02:36:29Z", - "additional_information": "Fri Feb 24 18:36:29 PST 2023" + "created_at": "2023-07-08T00:40:39Z", + "updated_at": "2023-07-08T00:40:39Z", + "additional_information": "Fri Jul 7 17:40:39 PDT 2023" }, { - "id": "sphszmfqtplzymns6fd5mecysa", - "title": "Example Password Item 14", + "id": "nxufacchbrsck5mlfdjvlcjnuq", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -345,13 +345,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:35Z", - "updated_at": "2023-02-25T02:36:35Z", - "additional_information": "Fri Feb 24 18:36:35 PST 2023" + "created_at": "2023-07-08T00:40:40Z", + "updated_at": "2023-07-08T00:40:40Z", + "additional_information": "Fri Jul 7 17:40:40 PDT 2023" }, { - "id": "47g6fzabagrpxmsah5gqjp7cp4", - "title": "Example Password Item 07", + "id": "kge5tr2s7plxk6snwpztawzumq", + "title": "Example Login Item 29", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -359,13 +359,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:28Z", - "updated_at": "2023-02-25T02:36:28Z", - "additional_information": "Fri Feb 24 18:36:28 PST 2023" + "created_at": "2023-07-08T00:40:42Z", + "updated_at": "2023-07-08T00:40:42Z", + "additional_information": "Fri Jul 7 17:40:41 PDT 2023" }, { - "id": "fktdugqih2grtrls7sgcggj2ui", - "title": "Example Password Item 24", + "id": "kxerddgnuq75664otjvgi2c6ky", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -373,13 +373,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:45Z", - "updated_at": "2023-02-25T02:36:45Z", - "additional_information": "Fri Feb 24 18:36:44 PST 2023" + "created_at": "2023-07-08T00:40:43Z", + "updated_at": "2023-07-08T00:40:43Z", + "additional_information": "Fri Jul 7 17:40:42 PDT 2023" }, { - "id": "p7curv2rmsv54qn44ztup5cwle", - "title": "Example Password Item 28", + "id": "6k53xgsj5fmkreejedd5vlfwsi", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -387,13 +387,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:48Z", - "updated_at": "2023-02-25T02:36:48Z", - "additional_information": "Fri Feb 24 18:36:48 PST 2023" + "created_at": "2023-07-08T00:40:44Z", + "updated_at": "2023-07-08T00:40:44Z", + "additional_information": "Fri Jul 7 17:40:43 PDT 2023" }, { - "id": "yr3nfvs236fxol4cwwezmwpaia", - "title": "Example Password Item 17", + "id": "2t6kclb5idv3wirt2bodzaxk5i", + "title": "Example Login Item 32", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -401,13 +401,13 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:38Z", - "updated_at": "2023-02-25T02:36:38Z", - "additional_information": "Fri Feb 24 18:36:38 PST 2023" + "created_at": "2023-07-08T00:40:45Z", + "updated_at": "2023-07-08T00:40:45Z", + "additional_information": "Fri Jul 7 17:40:44 PDT 2023" }, { - "id": "cu4enypkrjufapppibatttg6vm", - "title": "Example Password Item 25", + "id": "2htjmiay46rpv5svypb2yqgq5y", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -415,8 +415,246 @@ }, "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-25T02:36:46Z", - "updated_at": "2023-02-25T02:36:46Z", - "additional_information": "Fri Feb 24 18:36:45 PST 2023" + "created_at": "2023-07-08T00:40:46Z", + "updated_at": "2023-07-08T00:40:46Z", + "additional_information": "Fri Jul 7 17:40:46 PDT 2023" + }, + { + "id": "tjh6n6czsn3lh2ei4xzpt3bdoi", + "title": "Example Login Item 34", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:47Z", + "updated_at": "2023-07-08T00:40:47Z", + "additional_information": "Fri Jul 7 17:40:47 PDT 2023" + }, + { + "id": "qdtp7salm32bdrykzgx37e5rji", + "title": "Example Login Item 35", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:48Z", + "updated_at": "2023-07-08T00:40:48Z", + "additional_information": "Fri Jul 7 17:40:48 PDT 2023" + }, + { + "id": "ovrl4aamr33s4fvzfsqeoqrlha", + "title": "Example Login Item 36", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:50Z", + "updated_at": "2023-07-08T00:40:50Z", + "additional_information": "Fri Jul 7 17:40:49 PDT 2023" + }, + { + "id": "oezzsvvzc5czn5ywdipfliogym", + "title": "Example Login Item 37", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:51Z", + "updated_at": "2023-07-08T00:40:51Z", + "additional_information": "Fri Jul 7 17:40:50 PDT 2023" + }, + { + "id": "i74fqdn4yq6bgx7o5palpntu6q", + "title": "Example Login Item 38", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:52Z", + "updated_at": "2023-07-08T00:40:52Z", + "additional_information": "Fri Jul 7 17:40:51 PDT 2023" + }, + { + "id": "yt5gikpebpu5rnwqw6ll4hv5gi", + "title": "Example Login Item 39", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:53Z", + "updated_at": "2023-07-08T00:40:53Z", + "additional_information": "Fri Jul 7 17:40:53 PDT 2023" + }, + { + "id": "5jrig2lfhyutqjgfifva4x5ghi", + "title": "Example Login Item 40", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:54Z", + "updated_at": "2023-07-08T00:40:54Z", + "additional_information": "Fri Jul 7 17:40:54 PDT 2023" + }, + { + "id": "fwayio5jymekyylod5yhirqv2u", + "title": "Example Login Item 41", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:55Z", + "updated_at": "2023-07-08T00:40:55Z", + "additional_information": "Fri Jul 7 17:40:55 PDT 2023" + }, + { + "id": "xnggelzpai6dl4mtj2z5rzjm7y", + "title": "Example Login Item 42", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:57Z", + "updated_at": "2023-07-08T00:40:57Z", + "additional_information": "Fri Jul 7 17:40:56 PDT 2023" + }, + { + "id": "mylacx6bumnwyee7nw7qjwlwfm", + "title": "Example Login Item 45", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:00Z", + "updated_at": "2023-07-08T00:41:00Z", + "additional_information": "Fri Jul 7 17:41:00 PDT 2023" + }, + { + "id": "5ywqsvskxl7ppxd5zriif2n64m", + "title": "Example Login Item 43", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:58Z", + "updated_at": "2023-07-08T00:40:58Z", + "additional_information": "Fri Jul 7 17:40:57 PDT 2023" + }, + { + "id": "ren7aohec5rjl3dpybma3nth5a", + "title": "Example Login Item 44", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:59Z", + "updated_at": "2023-07-08T00:40:59Z", + "additional_information": "Fri Jul 7 17:40:59 PDT 2023" + }, + { + "id": "qvmeyoaueb7xjzup27x6bd365m", + "title": "Example Login Item 00", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:09Z", + "updated_at": "2023-07-08T00:40:09Z", + "additional_information": "Fri Jul 7 17:40:08 PDT 2023" + }, + { + "id": "awtaih7kofxs4i3vyzljobavpu", + "title": "Example Login Item 02", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:10Z", + "updated_at": "2023-07-08T00:40:10Z", + "additional_information": "Fri Jul 7 17:40:10 PDT 2023" + }, + { + "id": "egx257uzqszyuytrffccrzts5m", + "title": "Example Login Item 03", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:12Z", + "updated_at": "2023-07-08T00:40:12Z", + "additional_information": "Fri Jul 7 17:40:11 PDT 2023" + }, + { + "id": "rbuemivgo2ih5e3dms2gijaotu", + "title": "Example Login Item 01", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:10Z", + "updated_at": "2023-07-08T00:40:10Z", + "additional_information": "Fri Jul 7 17:40:09 PDT 2023" + }, + { + "id": "3yj6x5jq3tb6wbol2q57bjqfzy", + "title": "Example Login Item 46", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:02Z", + "updated_at": "2023-07-08T00:41:02Z", + "additional_information": "Fri Jul 7 17:41:01 PDT 2023" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-1/output b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-1/output index 82d2fb4e..dfca5be5 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-1/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-1/output @@ -1,7 +1,7 @@ [ { - "id": "uaaxgohlltusrsyo5gnjkmpusq", - "title": "Example Login Item 04", + "id": "bz7trmpegmv5jfcy6ei4nqnod4", + "title": "Example Login Item 00", "tags": ["tag_1"], "version": 1, "vault": { @@ -10,12 +10,12 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:57Z", - "updated_at": "2023-02-24T17:55:57Z", - "additional_information": "user_04" + "created_at": "2023-07-08T00:41:38Z", + "updated_at": "2023-07-08T00:41:38Z", + "additional_information": "user_00" }, { - "id": "k25m7frtvexrgdlvel26qwvoo4", + "id": "gb4wehmbza2fx2hs6qziksegfq", "title": "Example Login Item 02", "tags": ["tag_1"], "version": 1, @@ -25,13 +25,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:55Z", - "updated_at": "2023-02-24T17:55:55Z", + "created_at": "2023-07-08T00:41:40Z", + "updated_at": "2023-07-08T00:41:40Z", "additional_information": "user_02" }, { - "id": "c7zymyca3aqab4zitzzod33dxi", - "title": "Example Login Item 08", + "id": "ehfzlnwlbp4ou7qvir7qs6ukia", + "title": "Example Login Item 04", "tags": ["tag_1"], "version": 1, "vault": { @@ -40,13 +40,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:01Z", - "updated_at": "2023-02-24T17:56:01Z", - "additional_information": "user_08" + "created_at": "2023-07-08T00:41:42Z", + "updated_at": "2023-07-08T00:41:42Z", + "additional_information": "user_04" }, { - "id": "uuaae5bgahf6noeeb5efwdligy", - "title": "Example Login Item 36", + "id": "cvnea5iv2xboxoouqwmyokvoyq", + "title": "Example Login Item 32", "tags": ["tag_1"], "version": 1, "vault": { @@ -55,13 +55,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:28Z", - "updated_at": "2023-02-24T17:56:28Z", - "additional_information": "user_36" + "created_at": "2023-07-08T00:42:08Z", + "updated_at": "2023-07-08T00:42:08Z", + "additional_information": "user_32" }, { - "id": "swugdbaij3e3gt72u45n5sptwq", - "title": "Example Login Item 00", + "id": "l45vzrepriim5zuj5skrsjrqm4", + "title": "Example Login Item 06", "tags": ["tag_1"], "version": 1, "vault": { @@ -70,13 +70,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:53Z", - "updated_at": "2023-02-24T17:55:53Z", - "additional_information": "user_00" + "created_at": "2023-07-08T00:41:44Z", + "updated_at": "2023-07-08T00:41:44Z", + "additional_information": "user_06" }, { - "id": "227wjxp7hwepl42abtj72mrzfu", - "title": "Example Login Item 16", + "id": "gxe6mjviopczx4w4kf5jsmjnmq", + "title": "Example Login Item 08", "tags": ["tag_1"], "version": 1, "vault": { @@ -85,13 +85,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:09Z", - "updated_at": "2023-02-24T17:56:09Z", - "additional_information": "user_16" + "created_at": "2023-07-08T00:41:46Z", + "updated_at": "2023-07-08T00:41:46Z", + "additional_information": "user_08" }, { - "id": "6w5rlrwwkmv3czhilhswtvq62q", - "title": "Example Login Item 38", + "id": "w6vmwhxirabpl3hcjdnzby37wy", + "title": "Example Login Item 34", "tags": ["tag_1"], "version": 1, "vault": { @@ -100,13 +100,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:30Z", - "updated_at": "2023-02-24T17:56:30Z", - "additional_information": "user_38" + "created_at": "2023-07-08T00:42:10Z", + "updated_at": "2023-07-08T00:42:10Z", + "additional_information": "user_34" }, { - "id": "rnrvtzfyrwxa4375ebkzugw3vm", - "title": "Example Login Item 10", + "id": "zultfskvawjpsiwyrmx3lsp3fa", + "title": "Example Login Item 20", "tags": ["tag_1"], "version": 1, "vault": { @@ -115,13 +115,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:03Z", - "updated_at": "2023-02-24T17:56:03Z", - "additional_information": "user_10" + "created_at": "2023-07-08T00:41:57Z", + "updated_at": "2023-07-08T00:41:57Z", + "additional_information": "user_20" }, { - "id": "t55uxoi37fy7bv4vlpq7kuuxty", - "title": "Example Login Item 06", + "id": "36fpoffepi2s5642f7lxpfv7ai", + "title": "Example Login Item 36", "tags": ["tag_1"], "version": 1, "vault": { @@ -130,13 +130,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:59Z", - "updated_at": "2023-02-24T17:55:59Z", - "additional_information": "user_06" + "created_at": "2023-07-08T00:42:12Z", + "updated_at": "2023-07-08T00:42:12Z", + "additional_information": "user_36" }, { - "id": "tk2nncbqpiyzueumccbk3cxqo4", - "title": "Example Login Item 34", + "id": "fhoes55rhovtblrtw36nd7to5a", + "title": "Example Login Item 22", "tags": ["tag_1"], "version": 1, "vault": { @@ -145,13 +145,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:26Z", - "updated_at": "2023-02-24T17:56:26Z", - "additional_information": "user_34" + "created_at": "2023-07-08T00:41:59Z", + "updated_at": "2023-07-08T00:41:59Z", + "additional_information": "user_22" }, { - "id": "jywp5hgephetphypkyffh774n4", - "title": "Example Login Item 20", + "id": "ni4vvin6zdkmgwwvq7maeywjya", + "title": "Example Login Item 10", "tags": ["tag_1"], "version": 1, "vault": { @@ -160,13 +160,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:13Z", - "updated_at": "2023-02-24T17:56:13Z", - "additional_information": "user_20" + "created_at": "2023-07-08T00:41:47Z", + "updated_at": "2023-07-08T00:41:47Z", + "additional_information": "user_10" }, { - "id": "wfqbcyivconjpmx5wb2vo6ggcy", - "title": "Example Login Item 40", + "id": "jknkoe5pufm5lv2erwgvy5r6wa", + "title": "Example Login Item 42", "tags": ["tag_1"], "version": 1, "vault": { @@ -175,13 +175,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:32Z", - "updated_at": "2023-02-24T17:56:32Z", - "additional_information": "user_40" + "created_at": "2023-07-08T00:42:17Z", + "updated_at": "2023-07-08T00:42:17Z", + "additional_information": "user_42" }, { - "id": "mhwrdj5pas3tapdesm3fm2vaea", - "title": "Example Login Item 12", + "id": "6u4vymvejjhiku36367ctb7vo4", + "title": "Example Login Item 54", "tags": ["tag_1"], "version": 1, "vault": { @@ -190,13 +190,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:05Z", - "updated_at": "2023-02-24T17:56:05Z", - "additional_information": "user_12" + "created_at": "2023-07-08T00:42:28Z", + "updated_at": "2023-07-08T00:42:28Z", + "additional_information": "user_54" }, { - "id": "qaor4zvdl3ogtqlwl52dfdr7su", - "title": "Example Login Item 28", + "id": "tbnvtzwdonyt4d4g7pxxqsllzy", + "title": "Example Login Item 56", "tags": ["tag_1"], "version": 1, "vault": { @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:20Z", - "updated_at": "2023-02-24T17:56:20Z", - "additional_information": "user_28" + "created_at": "2023-07-08T00:42:30Z", + "updated_at": "2023-07-08T00:42:30Z", + "additional_information": "user_56" }, { - "id": "w2fri7vllesxfwcc7ket5oafaa", - "title": "Example Login Item 18", + "id": "3xup26ef7in6clllxq2lsa7f5a", + "title": "Example Login Item 38", "tags": ["tag_1"], "version": 1, "vault": { @@ -220,13 +220,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:11Z", - "updated_at": "2023-02-24T17:56:11Z", - "additional_information": "user_18" + "created_at": "2023-07-08T00:42:14Z", + "updated_at": "2023-07-08T00:42:14Z", + "additional_information": "user_38" }, { - "id": "m4ja2hv5jlbw4ibymnjkkwx5xm", - "title": "Example Login Item 50", + "id": "5kgdz3uievcxybxeuzedxkdcme", + "title": "Example Login Item 48", "tags": ["tag_1"], "version": 1, "vault": { @@ -235,12 +235,12 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:43Z", - "updated_at": "2023-02-24T17:56:43Z", - "additional_information": "user_50" + "created_at": "2023-07-08T00:42:23Z", + "updated_at": "2023-07-08T00:42:23Z", + "additional_information": "user_48" }, { - "id": "vwow3kdi4mmxgktscpou6zmbki", + "id": "cdo4yda4y2jeplelfjcglcgbpe", "title": "Example Login Item 44", "tags": ["tag_1"], "version": 1, @@ -250,13 +250,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:36Z", - "updated_at": "2023-02-24T17:56:36Z", + "created_at": "2023-07-08T00:42:19Z", + "updated_at": "2023-07-08T00:42:19Z", "additional_information": "user_44" }, { - "id": "g3hsebriiketnduxt6ziuxd23u", - "title": "Example Login Item 46", + "id": "nrvg3xsmg34yflfsphxehpw2lm", + "title": "Example Login Item 12", "tags": ["tag_1"], "version": 1, "vault": { @@ -265,13 +265,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:38Z", - "updated_at": "2023-02-24T17:56:38Z", - "additional_information": "user_46" + "created_at": "2023-07-08T00:41:49Z", + "updated_at": "2023-07-08T00:41:49Z", + "additional_information": "user_12" }, { - "id": "fdfchkseihjonakoi7hwdyxpsm", - "title": "Example Login Item 54", + "id": "sx457ikdbw45tg65ikd6beb6di", + "title": "Example Login Item 24", "tags": ["tag_1"], "version": 1, "vault": { @@ -280,13 +280,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:47Z", - "updated_at": "2023-02-24T17:56:47Z", - "additional_information": "user_54" + "created_at": "2023-07-08T00:42:00Z", + "updated_at": "2023-07-08T00:42:00Z", + "additional_information": "user_24" }, { - "id": "kjphrlaziyznxd5kyjjtb46bqi", - "title": "Example Login Item 32", + "id": "nr6byqwvhxspadvbipyyyes4xu", + "title": "Example Login Item 40", "tags": ["tag_1"], "version": 1, "vault": { @@ -295,13 +295,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:24Z", - "updated_at": "2023-02-24T17:56:24Z", - "additional_information": "user_32" + "created_at": "2023-07-08T00:42:15Z", + "updated_at": "2023-07-08T00:42:15Z", + "additional_information": "user_40" }, { - "id": "zynr2g4iu6gkartqxapeuyvw5m", - "title": "Example Login Item 14", + "id": "3k4dsem437daukn35nsmvaigp4", + "title": "Example Login Item 58", "tags": ["tag_1"], "version": 1, "vault": { @@ -310,13 +310,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:07Z", - "updated_at": "2023-02-24T17:56:07Z", - "additional_information": "user_14" + "created_at": "2023-07-08T00:42:32Z", + "updated_at": "2023-07-08T00:42:32Z", + "additional_information": "user_58" }, { - "id": "uwbejwcjz34y6qfblywunaj5ea", - "title": "Example Login Item 56", + "id": "mpxkulphilhf5lkyjobpp37t24", + "title": "Example Login Item 46", "tags": ["tag_1"], "version": 1, "vault": { @@ -325,13 +325,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:49Z", - "updated_at": "2023-02-24T17:56:49Z", - "additional_information": "user_56" + "created_at": "2023-07-08T00:42:21Z", + "updated_at": "2023-07-08T00:42:21Z", + "additional_information": "user_46" }, { - "id": "synhmwpq5j5uouptpggnwws5im", - "title": "Example Login Item 48", + "id": "7h6f4ner6zgooau4tdvbongx2q", + "title": "Example Login Item 26", "tags": ["tag_1"], "version": 1, "vault": { @@ -340,13 +340,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:41Z", - "updated_at": "2023-02-24T17:56:41Z", - "additional_information": "user_48" + "created_at": "2023-07-08T00:42:02Z", + "updated_at": "2023-07-08T00:42:02Z", + "additional_information": "user_26" }, { - "id": "rz6aoaboubxnuyyg6a2lnvoamq", - "title": "Example Login Item 24", + "id": "cwc33lay6hfiq7n7txzla3wvgy", + "title": "Example Login Item 28", "tags": ["tag_1"], "version": 1, "vault": { @@ -355,13 +355,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:17Z", - "updated_at": "2023-02-24T17:56:17Z", - "additional_information": "user_24" + "created_at": "2023-07-08T00:42:04Z", + "updated_at": "2023-07-08T00:42:04Z", + "additional_information": "user_28" }, { - "id": "3b22ugscmcg44ewj2pjb42y7qm", - "title": "Example Login Item 52", + "id": "ss3fv62w2zhlu26dx2upym5fgi", + "title": "Example Login Item 14", "tags": ["tag_1"], "version": 1, "vault": { @@ -370,13 +370,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:45Z", - "updated_at": "2023-02-24T17:56:45Z", - "additional_information": "user_52" + "created_at": "2023-07-08T00:41:51Z", + "updated_at": "2023-07-08T00:41:51Z", + "additional_information": "user_14" }, { - "id": "tetw7r5ni5diskdlkwrjk7mbze", - "title": "Example Login Item 22", + "id": "v6myd3fyhr6nof4y2rflg6i57q", + "title": "Example Login Item 50", "tags": ["tag_1"], "version": 1, "vault": { @@ -385,13 +385,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:15Z", - "updated_at": "2023-02-24T17:56:15Z", - "additional_information": "user_22" + "created_at": "2023-07-08T00:42:25Z", + "updated_at": "2023-07-08T00:42:25Z", + "additional_information": "user_50" }, { - "id": "l23yjgp2oqblp6ocqwqnr4gi7q", - "title": "Example Login Item 58", + "id": "bj54ajctjinadjknqaqg4gj4me", + "title": "Example Login Item 30", "tags": ["tag_1"], "version": 1, "vault": { @@ -400,13 +400,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:52Z", - "updated_at": "2023-02-24T17:56:52Z", - "additional_information": "user_58" + "created_at": "2023-07-08T00:42:06Z", + "updated_at": "2023-07-08T00:42:06Z", + "additional_information": "user_30" }, { - "id": "63hg6bryj6roo3ompjjkrgclq4", - "title": "Example Login Item 26", + "id": "mguxk44wot6fy5p2ihg3nz6ngu", + "title": "Example Login Item 16", "tags": ["tag_1"], "version": 1, "vault": { @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:19Z", - "updated_at": "2023-02-24T17:56:19Z", - "additional_information": "user_26" + "created_at": "2023-07-08T00:41:53Z", + "updated_at": "2023-07-08T00:41:53Z", + "additional_information": "user_16" }, { - "id": "qhxuds7r6nyyjife435636qxrm", - "title": "Example Login Item 42", + "id": "2h57i6mnc4er2fl3wmv6dqh5oq", + "title": "Example Login Item 52", "tags": ["tag_1"], "version": 1, "vault": { @@ -430,13 +430,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:34Z", - "updated_at": "2023-02-24T17:56:34Z", - "additional_information": "user_42" + "created_at": "2023-07-08T00:42:27Z", + "updated_at": "2023-07-08T00:42:27Z", + "additional_information": "user_52" }, { - "id": "ytnpda6ggiekr6rqhomcfjz4gm", - "title": "Example Login Item 30", + "id": "nmxtg62jsksz7bi67ev2qavaxy", + "title": "Example Login Item 18", "tags": ["tag_1"], "version": 1, "vault": { @@ -445,8 +445,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:22Z", - "updated_at": "2023-02-24T17:56:22Z", - "additional_information": "user_30" + "created_at": "2023-07-08T00:41:55Z", + "updated_at": "2023-07-08T00:41:55Z", + "additional_information": "user_18" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-2/output b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-2/output index 51f50d73..ea1d2752 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-2/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3-tag-2/output @@ -1,6 +1,6 @@ [ { - "id": "eqxctjvoxupbqxcmoyrxxpahbi", + "id": "jkkako75gbr5bz32jln3vx7fie", "title": "Example Login Item 59", "tags": ["tag_2"], "version": 1, @@ -10,13 +10,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:53Z", - "updated_at": "2023-02-24T17:56:53Z", + "created_at": "2023-07-08T00:42:33Z", + "updated_at": "2023-07-08T00:42:33Z", "additional_information": "user_59" }, { - "id": "44fcym7h3dk4ibetgw3cbg37aq", - "title": "Example Login Item 29", + "id": "suol6frogf5e3mszgt3eu3a4by", + "title": "Example Login Item 41", "tags": ["tag_2"], "version": 1, "vault": { @@ -25,13 +25,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:21Z", - "updated_at": "2023-02-24T17:56:21Z", - "additional_information": "user_29" + "created_at": "2023-07-08T00:42:16Z", + "updated_at": "2023-07-08T00:42:16Z", + "additional_information": "user_41" }, { - "id": "7dqfjazacjwvbbo7cxvmhj7f5m", - "title": "Example Login Item 45", + "id": "gxiweo5d3wmjl26yqwghjlwkca", + "title": "Example Login Item 05", "tags": ["tag_2"], "version": 1, "vault": { @@ -40,13 +40,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:37Z", - "updated_at": "2023-02-24T17:56:37Z", - "additional_information": "user_45" + "created_at": "2023-07-08T00:41:43Z", + "updated_at": "2023-07-08T00:41:43Z", + "additional_information": "user_05" }, { - "id": "2m7ulegiyrhxkz4vhjcwxua6me", - "title": "Example Login Item 15", + "id": "euwilsrjdmoc72oeq55mn26aua", + "title": "Example Login Item 07", "tags": ["tag_2"], "version": 1, "vault": { @@ -55,13 +55,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:08Z", - "updated_at": "2023-02-24T17:56:08Z", - "additional_information": "user_15" + "created_at": "2023-07-08T00:41:45Z", + "updated_at": "2023-07-08T00:41:45Z", + "additional_information": "user_07" }, { - "id": "3b5lgd42msjwl4ysvli52bm7ry", - "title": "Example Login Item 53", + "id": "uydqmqfe3kwt4a5lrwrdizoo2a", + "title": "Example Login Item 31", "tags": ["tag_2"], "version": 1, "vault": { @@ -70,13 +70,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:46Z", - "updated_at": "2023-02-24T17:56:46Z", - "additional_information": "user_53" + "created_at": "2023-07-08T00:42:07Z", + "updated_at": "2023-07-08T00:42:07Z", + "additional_information": "user_31" }, { - "id": "5jc5pyklfgkjxchuvp6ye5xcda", - "title": "Example Login Item 17", + "id": "464gghlcyuzukmb6mvcibbqjqi", + "title": "Example Login Item 09", "tags": ["tag_2"], "version": 1, "vault": { @@ -85,13 +85,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:10Z", - "updated_at": "2023-02-24T17:56:10Z", - "additional_information": "user_17" + "created_at": "2023-07-08T00:41:47Z", + "updated_at": "2023-07-08T00:41:47Z", + "additional_information": "user_09" }, { - "id": "fxtwj6dy64gkpttwrkdmhe2qeu", - "title": "Example Login Item 31", + "id": "xtaesbnq5quulprnggw3rbifqm", + "title": "Example Login Item 25", "tags": ["tag_2"], "version": 1, "vault": { @@ -100,13 +100,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:23Z", - "updated_at": "2023-02-24T17:56:23Z", - "additional_information": "user_31" + "created_at": "2023-07-08T00:42:01Z", + "updated_at": "2023-07-08T00:42:01Z", + "additional_information": "user_25" }, { - "id": "jx2p4scgtcgunh2byphba4aqmi", - "title": "Example Login Item 01", + "id": "xjfktjshz2y6qugc43o6v6llh4", + "title": "Example Login Item 43", "tags": ["tag_2"], "version": 1, "vault": { @@ -115,13 +115,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:54Z", - "updated_at": "2023-02-24T17:55:54Z", - "additional_information": "user_01" + "created_at": "2023-07-08T00:42:18Z", + "updated_at": "2023-07-08T00:42:18Z", + "additional_information": "user_43" }, { - "id": "xf77ka63em7xpkkbfuuu4fihjq", - "title": "Example Login Item 55", + "id": "igl2fbuhqlv4dg6qmpeuj5nfb4", + "title": "Example Login Item 11", "tags": ["tag_2"], "version": 1, "vault": { @@ -130,13 +130,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:48Z", - "updated_at": "2023-02-24T17:56:48Z", - "additional_information": "user_55" + "created_at": "2023-07-08T00:41:48Z", + "updated_at": "2023-07-08T00:41:48Z", + "additional_information": "user_11" }, { - "id": "3srtzdqw5owgexrbwejievnlba", - "title": "Example Login Item 19", + "id": "ghse4pcxazja4kaiblm6esidc4", + "title": "Example Login Item 27", "tags": ["tag_2"], "version": 1, "vault": { @@ -145,13 +145,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:12Z", - "updated_at": "2023-02-24T17:56:12Z", - "additional_information": "user_19" + "created_at": "2023-07-08T00:42:03Z", + "updated_at": "2023-07-08T00:42:03Z", + "additional_information": "user_27" }, { - "id": "5qbtlgx3q4jedrxvvnjljvpm44", - "title": "Example Login Item 33", + "id": "ajwks4dlm6n3d2mboq3eadeabm", + "title": "Example Login Item 13", "tags": ["tag_2"], "version": 1, "vault": { @@ -160,13 +160,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:25Z", - "updated_at": "2023-02-24T17:56:25Z", - "additional_information": "user_33" + "created_at": "2023-07-08T00:41:50Z", + "updated_at": "2023-07-08T00:41:50Z", + "additional_information": "user_13" }, { - "id": "bpdpbvqa6mpook6f6kezzdbqkm", - "title": "Example Login Item 03", + "id": "4qe7s6hg6rbnetifh2khioyubi", + "title": "Example Login Item 29", "tags": ["tag_2"], "version": 1, "vault": { @@ -175,13 +175,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:56Z", - "updated_at": "2023-02-24T17:55:56Z", - "additional_information": "user_03" + "created_at": "2023-07-08T00:42:05Z", + "updated_at": "2023-07-08T00:42:05Z", + "additional_information": "user_29" }, { - "id": "sltbe3nfqdsyo6gfyslmzuzemi", - "title": "Example Login Item 21", + "id": "mlocnwqdjqmmpy2ot2djpy5bnu", + "title": "Example Login Item 45", "tags": ["tag_2"], "version": 1, "vault": { @@ -190,13 +190,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:14Z", - "updated_at": "2023-02-24T17:56:14Z", - "additional_information": "user_21" + "created_at": "2023-07-08T00:42:20Z", + "updated_at": "2023-07-08T00:42:20Z", + "additional_information": "user_45" }, { - "id": "epd4ou34sowqb6tejdqhw6fsri", - "title": "Example Login Item 09", + "id": "wxmirx357brwz4iiac7unsey54", + "title": "Example Login Item 15", "tags": ["tag_2"], "version": 1, "vault": { @@ -205,12 +205,12 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:02Z", - "updated_at": "2023-02-24T17:56:02Z", - "additional_information": "user_09" + "created_at": "2023-07-08T00:41:52Z", + "updated_at": "2023-07-08T00:41:52Z", + "additional_information": "user_15" }, { - "id": "vuohfuqvpi5sqbrebhhcdpadsa", + "id": "a2zljydknkdommoj7pm7sxdciu", "title": "Example Login Item 35", "tags": ["tag_2"], "version": 1, @@ -220,13 +220,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:27Z", - "updated_at": "2023-02-24T17:56:27Z", + "created_at": "2023-07-08T00:42:11Z", + "updated_at": "2023-07-08T00:42:11Z", "additional_information": "user_35" }, { - "id": "liadbfkaoetwbiu25ulkmbyb34", - "title": "Example Login Item 05", + "id": "xeite36sy64ubgy37pxkxikevi", + "title": "Example Login Item 47", "tags": ["tag_2"], "version": 1, "vault": { @@ -235,13 +235,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:58Z", - "updated_at": "2023-02-24T17:55:58Z", - "additional_information": "user_05" + "created_at": "2023-07-08T00:42:22Z", + "updated_at": "2023-07-08T00:42:22Z", + "additional_information": "user_47" }, { - "id": "usyl6cc2juicjmhu7kpeek7jmi", - "title": "Example Login Item 11", + "id": "ublx6ock536mgsglmyy24uqjwe", + "title": "Example Login Item 17", "tags": ["tag_2"], "version": 1, "vault": { @@ -250,13 +250,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:04Z", - "updated_at": "2023-02-24T17:56:04Z", - "additional_information": "user_11" + "created_at": "2023-07-08T00:41:54Z", + "updated_at": "2023-07-08T00:41:54Z", + "additional_information": "user_17" }, { - "id": "j6b77wlbwjskfub6nnidcfkeuy", - "title": "Example Login Item 23", + "id": "hqzy3h4k3k3ad7lzv4q64jd2ue", + "title": "Example Login Item 37", "tags": ["tag_2"], "version": 1, "vault": { @@ -265,13 +265,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:16Z", - "updated_at": "2023-02-24T17:56:16Z", - "additional_information": "user_23" + "created_at": "2023-07-08T00:42:13Z", + "updated_at": "2023-07-08T00:42:13Z", + "additional_information": "user_37" }, { - "id": "gpdv3i52wgzgem7ahm6bmf2mgi", - "title": "Example Login Item 37", + "id": "o37lfrsn4johum5znnhka6yyqe", + "title": "Example Login Item 33", "tags": ["tag_2"], "version": 1, "vault": { @@ -280,13 +280,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:29Z", - "updated_at": "2023-02-24T17:56:29Z", - "additional_information": "user_37" + "created_at": "2023-07-08T00:42:09Z", + "updated_at": "2023-07-08T00:42:09Z", + "additional_information": "user_33" }, { - "id": "e3xgioplb5fwwyhvw5cgx6p4h4", - "title": "Example Login Item 07", + "id": "bcee26kozqfxz2x3ud2mod3owy", + "title": "Example Login Item 19", "tags": ["tag_2"], "version": 1, "vault": { @@ -295,13 +295,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:00Z", - "updated_at": "2023-02-24T17:56:00Z", - "additional_information": "user_07" + "created_at": "2023-07-08T00:41:56Z", + "updated_at": "2023-07-08T00:41:56Z", + "additional_information": "user_19" }, { - "id": "5v6355kyw4odfoyazgfa5763za", - "title": "Example Login Item 13", + "id": "c7wc37dg4hqznao2tce4gopfii", + "title": "Example Login Item 49", "tags": ["tag_2"], "version": 1, "vault": { @@ -310,13 +310,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:06Z", - "updated_at": "2023-02-24T17:56:06Z", - "additional_information": "user_13" + "created_at": "2023-07-08T00:42:24Z", + "updated_at": "2023-07-08T00:42:24Z", + "additional_information": "user_49" }, { - "id": "3cutouoilmxk3jduqjgmhe7ete", - "title": "Example Login Item 25", + "id": "7rrcd5ctmofspsxwc5o5je6yha", + "title": "Example Login Item 21", "tags": ["tag_2"], "version": 1, "vault": { @@ -325,13 +325,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:18Z", - "updated_at": "2023-02-24T17:56:18Z", - "additional_information": "user_25" + "created_at": "2023-07-08T00:41:58Z", + "updated_at": "2023-07-08T00:41:58Z", + "additional_information": "user_21" }, { - "id": "d5sydookffvlkvgini5fuboykq", - "title": "Example Login Item 27", + "id": "2axi5b4g3sk4avnl326b4qd62u", + "title": "Example Login Item 51", "tags": ["tag_2"], "version": 1, "vault": { @@ -340,13 +340,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:20Z", - "updated_at": "2023-02-24T17:56:20Z", - "additional_information": "user_27" + "created_at": "2023-07-08T00:42:26Z", + "updated_at": "2023-07-08T00:42:26Z", + "additional_information": "user_51" }, { - "id": "fcliwcb2kaxvttvdyx2llubdby", - "title": "Example Login Item 39", + "id": "ea43m2fxsdxoqkfchnyjhf3mu4", + "title": "Example Login Item 03", "tags": ["tag_2"], "version": 1, "vault": { @@ -355,13 +355,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:31Z", - "updated_at": "2023-02-24T17:56:31Z", - "additional_information": "user_39" + "created_at": "2023-07-08T00:41:41Z", + "updated_at": "2023-07-08T00:41:41Z", + "additional_information": "user_03" }, { - "id": "txcqg27jb2mgs3ltt6hlchaulu", - "title": "Example Login Item 51", + "id": "gug2exuykefjqtltfae72nlax4", + "title": "Example Login Item 55", "tags": ["tag_2"], "version": 1, "vault": { @@ -370,13 +370,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:44Z", - "updated_at": "2023-02-24T17:56:44Z", - "additional_information": "user_51" + "created_at": "2023-07-08T00:42:29Z", + "updated_at": "2023-07-08T00:42:29Z", + "additional_information": "user_55" }, { - "id": "y22pqwjet5zuj7prax6lupmmye", - "title": "Example Login Item 57", + "id": "fgqounewhbgxzqvenxabtrn22e", + "title": "Example Login Item 53", "tags": ["tag_2"], "version": 1, "vault": { @@ -385,13 +385,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:50Z", - "updated_at": "2023-02-24T17:56:50Z", - "additional_information": "user_57" + "created_at": "2023-07-08T00:42:27Z", + "updated_at": "2023-07-08T00:42:27Z", + "additional_information": "user_53" }, { - "id": "czktqfjby75gddwbc5f42keutq", - "title": "Example Login Item 47", + "id": "polljyc4fzna3hka2itkaajpfm", + "title": "Example Login Item 57", "tags": ["tag_2"], "version": 1, "vault": { @@ -400,13 +400,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:40Z", - "updated_at": "2023-02-24T17:56:40Z", - "additional_information": "user_47" + "created_at": "2023-07-08T00:42:31Z", + "updated_at": "2023-07-08T00:42:31Z", + "additional_information": "user_57" }, { - "id": "wx56bupwvq3z7wufqzm3ongs4m", - "title": "Example Login Item 43", + "id": "auwrga7ebnmq4mgjyeq4mggkm4", + "title": "Example Login Item 01", "tags": ["tag_2"], "version": 1, "vault": { @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:35Z", - "updated_at": "2023-02-24T17:56:35Z", - "additional_information": "user_43" + "created_at": "2023-07-08T00:41:39Z", + "updated_at": "2023-07-08T00:41:39Z", + "additional_information": "user_01" }, { - "id": "gcquu2t47uk3p2547jm7gckxk4", - "title": "Example Login Item 41", + "id": "xym67w4f5bsdwifckdxj5dwjkm", + "title": "Example Login Item 23", "tags": ["tag_2"], "version": 1, "vault": { @@ -430,13 +430,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:33Z", - "updated_at": "2023-02-24T17:56:33Z", - "additional_information": "user_41" + "created_at": "2023-07-08T00:41:59Z", + "updated_at": "2023-07-08T00:41:59Z", + "additional_information": "user_23" }, { - "id": "zeowgzqfh65khenxy4iuurkh6e", - "title": "Example Login Item 49", + "id": "eqkfmddqsger2ka453jnovpnl4", + "title": "Example Login Item 39", "tags": ["tag_2"], "version": 1, "vault": { @@ -445,8 +445,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:42Z", - "updated_at": "2023-02-24T17:56:42Z", - "additional_information": "user_49" + "created_at": "2023-07-08T00:42:14Z", + "updated_at": "2023-07-08T00:42:14Z", + "additional_information": "user_39" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3/output b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3/output index c947e415..0a50a527 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-1/item-list-test-data-3/output @@ -1,8 +1,22 @@ [ { - "id": "bpdpbvqa6mpook6f6kezzdbqkm", + "id": "egx257uzqszyuytrffccrzts5m", "title": "Example Login Item 03", - "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:12Z", + "updated_at": "2023-07-08T00:40:12Z", + "additional_information": "Fri Jul 7 17:40:11 PDT 2023" + }, + { + "id": "gxe6mjviopczx4w4kf5jsmjnmq", + "title": "Example Login Item 08", + "tags": ["tag_1"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -10,13 +24,41 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:56Z", - "updated_at": "2023-02-24T17:55:56Z", - "additional_information": "user_03" + "created_at": "2023-07-08T00:41:46Z", + "updated_at": "2023-07-08T00:41:46Z", + "additional_information": "user_08" }, { - "id": "5jc5pyklfgkjxchuvp6ye5xcda", - "title": "Example Login Item 17", + "id": "qdtp7salm32bdrykzgx37e5rji", + "title": "Example Login Item 35", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:48Z", + "updated_at": "2023-07-08T00:40:48Z", + "additional_information": "Fri Jul 7 17:40:48 PDT 2023" + }, + { + "id": "ovrl4aamr33s4fvzfsqeoqrlha", + "title": "Example Login Item 36", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:50Z", + "updated_at": "2023-07-08T00:40:50Z", + "additional_information": "Fri Jul 7 17:40:49 PDT 2023" + }, + { + "id": "jkkako75gbr5bz32jln3vx7fie", + "title": "Example Login Item 59", "tags": ["tag_2"], "version": 1, "vault": { @@ -25,13 +67,41 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:10Z", - "updated_at": "2023-02-24T17:56:10Z", - "additional_information": "user_17" + "created_at": "2023-07-08T00:42:33Z", + "updated_at": "2023-07-08T00:42:33Z", + "additional_information": "user_59" }, { - "id": "jx2p4scgtcgunh2byphba4aqmi", - "title": "Example Login Item 01", + "id": "hdrcyvhdyx7mnkwjkx67knmzmy", + "title": "Example Login Item 04", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:13Z", + "updated_at": "2023-07-08T00:40:13Z", + "additional_information": "Fri Jul 7 17:40:12 PDT 2023" + }, + { + "id": "oezzsvvzc5czn5ywdipfliogym", + "title": "Example Login Item 37", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:51Z", + "updated_at": "2023-07-08T00:40:51Z", + "additional_information": "Fri Jul 7 17:40:50 PDT 2023" + }, + { + "id": "464gghlcyuzukmb6mvcibbqjqi", + "title": "Example Login Item 09", "tags": ["tag_2"], "version": 1, "vault": { @@ -40,13 +110,70 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:54Z", - "updated_at": "2023-02-24T17:55:54Z", - "additional_information": "user_01" + "created_at": "2023-07-08T00:41:47Z", + "updated_at": "2023-07-08T00:41:47Z", + "additional_information": "user_09" + }, + { + "id": "i74fqdn4yq6bgx7o5palpntu6q", + "title": "Example Login Item 38", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:52Z", + "updated_at": "2023-07-08T00:40:52Z", + "additional_information": "Fri Jul 7 17:40:51 PDT 2023" + }, + { + "id": "7dmhpxwgak62ob3grkupddvlqm", + "title": "Example Login Item 05", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:14Z", + "updated_at": "2023-07-08T00:40:14Z", + "additional_information": "Fri Jul 7 17:40:13 PDT 2023" }, { - "id": "fcliwcb2kaxvttvdyx2llubdby", + "id": "ni4vvin6zdkmgwwvq7maeywjya", + "title": "Example Login Item 10", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:47Z", + "updated_at": "2023-07-08T00:41:47Z", + "additional_information": "user_10" + }, + { + "id": "yt5gikpebpu5rnwqw6ll4hv5gi", "title": "Example Login Item 39", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:53Z", + "updated_at": "2023-07-08T00:40:53Z", + "additional_information": "Fri Jul 7 17:40:53 PDT 2023" + }, + { + "id": "igl2fbuhqlv4dg6qmpeuj5nfb4", + "title": "Example Login Item 11", "tags": ["tag_2"], "version": 1, "vault": { @@ -55,13 +182,98 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:31Z", - "updated_at": "2023-02-24T17:56:31Z", - "additional_information": "user_39" + "created_at": "2023-07-08T00:41:48Z", + "updated_at": "2023-07-08T00:41:48Z", + "additional_information": "user_11" }, { - "id": "eqxctjvoxupbqxcmoyrxxpahbi", - "title": "Example Login Item 59", + "id": "3x4sbtrvisd2ykpaxkvhzkr5ua", + "title": "Example Login Item 06", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:15Z", + "updated_at": "2023-07-08T00:40:15Z", + "additional_information": "Fri Jul 7 17:40:15 PDT 2023" + }, + { + "id": "5jrig2lfhyutqjgfifva4x5ghi", + "title": "Example Login Item 40", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:54Z", + "updated_at": "2023-07-08T00:40:54Z", + "additional_information": "Fri Jul 7 17:40:54 PDT 2023" + }, + { + "id": "nrvg3xsmg34yflfsphxehpw2lm", + "title": "Example Login Item 12", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:49Z", + "updated_at": "2023-07-08T00:41:49Z", + "additional_information": "user_12" + }, + { + "id": "fwayio5jymekyylod5yhirqv2u", + "title": "Example Login Item 41", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:55Z", + "updated_at": "2023-07-08T00:40:55Z", + "additional_information": "Fri Jul 7 17:40:55 PDT 2023" + }, + { + "id": "qvmeyoaueb7xjzup27x6bd365m", + "title": "Example Login Item 00", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:09Z", + "updated_at": "2023-07-08T00:40:09Z", + "additional_information": "Fri Jul 7 17:40:08 PDT 2023" + }, + { + "id": "z6obgfjblqb75grifhwjlcpjyq", + "title": "Example Login Item 07", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:16Z", + "updated_at": "2023-07-08T00:40:16Z", + "additional_information": "Fri Jul 7 17:40:16 PDT 2023" + }, + { + "id": "ajwks4dlm6n3d2mboq3eadeabm", + "title": "Example Login Item 13", "tags": ["tag_2"], "version": 1, "vault": { @@ -70,12 +282,213 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:53Z", - "updated_at": "2023-02-24T17:56:53Z", - "additional_information": "user_59" + "created_at": "2023-07-08T00:41:50Z", + "updated_at": "2023-07-08T00:41:50Z", + "additional_information": "user_13" + }, + { + "id": "xnggelzpai6dl4mtj2z5rzjm7y", + "title": "Example Login Item 42", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:57Z", + "updated_at": "2023-07-08T00:40:57Z", + "additional_information": "Fri Jul 7 17:40:56 PDT 2023" }, { - "id": "uaaxgohlltusrsyo5gnjkmpusq", + "id": "rbuemivgo2ih5e3dms2gijaotu", + "title": "Example Login Item 01", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:10Z", + "updated_at": "2023-07-08T00:40:10Z", + "additional_information": "Fri Jul 7 17:40:09 PDT 2023" + }, + { + "id": "ss3fv62w2zhlu26dx2upym5fgi", + "title": "Example Login Item 14", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:51Z", + "updated_at": "2023-07-08T00:41:51Z", + "additional_information": "user_14" + }, + { + "id": "5ywqsvskxl7ppxd5zriif2n64m", + "title": "Example Login Item 43", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:58Z", + "updated_at": "2023-07-08T00:40:58Z", + "additional_information": "Fri Jul 7 17:40:57 PDT 2023" + }, + { + "id": "ziszemmiihz7wrvaeaiyuqn2b4", + "title": "Example Login Item 08", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:17Z", + "updated_at": "2023-07-08T00:40:17Z", + "additional_information": "Fri Jul 7 17:40:17 PDT 2023" + }, + { + "id": "awtaih7kofxs4i3vyzljobavpu", + "title": "Example Login Item 02", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:10Z", + "updated_at": "2023-07-08T00:40:10Z", + "additional_information": "Fri Jul 7 17:40:10 PDT 2023" + }, + { + "id": "ren7aohec5rjl3dpybma3nth5a", + "title": "Example Login Item 44", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:59Z", + "updated_at": "2023-07-08T00:40:59Z", + "additional_information": "Fri Jul 7 17:40:59 PDT 2023" + }, + { + "id": "wxmirx357brwz4iiac7unsey54", + "title": "Example Login Item 15", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:52Z", + "updated_at": "2023-07-08T00:41:52Z", + "additional_information": "user_15" + }, + { + "id": "gb4wehmbza2fx2hs6qziksegfq", + "title": "Example Login Item 02", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:40Z", + "updated_at": "2023-07-08T00:41:40Z", + "additional_information": "user_02" + }, + { + "id": "rym5zxrmjqol4ywjmuvbgefxde", + "title": "Example Login Item 22", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:33Z", + "updated_at": "2023-07-08T00:40:33Z", + "additional_information": "Fri Jul 7 17:40:33 PDT 2023" + }, + { + "id": "afdklchofkygv624plb54yoj4u", + "title": "Example Login Item 21", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:32Z", + "updated_at": "2023-07-08T00:40:32Z", + "additional_information": "Fri Jul 7 17:40:32 PDT 2023" + }, + { + "id": "ea43m2fxsdxoqkfchnyjhf3mu4", + "title": "Example Login Item 03", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:41Z", + "updated_at": "2023-07-08T00:41:41Z", + "additional_information": "user_03" + }, + { + "id": "mguxk44wot6fy5p2ihg3nz6ngu", + "title": "Example Login Item 16", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:53Z", + "updated_at": "2023-07-08T00:41:53Z", + "additional_information": "user_16" + }, + { + "id": "mylacx6bumnwyee7nw7qjwlwfm", + "title": "Example Login Item 45", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:00Z", + "updated_at": "2023-07-08T00:41:00Z", + "additional_information": "Fri Jul 7 17:41:00 PDT 2023" + }, + { + "id": "ehfzlnwlbp4ou7qvir7qs6ukia", "title": "Example Login Item 04", "tags": ["tag_1"], "version": 1, @@ -85,12 +498,157 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:57Z", - "updated_at": "2023-02-24T17:55:57Z", + "created_at": "2023-07-08T00:41:42Z", + "updated_at": "2023-07-08T00:41:42Z", "additional_information": "user_04" }, { - "id": "wfqbcyivconjpmx5wb2vo6ggcy", + "id": "ublx6ock536mgsglmyy24uqjwe", + "title": "Example Login Item 17", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:54Z", + "updated_at": "2023-07-08T00:41:54Z", + "additional_information": "user_17" + }, + { + "id": "jxnrei56chdt27kdouhyxbytdy", + "title": "Example Login Item 23", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:35Z", + "updated_at": "2023-07-08T00:40:35Z", + "additional_information": "Fri Jul 7 17:40:34 PDT 2023" + }, + { + "id": "zs3oquihnjp2hu3x56pw6sibem", + "title": "Example Login Item 09", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:19Z", + "updated_at": "2023-07-08T00:40:19Z", + "additional_information": "Fri Jul 7 17:40:18 PDT 2023" + }, + { + "id": "3yj6x5jq3tb6wbol2q57bjqfzy", + "title": "Example Login Item 46", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:02Z", + "updated_at": "2023-07-08T00:41:02Z", + "additional_information": "Fri Jul 7 17:41:01 PDT 2023" + }, + { + "id": "3xup26ef7in6clllxq2lsa7f5a", + "title": "Example Login Item 38", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:42:14Z", + "updated_at": "2023-07-08T00:42:14Z", + "additional_information": "user_38" + }, + { + "id": "gxiweo5d3wmjl26yqwghjlwkca", + "title": "Example Login Item 05", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:43Z", + "updated_at": "2023-07-08T00:41:43Z", + "additional_information": "user_05" + }, + { + "id": "eqkfmddqsger2ka453jnovpnl4", + "title": "Example Login Item 39", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:42:14Z", + "updated_at": "2023-07-08T00:42:14Z", + "additional_information": "user_39" + }, + { + "id": "bz7trmpegmv5jfcy6ei4nqnod4", + "title": "Example Login Item 00", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:38Z", + "updated_at": "2023-07-08T00:41:38Z", + "additional_information": "user_00" + }, + { + "id": "ok66qcg63elbtmcgatg74oqwyq", + "title": "Example Login Item 24", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:36Z", + "updated_at": "2023-07-08T00:40:36Z", + "additional_information": "Fri Jul 7 17:40:35 PDT 2023" + }, + { + "id": "k2kr6li24g72i2ttru6izgw6iu", + "title": "Example Login Item 10", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:20Z", + "updated_at": "2023-07-08T00:40:20Z", + "additional_information": "Fri Jul 7 17:40:19 PDT 2023" + }, + { + "id": "nr6byqwvhxspadvbipyyyes4xu", "title": "Example Login Item 40", "tags": ["tag_1"], "version": 1, @@ -100,13 +658,116 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:32Z", - "updated_at": "2023-02-24T17:56:32Z", + "created_at": "2023-07-08T00:42:15Z", + "updated_at": "2023-07-08T00:42:15Z", "additional_information": "user_40" }, { - "id": "swugdbaij3e3gt72u45n5sptwq", - "title": "Example Login Item 00", + "id": "l45vzrepriim5zuj5skrsjrqm4", + "title": "Example Login Item 06", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:44Z", + "updated_at": "2023-07-08T00:41:44Z", + "additional_information": "user_06" + }, + { + "id": "auwrga7ebnmq4mgjyeq4mggkm4", + "title": "Example Login Item 01", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:39Z", + "updated_at": "2023-07-08T00:41:39Z", + "additional_information": "user_01" + }, + { + "id": "nmxtg62jsksz7bi67ev2qavaxy", + "title": "Example Login Item 18", + "tags": ["tag_1"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:55Z", + "updated_at": "2023-07-08T00:41:55Z", + "additional_information": "user_18" + }, + { + "id": "suol6frogf5e3mszgt3eu3a4by", + "title": "Example Login Item 41", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:42:16Z", + "updated_at": "2023-07-08T00:42:16Z", + "additional_information": "user_41" + }, + { + "id": "euwilsrjdmoc72oeq55mn26aua", + "title": "Example Login Item 07", + "tags": ["tag_2"], + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "LOGIN", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:41:45Z", + "updated_at": "2023-07-08T00:41:45Z", + "additional_information": "user_07" + }, + { + "id": "jz7jgewe6a7yj4kib2frmrr3iu", + "title": "Example Login Item 11", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:21Z", + "updated_at": "2023-07-08T00:40:21Z", + "additional_information": "Fri Jul 7 17:40:20 PDT 2023" + }, + { + "id": "s4rmjaxrhlzvw4usnmy5qubeyi", + "title": "Example Login Item 25", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:37Z", + "updated_at": "2023-07-08T00:40:37Z", + "additional_information": "Fri Jul 7 17:40:36 PDT 2023" + }, + { + "id": "v6myd3fyhr6nof4y2rflg6i57q", + "title": "Example Login Item 50", "tags": ["tag_1"], "version": 1, "vault": { @@ -115,14 +776,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:53Z", - "updated_at": "2023-02-24T17:55:53Z", - "additional_information": "user_00" + "created_at": "2023-07-08T00:42:25Z", + "updated_at": "2023-07-08T00:42:25Z", + "additional_information": "user_50" }, { - "id": "k25m7frtvexrgdlvel26qwvoo4", - "title": "Example Login Item 02", - "tags": ["tag_1"], + "id": "2axi5b4g3sk4avnl326b4qd62u", + "title": "Example Login Item 51", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -130,13 +791,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:55Z", - "updated_at": "2023-02-24T17:55:55Z", - "additional_information": "user_02" + "created_at": "2023-07-08T00:42:26Z", + "updated_at": "2023-07-08T00:42:26Z", + "additional_information": "user_51" }, { - "id": "liadbfkaoetwbiu25ulkmbyb34", - "title": "Example Login Item 05", + "id": "bcee26kozqfxz2x3ud2mod3owy", + "title": "Example Login Item 19", "tags": ["tag_2"], "version": 1, "vault": { @@ -145,13 +806,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:58Z", - "updated_at": "2023-02-24T17:55:58Z", - "additional_information": "user_05" + "created_at": "2023-07-08T00:41:56Z", + "updated_at": "2023-07-08T00:41:56Z", + "additional_information": "user_19" }, { - "id": "6w5rlrwwkmv3czhilhswtvq62q", - "title": "Example Login Item 38", + "id": "jknkoe5pufm5lv2erwgvy5r6wa", + "title": "Example Login Item 42", "tags": ["tag_1"], "version": 1, "vault": { @@ -160,28 +821,27 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:30Z", - "updated_at": "2023-02-24T17:56:30Z", - "additional_information": "user_38" + "created_at": "2023-07-08T00:42:17Z", + "updated_at": "2023-07-08T00:42:17Z", + "additional_information": "user_42" }, { - "id": "gcquu2t47uk3p2547jm7gckxk4", - "title": "Example Login Item 41", - "tags": ["tag_2"], + "id": "cmvnalgy4qgqmuwfdbczu5j2w4", + "title": "Example Login Item 12", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:33Z", - "updated_at": "2023-02-24T17:56:33Z", - "additional_information": "user_41" + "created_at": "2023-07-08T00:40:22Z", + "updated_at": "2023-07-08T00:40:22Z", + "additional_information": "Fri Jul 7 17:40:22 PDT 2023" }, { - "id": "t55uxoi37fy7bv4vlpq7kuuxty", - "title": "Example Login Item 06", + "id": "2h57i6mnc4er2fl3wmv6dqh5oq", + "title": "Example Login Item 52", "tags": ["tag_1"], "version": 1, "vault": { @@ -190,28 +850,27 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:59Z", - "updated_at": "2023-02-24T17:55:59Z", - "additional_information": "user_06" + "created_at": "2023-07-08T00:42:27Z", + "updated_at": "2023-07-08T00:42:27Z", + "additional_information": "user_52" }, { - "id": "usyl6cc2juicjmhu7kpeek7jmi", - "title": "Example Login Item 11", - "tags": ["tag_2"], + "id": "26vogk6mlyvarwfnqfcgbzhli4", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:04Z", - "updated_at": "2023-02-24T17:56:04Z", - "additional_information": "user_11" + "created_at": "2023-07-08T00:40:38Z", + "updated_at": "2023-07-08T00:40:38Z", + "additional_information": "Fri Jul 7 17:40:38 PDT 2023" }, { - "id": "d5sydookffvlkvgini5fuboykq", - "title": "Example Login Item 27", + "id": "xjfktjshz2y6qugc43o6v6llh4", + "title": "Example Login Item 43", "tags": ["tag_2"], "version": 1, "vault": { @@ -220,14 +879,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:20Z", - "updated_at": "2023-02-24T17:56:20Z", - "additional_information": "user_27" + "created_at": "2023-07-08T00:42:18Z", + "updated_at": "2023-07-08T00:42:18Z", + "additional_information": "user_43" }, { - "id": "44fcym7h3dk4ibetgw3cbg37aq", - "title": "Example Login Item 29", - "tags": ["tag_2"], + "id": "zultfskvawjpsiwyrmx3lsp3fa", + "title": "Example Login Item 20", + "tags": ["tag_1"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -235,14 +894,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:21Z", - "updated_at": "2023-02-24T17:56:21Z", - "additional_information": "user_29" + "created_at": "2023-07-08T00:41:57Z", + "updated_at": "2023-07-08T00:41:57Z", + "additional_information": "user_20" }, { - "id": "qaor4zvdl3ogtqlwl52dfdr7su", - "title": "Example Login Item 28", - "tags": ["tag_1"], + "id": "fgqounewhbgxzqvenxabtrn22e", + "title": "Example Login Item 53", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -250,28 +909,27 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:20Z", - "updated_at": "2023-02-24T17:56:20Z", - "additional_information": "user_28" + "created_at": "2023-07-08T00:42:27Z", + "updated_at": "2023-07-08T00:42:27Z", + "additional_information": "user_53" }, { - "id": "txcqg27jb2mgs3ltt6hlchaulu", - "title": "Example Login Item 51", - "tags": ["tag_2"], + "id": "p3uedo3ojfcswl2rnltlhy4rm4", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:44Z", - "updated_at": "2023-02-24T17:56:44Z", - "additional_information": "user_51" + "created_at": "2023-07-08T00:40:23Z", + "updated_at": "2023-07-08T00:40:23Z", + "additional_information": "Fri Jul 7 17:40:23 PDT 2023" }, { - "id": "m4ja2hv5jlbw4ibymnjkkwx5xm", - "title": "Example Login Item 50", + "id": "cdo4yda4y2jeplelfjcglcgbpe", + "title": "Example Login Item 44", "tags": ["tag_1"], "version": 1, "vault": { @@ -280,28 +938,27 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:43Z", - "updated_at": "2023-02-24T17:56:43Z", - "additional_information": "user_50" + "created_at": "2023-07-08T00:42:19Z", + "updated_at": "2023-07-08T00:42:19Z", + "additional_information": "user_44" }, { - "id": "tk2nncbqpiyzueumccbk3cxqo4", - "title": "Example Login Item 34", - "tags": ["tag_1"], + "id": "ekgqssuk22vjal6k4x3faqs32i", + "title": "Example Login Item 27", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:26Z", - "updated_at": "2023-02-24T17:56:26Z", - "additional_information": "user_34" + "created_at": "2023-07-08T00:40:39Z", + "updated_at": "2023-07-08T00:40:39Z", + "additional_information": "Fri Jul 7 17:40:39 PDT 2023" }, { - "id": "mhwrdj5pas3tapdesm3fm2vaea", - "title": "Example Login Item 12", + "id": "6u4vymvejjhiku36367ctb7vo4", + "title": "Example Login Item 54", "tags": ["tag_1"], "version": 1, "vault": { @@ -310,14 +967,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:05Z", - "updated_at": "2023-02-24T17:56:05Z", - "additional_information": "user_12" + "created_at": "2023-07-08T00:42:28Z", + "updated_at": "2023-07-08T00:42:28Z", + "additional_information": "user_54" }, { - "id": "w2fri7vllesxfwcc7ket5oafaa", - "title": "Example Login Item 18", - "tags": ["tag_1"], + "id": "7rrcd5ctmofspsxwc5o5je6yha", + "title": "Example Login Item 21", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -325,13 +982,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:11Z", - "updated_at": "2023-02-24T17:56:11Z", - "additional_information": "user_18" + "created_at": "2023-07-08T00:41:58Z", + "updated_at": "2023-07-08T00:41:58Z", + "additional_information": "user_21" }, { - "id": "vuohfuqvpi5sqbrebhhcdpadsa", - "title": "Example Login Item 35", + "id": "mlocnwqdjqmmpy2ot2djpy5bnu", + "title": "Example Login Item 45", "tags": ["tag_2"], "version": 1, "vault": { @@ -340,28 +997,27 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:27Z", - "updated_at": "2023-02-24T17:56:27Z", - "additional_information": "user_35" + "created_at": "2023-07-08T00:42:20Z", + "updated_at": "2023-07-08T00:42:20Z", + "additional_information": "user_45" }, { - "id": "5v6355kyw4odfoyazgfa5763za", - "title": "Example Login Item 13", - "tags": ["tag_2"], + "id": "drk3swentzknc4wilb3v6h2tvu", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:06Z", - "updated_at": "2023-02-24T17:56:06Z", - "additional_information": "user_13" + "created_at": "2023-07-08T00:40:24Z", + "updated_at": "2023-07-08T00:40:24Z", + "additional_information": "Fri Jul 7 17:40:24 PDT 2023" }, { - "id": "3srtzdqw5owgexrbwejievnlba", - "title": "Example Login Item 19", + "id": "gug2exuykefjqtltfae72nlax4", + "title": "Example Login Item 55", "tags": ["tag_2"], "version": 1, "vault": { @@ -370,28 +1026,27 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:12Z", - "updated_at": "2023-02-24T17:56:12Z", - "additional_information": "user_19" + "created_at": "2023-07-08T00:42:29Z", + "updated_at": "2023-07-08T00:42:29Z", + "additional_information": "user_55" }, { - "id": "uuaae5bgahf6noeeb5efwdligy", - "title": "Example Login Item 36", - "tags": ["tag_1"], + "id": "nxufacchbrsck5mlfdjvlcjnuq", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:28Z", - "updated_at": "2023-02-24T17:56:28Z", - "additional_information": "user_36" + "created_at": "2023-07-08T00:40:40Z", + "updated_at": "2023-07-08T00:40:40Z", + "additional_information": "Fri Jul 7 17:40:40 PDT 2023" }, { - "id": "jywp5hgephetphypkyffh774n4", - "title": "Example Login Item 20", + "id": "mpxkulphilhf5lkyjobpp37t24", + "title": "Example Login Item 46", "tags": ["tag_1"], "version": 1, "vault": { @@ -400,13 +1055,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:13Z", - "updated_at": "2023-02-24T17:56:13Z", - "additional_information": "user_20" + "created_at": "2023-07-08T00:42:21Z", + "updated_at": "2023-07-08T00:42:21Z", + "additional_information": "user_46" }, { - "id": "zynr2g4iu6gkartqxapeuyvw5m", - "title": "Example Login Item 14", + "id": "fhoes55rhovtblrtw36nd7to5a", + "title": "Example Login Item 22", "tags": ["tag_1"], "version": 1, "vault": { @@ -415,14 +1070,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:07Z", - "updated_at": "2023-02-24T17:56:07Z", - "additional_information": "user_14" + "created_at": "2023-07-08T00:41:59Z", + "updated_at": "2023-07-08T00:41:59Z", + "additional_information": "user_22" }, { - "id": "gpdv3i52wgzgem7ahm6bmf2mgi", - "title": "Example Login Item 37", - "tags": ["tag_2"], + "id": "tbnvtzwdonyt4d4g7pxxqsllzy", + "title": "Example Login Item 56", + "tags": ["tag_1"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -430,13 +1085,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:29Z", - "updated_at": "2023-02-24T17:56:29Z", - "additional_information": "user_37" + "created_at": "2023-07-08T00:42:30Z", + "updated_at": "2023-07-08T00:42:30Z", + "additional_information": "user_56" }, { - "id": "c7zymyca3aqab4zitzzod33dxi", - "title": "Example Login Item 08", + "id": "5kgdz3uievcxybxeuzedxkdcme", + "title": "Example Login Item 48", "tags": ["tag_1"], "version": 1, "vault": { @@ -445,13 +1100,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:01Z", - "updated_at": "2023-02-24T17:56:01Z", - "additional_information": "user_08" + "created_at": "2023-07-08T00:42:23Z", + "updated_at": "2023-07-08T00:42:23Z", + "additional_information": "user_48" }, { - "id": "sltbe3nfqdsyo6gfyslmzuzemi", - "title": "Example Login Item 21", + "id": "c7wc37dg4hqznao2tce4gopfii", + "title": "Example Login Item 49", "tags": ["tag_2"], "version": 1, "vault": { @@ -460,28 +1115,41 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:14Z", - "updated_at": "2023-02-24T17:56:14Z", - "additional_information": "user_21" + "created_at": "2023-07-08T00:42:24Z", + "updated_at": "2023-07-08T00:42:24Z", + "additional_information": "user_49" }, { - "id": "2m7ulegiyrhxkz4vhjcwxua6me", + "id": "vj6avyeejt6fqplwfsgjm7a3vq", "title": "Example Login Item 15", - "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:08Z", - "updated_at": "2023-02-24T17:56:08Z", - "additional_information": "user_15" + "created_at": "2023-07-08T00:40:26Z", + "updated_at": "2023-07-08T00:40:26Z", + "additional_information": "Fri Jul 7 17:40:25 PDT 2023" }, { - "id": "e3xgioplb5fwwyhvw5cgx6p4h4", - "title": "Example Login Item 07", + "id": "kge5tr2s7plxk6snwpztawzumq", + "title": "Example Login Item 29", + "version": 1, + "vault": { + "id": "ptpmg6qseanbhoesdooqniehhy", + "name": "Test Data 3" + }, + "category": "PASSWORD", + "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", + "created_at": "2023-07-08T00:40:42Z", + "updated_at": "2023-07-08T00:40:42Z", + "additional_information": "Fri Jul 7 17:40:41 PDT 2023" + }, + { + "id": "polljyc4fzna3hka2itkaajpfm", + "title": "Example Login Item 57", "tags": ["tag_2"], "version": 1, "vault": { @@ -490,14 +1158,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:00Z", - "updated_at": "2023-02-24T17:56:00Z", - "additional_information": "user_07" + "created_at": "2023-07-08T00:42:31Z", + "updated_at": "2023-07-08T00:42:31Z", + "additional_information": "user_57" }, { - "id": "tetw7r5ni5diskdlkwrjk7mbze", - "title": "Example Login Item 22", - "tags": ["tag_1"], + "id": "xeite36sy64ubgy37pxkxikevi", + "title": "Example Login Item 47", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -505,13 +1173,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:15Z", - "updated_at": "2023-02-24T17:56:15Z", - "additional_information": "user_22" + "created_at": "2023-07-08T00:42:22Z", + "updated_at": "2023-07-08T00:42:22Z", + "additional_information": "user_47" }, { - "id": "fxtwj6dy64gkpttwrkdmhe2qeu", - "title": "Example Login Item 31", + "id": "xym67w4f5bsdwifckdxj5dwjkm", + "title": "Example Login Item 23", "tags": ["tag_2"], "version": 1, "vault": { @@ -520,73 +1188,69 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:23Z", - "updated_at": "2023-02-24T17:56:23Z", - "additional_information": "user_31" + "created_at": "2023-07-08T00:41:59Z", + "updated_at": "2023-07-08T00:41:59Z", + "additional_information": "user_23" }, { - "id": "227wjxp7hwepl42abtj72mrzfu", - "title": "Example Login Item 16", - "tags": ["tag_1"], + "id": "2t6kclb5idv3wirt2bodzaxk5i", + "title": "Example Login Item 32", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:09Z", - "updated_at": "2023-02-24T17:56:09Z", - "additional_information": "user_16" + "created_at": "2023-07-08T00:40:45Z", + "updated_at": "2023-07-08T00:40:45Z", + "additional_information": "Fri Jul 7 17:40:44 PDT 2023" }, { - "id": "j6b77wlbwjskfub6nnidcfkeuy", - "title": "Example Login Item 23", - "tags": ["tag_2"], + "id": "rwfuncth7yl52yz5j7xm3h6hxa", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:16Z", - "updated_at": "2023-02-24T17:56:16Z", - "additional_information": "user_23" + "created_at": "2023-07-08T00:40:27Z", + "updated_at": "2023-07-08T00:40:27Z", + "additional_information": "Fri Jul 7 17:40:26 PDT 2023" }, { - "id": "ytnpda6ggiekr6rqhomcfjz4gm", - "title": "Example Login Item 30", - "tags": ["tag_1"], + "id": "2htjmiay46rpv5svypb2yqgq5y", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:22Z", - "updated_at": "2023-02-24T17:56:22Z", - "additional_information": "user_30" + "created_at": "2023-07-08T00:40:46Z", + "updated_at": "2023-07-08T00:40:46Z", + "additional_information": "Fri Jul 7 17:40:46 PDT 2023" }, { - "id": "3cutouoilmxk3jduqjgmhe7ete", - "title": "Example Login Item 25", - "tags": ["tag_2"], + "id": "gglasusy7z6a75lwlveb5u3yrq", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:18Z", - "updated_at": "2023-02-24T17:56:18Z", - "additional_information": "user_25" + "created_at": "2023-07-08T00:40:29Z", + "updated_at": "2023-07-08T00:40:29Z", + "additional_information": "Fri Jul 7 17:40:28 PDT 2023" }, { - "id": "63hg6bryj6roo3ompjjkrgclq4", - "title": "Example Login Item 26", + "id": "3k4dsem437daukn35nsmvaigp4", + "title": "Example Login Item 58", "tags": ["tag_1"], "version": 1, "vault": { @@ -595,27 +1259,26 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:19Z", - "updated_at": "2023-02-24T17:56:19Z", - "additional_information": "user_26" + "created_at": "2023-07-08T00:42:32Z", + "updated_at": "2023-07-08T00:42:32Z", + "additional_information": "user_58" }, { - "id": "epd4ou34sowqb6tejdqhw6fsri", - "title": "Example Login Item 09", - "tags": ["tag_2"], + "id": "kxerddgnuq75664otjvgi2c6ky", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:02Z", - "updated_at": "2023-02-24T17:56:02Z", - "additional_information": "user_09" + "created_at": "2023-07-08T00:40:43Z", + "updated_at": "2023-07-08T00:40:43Z", + "additional_information": "Fri Jul 7 17:40:42 PDT 2023" }, { - "id": "rz6aoaboubxnuyyg6a2lnvoamq", + "id": "sx457ikdbw45tg65ikd6beb6di", "title": "Example Login Item 24", "tags": ["tag_1"], "version": 1, @@ -625,59 +1288,56 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:17Z", - "updated_at": "2023-02-24T17:56:17Z", + "created_at": "2023-07-08T00:42:00Z", + "updated_at": "2023-07-08T00:42:00Z", "additional_information": "user_24" }, { - "id": "kjphrlaziyznxd5kyjjtb46bqi", - "title": "Example Login Item 32", - "tags": ["tag_1"], + "id": "ozzdhe75ff4mxglyltozgkkbtu", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:24Z", - "updated_at": "2023-02-24T17:56:24Z", - "additional_information": "user_32" + "created_at": "2023-07-08T00:40:28Z", + "updated_at": "2023-07-08T00:40:28Z", + "additional_information": "Fri Jul 7 17:40:27 PDT 2023" }, { - "id": "xf77ka63em7xpkkbfuuu4fihjq", - "title": "Example Login Item 55", - "tags": ["tag_2"], + "id": "k3eigerhrdjvg34okli7x7dtje", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:48Z", - "updated_at": "2023-02-24T17:56:48Z", - "additional_information": "user_55" + "created_at": "2023-07-08T00:40:31Z", + "updated_at": "2023-07-08T00:40:31Z", + "additional_information": "Fri Jul 7 17:40:31 PDT 2023" }, { - "id": "5qbtlgx3q4jedrxvvnjljvpm44", - "title": "Example Login Item 33", - "tags": ["tag_2"], + "id": "6k53xgsj5fmkreejedd5vlfwsi", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:25Z", - "updated_at": "2023-02-24T17:56:25Z", - "additional_information": "user_33" + "created_at": "2023-07-08T00:40:44Z", + "updated_at": "2023-07-08T00:40:44Z", + "additional_information": "Fri Jul 7 17:40:43 PDT 2023" }, { - "id": "rnrvtzfyrwxa4375ebkzugw3vm", - "title": "Example Login Item 10", - "tags": ["tag_1"], + "id": "uydqmqfe3kwt4a5lrwrdizoo2a", + "title": "Example Login Item 31", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -685,43 +1345,41 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:03Z", - "updated_at": "2023-02-24T17:56:03Z", - "additional_information": "user_10" + "created_at": "2023-07-08T00:42:07Z", + "updated_at": "2023-07-08T00:42:07Z", + "additional_information": "user_31" }, { - "id": "3b5lgd42msjwl4ysvli52bm7ry", - "title": "Example Login Item 53", - "tags": ["tag_2"], + "id": "h5i6pdoclhp43vbwold6phhnga", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:46Z", - "updated_at": "2023-02-24T17:56:46Z", - "additional_information": "user_53" + "created_at": "2023-07-08T00:40:30Z", + "updated_at": "2023-07-08T00:40:30Z", + "additional_information": "Fri Jul 7 17:40:30 PDT 2023" }, { - "id": "7dqfjazacjwvbbo7cxvmhj7f5m", - "title": "Example Login Item 45", - "tags": ["tag_2"], + "id": "tjh6n6czsn3lh2ei4xzpt3bdoi", + "title": "Example Login Item 34", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", "name": "Test Data 3" }, - "category": "LOGIN", + "category": "PASSWORD", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:37Z", - "updated_at": "2023-02-24T17:56:37Z", - "additional_information": "user_45" + "created_at": "2023-07-08T00:40:47Z", + "updated_at": "2023-07-08T00:40:47Z", + "additional_information": "Fri Jul 7 17:40:47 PDT 2023" }, { - "id": "fdfchkseihjonakoi7hwdyxpsm", - "title": "Example Login Item 54", + "id": "36fpoffepi2s5642f7lxpfv7ai", + "title": "Example Login Item 36", "tags": ["tag_1"], "version": 1, "vault": { @@ -730,14 +1388,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:47Z", - "updated_at": "2023-02-24T17:56:47Z", - "additional_information": "user_54" + "created_at": "2023-07-08T00:42:12Z", + "updated_at": "2023-07-08T00:42:12Z", + "additional_information": "user_36" }, { - "id": "qhxuds7r6nyyjife435636qxrm", - "title": "Example Login Item 42", - "tags": ["tag_1"], + "id": "a2zljydknkdommoj7pm7sxdciu", + "title": "Example Login Item 35", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -745,13 +1403,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:34Z", - "updated_at": "2023-02-24T17:56:34Z", - "additional_information": "user_42" + "created_at": "2023-07-08T00:42:11Z", + "updated_at": "2023-07-08T00:42:11Z", + "additional_information": "user_35" }, { - "id": "3b22ugscmcg44ewj2pjb42y7qm", - "title": "Example Login Item 52", + "id": "cvnea5iv2xboxoouqwmyokvoyq", + "title": "Example Login Item 32", "tags": ["tag_1"], "version": 1, "vault": { @@ -760,14 +1418,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:45Z", - "updated_at": "2023-02-24T17:56:45Z", - "additional_information": "user_52" + "created_at": "2023-07-08T00:42:08Z", + "updated_at": "2023-07-08T00:42:08Z", + "additional_information": "user_32" }, { - "id": "g3hsebriiketnduxt6ziuxd23u", - "title": "Example Login Item 46", - "tags": ["tag_1"], + "id": "xtaesbnq5quulprnggw3rbifqm", + "title": "Example Login Item 25", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -775,13 +1433,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:38Z", - "updated_at": "2023-02-24T17:56:38Z", - "additional_information": "user_46" + "created_at": "2023-07-08T00:42:01Z", + "updated_at": "2023-07-08T00:42:01Z", + "additional_information": "user_25" }, { - "id": "czktqfjby75gddwbc5f42keutq", - "title": "Example Login Item 47", + "id": "o37lfrsn4johum5znnhka6yyqe", + "title": "Example Login Item 33", "tags": ["tag_2"], "version": 1, "vault": { @@ -790,14 +1448,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:40Z", - "updated_at": "2023-02-24T17:56:40Z", - "additional_information": "user_47" + "created_at": "2023-07-08T00:42:09Z", + "updated_at": "2023-07-08T00:42:09Z", + "additional_information": "user_33" }, { - "id": "zeowgzqfh65khenxy4iuurkh6e", - "title": "Example Login Item 49", - "tags": ["tag_2"], + "id": "w6vmwhxirabpl3hcjdnzby37wy", + "title": "Example Login Item 34", + "tags": ["tag_1"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -805,14 +1463,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:42Z", - "updated_at": "2023-02-24T17:56:42Z", - "additional_information": "user_49" + "created_at": "2023-07-08T00:42:10Z", + "updated_at": "2023-07-08T00:42:10Z", + "additional_information": "user_34" }, { - "id": "synhmwpq5j5uouptpggnwws5im", - "title": "Example Login Item 48", - "tags": ["tag_1"], + "id": "4qe7s6hg6rbnetifh2khioyubi", + "title": "Example Login Item 29", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -820,14 +1478,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:41Z", - "updated_at": "2023-02-24T17:56:41Z", - "additional_information": "user_48" + "created_at": "2023-07-08T00:42:05Z", + "updated_at": "2023-07-08T00:42:05Z", + "additional_information": "user_29" }, { - "id": "wx56bupwvq3z7wufqzm3ongs4m", - "title": "Example Login Item 43", - "tags": ["tag_2"], + "id": "cwc33lay6hfiq7n7txzla3wvgy", + "title": "Example Login Item 28", + "tags": ["tag_1"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -835,13 +1493,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:35Z", - "updated_at": "2023-02-24T17:56:35Z", - "additional_information": "user_43" + "created_at": "2023-07-08T00:42:04Z", + "updated_at": "2023-07-08T00:42:04Z", + "additional_information": "user_28" }, { - "id": "y22pqwjet5zuj7prax6lupmmye", - "title": "Example Login Item 57", + "id": "hqzy3h4k3k3ad7lzv4q64jd2ue", + "title": "Example Login Item 37", "tags": ["tag_2"], "version": 1, "vault": { @@ -850,13 +1508,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:50Z", - "updated_at": "2023-02-24T17:56:50Z", - "additional_information": "user_57" + "created_at": "2023-07-08T00:42:13Z", + "updated_at": "2023-07-08T00:42:13Z", + "additional_information": "user_37" }, { - "id": "vwow3kdi4mmxgktscpou6zmbki", - "title": "Example Login Item 44", + "id": "7h6f4ner6zgooau4tdvbongx2q", + "title": "Example Login Item 26", "tags": ["tag_1"], "version": 1, "vault": { @@ -865,14 +1523,14 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:36Z", - "updated_at": "2023-02-24T17:56:36Z", - "additional_information": "user_44" + "created_at": "2023-07-08T00:42:02Z", + "updated_at": "2023-07-08T00:42:02Z", + "additional_information": "user_26" }, { - "id": "l23yjgp2oqblp6ocqwqnr4gi7q", - "title": "Example Login Item 58", - "tags": ["tag_1"], + "id": "ghse4pcxazja4kaiblm6esidc4", + "title": "Example Login Item 27", + "tags": ["tag_2"], "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -880,13 +1538,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:52Z", - "updated_at": "2023-02-24T17:56:52Z", - "additional_information": "user_58" + "created_at": "2023-07-08T00:42:03Z", + "updated_at": "2023-07-08T00:42:03Z", + "additional_information": "user_27" }, { - "id": "uwbejwcjz34y6qfblywunaj5ea", - "title": "Example Login Item 56", + "id": "bj54ajctjinadjknqaqg4gj4me", + "title": "Example Login Item 30", "tags": ["tag_1"], "version": 1, "vault": { @@ -895,8 +1553,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:49Z", - "updated_at": "2023-02-24T17:56:49Z", - "additional_information": "user_56" + "created_at": "2023-07-08T00:42:06Z", + "updated_at": "2023-07-08T00:42:06Z", + "additional_information": "user_30" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-2/cli-version/output b/tests/config/mock-op/responses-item-delete-multiple/responses-2/cli-version/output index fd7d1759..ef0f38ab 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-2/cli-version/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-2/cli-version/output @@ -1 +1 @@ -2.15.0-beta.03 +2.19.0 diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3-tag-2/output b/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3-tag-2/output index 50494a8c..5a6d57fc 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3-tag-2/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3-tag-2/output @@ -1,7 +1,7 @@ [ { - "id": "d5sydookffvlkvgini5fuboykq", - "title": "Example Login Item 27", + "id": "jkkako75gbr5bz32jln3vx7fie", + "title": "Example Login Item 59", "tags": ["tag_2"], "version": 1, "vault": { @@ -10,13 +10,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:20Z", - "updated_at": "2023-02-24T17:56:20Z", - "additional_information": "user_27" + "created_at": "2023-07-08T00:42:33Z", + "updated_at": "2023-07-08T00:42:33Z", + "additional_information": "user_59" }, { - "id": "eqxctjvoxupbqxcmoyrxxpahbi", - "title": "Example Login Item 59", + "id": "4qe7s6hg6rbnetifh2khioyubi", + "title": "Example Login Item 29", "tags": ["tag_2"], "version": 1, "vault": { @@ -25,13 +25,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:53Z", - "updated_at": "2023-02-24T17:56:53Z", - "additional_information": "user_59" + "created_at": "2023-07-08T00:42:05Z", + "updated_at": "2023-07-08T00:42:05Z", + "additional_information": "user_29" }, { - "id": "5v6355kyw4odfoyazgfa5763za", - "title": "Example Login Item 13", + "id": "ghse4pcxazja4kaiblm6esidc4", + "title": "Example Login Item 27", "tags": ["tag_2"], "version": 1, "vault": { @@ -40,13 +40,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:06Z", - "updated_at": "2023-02-24T17:56:06Z", - "additional_information": "user_13" + "created_at": "2023-07-08T00:42:03Z", + "updated_at": "2023-07-08T00:42:03Z", + "additional_information": "user_27" }, { - "id": "44fcym7h3dk4ibetgw3cbg37aq", - "title": "Example Login Item 29", + "id": "uydqmqfe3kwt4a5lrwrdizoo2a", + "title": "Example Login Item 31", "tags": ["tag_2"], "version": 1, "vault": { @@ -55,13 +55,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:21Z", - "updated_at": "2023-02-24T17:56:21Z", - "additional_information": "user_29" + "created_at": "2023-07-08T00:42:07Z", + "updated_at": "2023-07-08T00:42:07Z", + "additional_information": "user_31" }, { - "id": "jx2p4scgtcgunh2byphba4aqmi", - "title": "Example Login Item 01", + "id": "o37lfrsn4johum5znnhka6yyqe", + "title": "Example Login Item 33", "tags": ["tag_2"], "version": 1, "vault": { @@ -70,13 +70,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:54Z", - "updated_at": "2023-02-24T17:55:54Z", - "additional_information": "user_01" + "created_at": "2023-07-08T00:42:09Z", + "updated_at": "2023-07-08T00:42:09Z", + "additional_information": "user_33" }, { - "id": "3b5lgd42msjwl4ysvli52bm7ry", - "title": "Example Login Item 53", + "id": "a2zljydknkdommoj7pm7sxdciu", + "title": "Example Login Item 35", "tags": ["tag_2"], "version": 1, "vault": { @@ -85,13 +85,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:46Z", - "updated_at": "2023-02-24T17:56:46Z", - "additional_information": "user_53" + "created_at": "2023-07-08T00:42:11Z", + "updated_at": "2023-07-08T00:42:11Z", + "additional_information": "user_35" }, { - "id": "2m7ulegiyrhxkz4vhjcwxua6me", - "title": "Example Login Item 15", + "id": "hqzy3h4k3k3ad7lzv4q64jd2ue", + "title": "Example Login Item 37", "tags": ["tag_2"], "version": 1, "vault": { @@ -100,13 +100,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:08Z", - "updated_at": "2023-02-24T17:56:08Z", - "additional_information": "user_15" + "created_at": "2023-07-08T00:42:13Z", + "updated_at": "2023-07-08T00:42:13Z", + "additional_information": "user_37" }, { - "id": "bpdpbvqa6mpook6f6kezzdbqkm", - "title": "Example Login Item 03", + "id": "auwrga7ebnmq4mgjyeq4mggkm4", + "title": "Example Login Item 01", "tags": ["tag_2"], "version": 1, "vault": { @@ -115,13 +115,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:56Z", - "updated_at": "2023-02-24T17:55:56Z", - "additional_information": "user_03" + "created_at": "2023-07-08T00:41:39Z", + "updated_at": "2023-07-08T00:41:39Z", + "additional_information": "user_01" }, { - "id": "xf77ka63em7xpkkbfuuu4fihjq", - "title": "Example Login Item 55", + "id": "eqkfmddqsger2ka453jnovpnl4", + "title": "Example Login Item 39", "tags": ["tag_2"], "version": 1, "vault": { @@ -130,13 +130,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:48Z", - "updated_at": "2023-02-24T17:56:48Z", - "additional_information": "user_55" + "created_at": "2023-07-08T00:42:14Z", + "updated_at": "2023-07-08T00:42:14Z", + "additional_information": "user_39" }, { - "id": "3srtzdqw5owgexrbwejievnlba", - "title": "Example Login Item 19", + "id": "suol6frogf5e3mszgt3eu3a4by", + "title": "Example Login Item 41", "tags": ["tag_2"], "version": 1, "vault": { @@ -145,13 +145,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:12Z", - "updated_at": "2023-02-24T17:56:12Z", - "additional_information": "user_19" + "created_at": "2023-07-08T00:42:16Z", + "updated_at": "2023-07-08T00:42:16Z", + "additional_information": "user_41" }, { - "id": "sltbe3nfqdsyo6gfyslmzuzemi", - "title": "Example Login Item 21", + "id": "ea43m2fxsdxoqkfchnyjhf3mu4", + "title": "Example Login Item 03", "tags": ["tag_2"], "version": 1, "vault": { @@ -160,13 +160,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:14Z", - "updated_at": "2023-02-24T17:56:14Z", - "additional_information": "user_21" + "created_at": "2023-07-08T00:41:41Z", + "updated_at": "2023-07-08T00:41:41Z", + "additional_information": "user_03" }, { - "id": "5jc5pyklfgkjxchuvp6ye5xcda", - "title": "Example Login Item 17", + "id": "xjfktjshz2y6qugc43o6v6llh4", + "title": "Example Login Item 43", "tags": ["tag_2"], "version": 1, "vault": { @@ -175,13 +175,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:10Z", - "updated_at": "2023-02-24T17:56:10Z", - "additional_information": "user_17" + "created_at": "2023-07-08T00:42:18Z", + "updated_at": "2023-07-08T00:42:18Z", + "additional_information": "user_43" }, { - "id": "liadbfkaoetwbiu25ulkmbyb34", - "title": "Example Login Item 05", + "id": "wxmirx357brwz4iiac7unsey54", + "title": "Example Login Item 15", "tags": ["tag_2"], "version": 1, "vault": { @@ -190,13 +190,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:58Z", - "updated_at": "2023-02-24T17:55:58Z", - "additional_information": "user_05" + "created_at": "2023-07-08T00:41:52Z", + "updated_at": "2023-07-08T00:41:52Z", + "additional_information": "user_15" }, { - "id": "czktqfjby75gddwbc5f42keutq", - "title": "Example Login Item 47", + "id": "mlocnwqdjqmmpy2ot2djpy5bnu", + "title": "Example Login Item 45", "tags": ["tag_2"], "version": 1, "vault": { @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:40Z", - "updated_at": "2023-02-24T17:56:40Z", - "additional_information": "user_47" + "created_at": "2023-07-08T00:42:20Z", + "updated_at": "2023-07-08T00:42:20Z", + "additional_information": "user_45" }, { - "id": "j6b77wlbwjskfub6nnidcfkeuy", - "title": "Example Login Item 23", + "id": "ublx6ock536mgsglmyy24uqjwe", + "title": "Example Login Item 17", "tags": ["tag_2"], "version": 1, "vault": { @@ -220,13 +220,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:16Z", - "updated_at": "2023-02-24T17:56:16Z", - "additional_information": "user_23" + "created_at": "2023-07-08T00:41:54Z", + "updated_at": "2023-07-08T00:41:54Z", + "additional_information": "user_17" }, { - "id": "3cutouoilmxk3jduqjgmhe7ete", - "title": "Example Login Item 25", + "id": "xeite36sy64ubgy37pxkxikevi", + "title": "Example Login Item 47", "tags": ["tag_2"], "version": 1, "vault": { @@ -235,12 +235,12 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:18Z", - "updated_at": "2023-02-24T17:56:18Z", - "additional_information": "user_25" + "created_at": "2023-07-08T00:42:22Z", + "updated_at": "2023-07-08T00:42:22Z", + "additional_information": "user_47" }, { - "id": "zeowgzqfh65khenxy4iuurkh6e", + "id": "c7wc37dg4hqznao2tce4gopfii", "title": "Example Login Item 49", "tags": ["tag_2"], "version": 1, @@ -250,13 +250,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:42Z", - "updated_at": "2023-02-24T17:56:42Z", + "created_at": "2023-07-08T00:42:24Z", + "updated_at": "2023-07-08T00:42:24Z", "additional_information": "user_49" }, { - "id": "e3xgioplb5fwwyhvw5cgx6p4h4", - "title": "Example Login Item 07", + "id": "bcee26kozqfxz2x3ud2mod3owy", + "title": "Example Login Item 19", "tags": ["tag_2"], "version": 1, "vault": { @@ -265,13 +265,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:00Z", - "updated_at": "2023-02-24T17:56:00Z", - "additional_information": "user_07" + "created_at": "2023-07-08T00:41:56Z", + "updated_at": "2023-07-08T00:41:56Z", + "additional_information": "user_19" }, { - "id": "7dqfjazacjwvbbo7cxvmhj7f5m", - "title": "Example Login Item 45", + "id": "2axi5b4g3sk4avnl326b4qd62u", + "title": "Example Login Item 51", "tags": ["tag_2"], "version": 1, "vault": { @@ -280,13 +280,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:37Z", - "updated_at": "2023-02-24T17:56:37Z", - "additional_information": "user_45" + "created_at": "2023-07-08T00:42:26Z", + "updated_at": "2023-07-08T00:42:26Z", + "additional_information": "user_51" }, { - "id": "epd4ou34sowqb6tejdqhw6fsri", - "title": "Example Login Item 09", + "id": "fgqounewhbgxzqvenxabtrn22e", + "title": "Example Login Item 53", "tags": ["tag_2"], "version": 1, "vault": { @@ -295,13 +295,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:02Z", - "updated_at": "2023-02-24T17:56:02Z", - "additional_information": "user_09" + "created_at": "2023-07-08T00:42:27Z", + "updated_at": "2023-07-08T00:42:27Z", + "additional_information": "user_53" }, { - "id": "usyl6cc2juicjmhu7kpeek7jmi", - "title": "Example Login Item 11", + "id": "7rrcd5ctmofspsxwc5o5je6yha", + "title": "Example Login Item 21", "tags": ["tag_2"], "version": 1, "vault": { @@ -310,13 +310,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:04Z", - "updated_at": "2023-02-24T17:56:04Z", - "additional_information": "user_11" + "created_at": "2023-07-08T00:41:58Z", + "updated_at": "2023-07-08T00:41:58Z", + "additional_information": "user_21" }, { - "id": "vuohfuqvpi5sqbrebhhcdpadsa", - "title": "Example Login Item 35", + "id": "gug2exuykefjqtltfae72nlax4", + "title": "Example Login Item 55", "tags": ["tag_2"], "version": 1, "vault": { @@ -325,13 +325,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:27Z", - "updated_at": "2023-02-24T17:56:27Z", - "additional_information": "user_35" + "created_at": "2023-07-08T00:42:29Z", + "updated_at": "2023-07-08T00:42:29Z", + "additional_information": "user_55" }, { - "id": "fxtwj6dy64gkpttwrkdmhe2qeu", - "title": "Example Login Item 31", + "id": "polljyc4fzna3hka2itkaajpfm", + "title": "Example Login Item 57", "tags": ["tag_2"], "version": 1, "vault": { @@ -340,13 +340,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:23Z", - "updated_at": "2023-02-24T17:56:23Z", - "additional_information": "user_31" + "created_at": "2023-07-08T00:42:31Z", + "updated_at": "2023-07-08T00:42:31Z", + "additional_information": "user_57" }, { - "id": "fcliwcb2kaxvttvdyx2llubdby", - "title": "Example Login Item 39", + "id": "xym67w4f5bsdwifckdxj5dwjkm", + "title": "Example Login Item 23", "tags": ["tag_2"], "version": 1, "vault": { @@ -355,13 +355,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:31Z", - "updated_at": "2023-02-24T17:56:31Z", - "additional_information": "user_39" + "created_at": "2023-07-08T00:41:59Z", + "updated_at": "2023-07-08T00:41:59Z", + "additional_information": "user_23" }, { - "id": "wx56bupwvq3z7wufqzm3ongs4m", - "title": "Example Login Item 43", + "id": "xtaesbnq5quulprnggw3rbifqm", + "title": "Example Login Item 25", "tags": ["tag_2"], "version": 1, "vault": { @@ -370,13 +370,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:35Z", - "updated_at": "2023-02-24T17:56:35Z", - "additional_information": "user_43" + "created_at": "2023-07-08T00:42:01Z", + "updated_at": "2023-07-08T00:42:01Z", + "additional_information": "user_25" }, { - "id": "5qbtlgx3q4jedrxvvnjljvpm44", - "title": "Example Login Item 33", + "id": "igl2fbuhqlv4dg6qmpeuj5nfb4", + "title": "Example Login Item 11", "tags": ["tag_2"], "version": 1, "vault": { @@ -385,13 +385,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:25Z", - "updated_at": "2023-02-24T17:56:25Z", - "additional_information": "user_33" + "created_at": "2023-07-08T00:41:48Z", + "updated_at": "2023-07-08T00:41:48Z", + "additional_information": "user_11" }, { - "id": "txcqg27jb2mgs3ltt6hlchaulu", - "title": "Example Login Item 51", + "id": "euwilsrjdmoc72oeq55mn26aua", + "title": "Example Login Item 07", "tags": ["tag_2"], "version": 1, "vault": { @@ -400,13 +400,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:44Z", - "updated_at": "2023-02-24T17:56:44Z", - "additional_information": "user_51" + "created_at": "2023-07-08T00:41:45Z", + "updated_at": "2023-07-08T00:41:45Z", + "additional_information": "user_07" }, { - "id": "gcquu2t47uk3p2547jm7gckxk4", - "title": "Example Login Item 41", + "id": "gxiweo5d3wmjl26yqwghjlwkca", + "title": "Example Login Item 05", "tags": ["tag_2"], "version": 1, "vault": { @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:33Z", - "updated_at": "2023-02-24T17:56:33Z", - "additional_information": "user_41" + "created_at": "2023-07-08T00:41:43Z", + "updated_at": "2023-07-08T00:41:43Z", + "additional_information": "user_05" }, { - "id": "gpdv3i52wgzgem7ahm6bmf2mgi", - "title": "Example Login Item 37", + "id": "464gghlcyuzukmb6mvcibbqjqi", + "title": "Example Login Item 09", "tags": ["tag_2"], "version": 1, "vault": { @@ -430,13 +430,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:29Z", - "updated_at": "2023-02-24T17:56:29Z", - "additional_information": "user_37" + "created_at": "2023-07-08T00:41:47Z", + "updated_at": "2023-07-08T00:41:47Z", + "additional_information": "user_09" }, { - "id": "y22pqwjet5zuj7prax6lupmmye", - "title": "Example Login Item 57", + "id": "ajwks4dlm6n3d2mboq3eadeabm", + "title": "Example Login Item 13", "tags": ["tag_2"], "version": 1, "vault": { @@ -445,8 +445,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:50Z", - "updated_at": "2023-02-24T17:56:50Z", - "additional_information": "user_57" + "created_at": "2023-07-08T00:41:50Z", + "updated_at": "2023-07-08T00:41:50Z", + "additional_information": "user_13" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3/output b/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3/output index 556d8650..079cb43a 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-2/item-list-test-data-3/output @@ -1,7 +1,7 @@ [ { - "id": "7dqfjazacjwvbbo7cxvmhj7f5m", - "title": "Example Login Item 45", + "id": "jkkako75gbr5bz32jln3vx7fie", + "title": "Example Login Item 59", "tags": ["tag_2"], "version": 1, "vault": { @@ -10,13 +10,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:37Z", - "updated_at": "2023-02-24T17:56:37Z", - "additional_information": "user_45" + "created_at": "2023-07-08T00:42:33Z", + "updated_at": "2023-07-08T00:42:33Z", + "additional_information": "user_59" }, { - "id": "eqxctjvoxupbqxcmoyrxxpahbi", - "title": "Example Login Item 59", + "id": "igl2fbuhqlv4dg6qmpeuj5nfb4", + "title": "Example Login Item 11", "tags": ["tag_2"], "version": 1, "vault": { @@ -25,13 +25,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:53Z", - "updated_at": "2023-02-24T17:56:53Z", - "additional_information": "user_59" + "created_at": "2023-07-08T00:41:48Z", + "updated_at": "2023-07-08T00:41:48Z", + "additional_information": "user_11" }, { - "id": "44fcym7h3dk4ibetgw3cbg37aq", - "title": "Example Login Item 29", + "id": "ajwks4dlm6n3d2mboq3eadeabm", + "title": "Example Login Item 13", "tags": ["tag_2"], "version": 1, "vault": { @@ -40,13 +40,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:21Z", - "updated_at": "2023-02-24T17:56:21Z", - "additional_information": "user_29" + "created_at": "2023-07-08T00:41:50Z", + "updated_at": "2023-07-08T00:41:50Z", + "additional_information": "user_13" }, { - "id": "2m7ulegiyrhxkz4vhjcwxua6me", - "title": "Example Login Item 15", + "id": "hqzy3h4k3k3ad7lzv4q64jd2ue", + "title": "Example Login Item 37", "tags": ["tag_2"], "version": 1, "vault": { @@ -55,13 +55,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:08Z", - "updated_at": "2023-02-24T17:56:08Z", - "additional_information": "user_15" + "created_at": "2023-07-08T00:42:13Z", + "updated_at": "2023-07-08T00:42:13Z", + "additional_information": "user_37" }, { - "id": "czktqfjby75gddwbc5f42keutq", - "title": "Example Login Item 47", + "id": "wxmirx357brwz4iiac7unsey54", + "title": "Example Login Item 15", "tags": ["tag_2"], "version": 1, "vault": { @@ -70,12 +70,12 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:40Z", - "updated_at": "2023-02-24T17:56:40Z", - "additional_information": "user_47" + "created_at": "2023-07-08T00:41:52Z", + "updated_at": "2023-07-08T00:41:52Z", + "additional_information": "user_15" }, { - "id": "5jc5pyklfgkjxchuvp6ye5xcda", + "id": "ublx6ock536mgsglmyy24uqjwe", "title": "Example Login Item 17", "tags": ["tag_2"], "version": 1, @@ -85,12 +85,12 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:10Z", - "updated_at": "2023-02-24T17:56:10Z", + "created_at": "2023-07-08T00:41:54Z", + "updated_at": "2023-07-08T00:41:54Z", "additional_information": "user_17" }, { - "id": "zeowgzqfh65khenxy4iuurkh6e", + "id": "c7wc37dg4hqznao2tce4gopfii", "title": "Example Login Item 49", "tags": ["tag_2"], "version": 1, @@ -100,13 +100,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:42Z", - "updated_at": "2023-02-24T17:56:42Z", + "created_at": "2023-07-08T00:42:24Z", + "updated_at": "2023-07-08T00:42:24Z", "additional_information": "user_49" }, { - "id": "wx56bupwvq3z7wufqzm3ongs4m", - "title": "Example Login Item 43", + "id": "7rrcd5ctmofspsxwc5o5je6yha", + "title": "Example Login Item 21", "tags": ["tag_2"], "version": 1, "vault": { @@ -115,13 +115,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:35Z", - "updated_at": "2023-02-24T17:56:35Z", - "additional_information": "user_43" + "created_at": "2023-07-08T00:41:58Z", + "updated_at": "2023-07-08T00:41:58Z", + "additional_information": "user_21" }, { - "id": "5v6355kyw4odfoyazgfa5763za", - "title": "Example Login Item 13", + "id": "xym67w4f5bsdwifckdxj5dwjkm", + "title": "Example Login Item 23", "tags": ["tag_2"], "version": 1, "vault": { @@ -130,13 +130,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:06Z", - "updated_at": "2023-02-24T17:56:06Z", - "additional_information": "user_13" + "created_at": "2023-07-08T00:41:59Z", + "updated_at": "2023-07-08T00:41:59Z", + "additional_information": "user_23" }, { - "id": "3srtzdqw5owgexrbwejievnlba", - "title": "Example Login Item 19", + "id": "4qe7s6hg6rbnetifh2khioyubi", + "title": "Example Login Item 29", "tags": ["tag_2"], "version": 1, "vault": { @@ -145,13 +145,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:12Z", - "updated_at": "2023-02-24T17:56:12Z", - "additional_information": "user_19" + "created_at": "2023-07-08T00:42:05Z", + "updated_at": "2023-07-08T00:42:05Z", + "additional_information": "user_29" }, { - "id": "txcqg27jb2mgs3ltt6hlchaulu", - "title": "Example Login Item 51", + "id": "uydqmqfe3kwt4a5lrwrdizoo2a", + "title": "Example Login Item 31", "tags": ["tag_2"], "version": 1, "vault": { @@ -160,13 +160,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:44Z", - "updated_at": "2023-02-24T17:56:44Z", - "additional_information": "user_51" + "created_at": "2023-07-08T00:42:07Z", + "updated_at": "2023-07-08T00:42:07Z", + "additional_information": "user_31" }, { - "id": "e3xgioplb5fwwyhvw5cgx6p4h4", - "title": "Example Login Item 07", + "id": "o37lfrsn4johum5znnhka6yyqe", + "title": "Example Login Item 33", "tags": ["tag_2"], "version": 1, "vault": { @@ -175,13 +175,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:00Z", - "updated_at": "2023-02-24T17:56:00Z", - "additional_information": "user_07" + "created_at": "2023-07-08T00:42:09Z", + "updated_at": "2023-07-08T00:42:09Z", + "additional_information": "user_33" }, { - "id": "sltbe3nfqdsyo6gfyslmzuzemi", - "title": "Example Login Item 21", + "id": "suol6frogf5e3mszgt3eu3a4by", + "title": "Example Login Item 41", "tags": ["tag_2"], "version": 1, "vault": { @@ -190,13 +190,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:14Z", - "updated_at": "2023-02-24T17:56:14Z", - "additional_information": "user_21" + "created_at": "2023-07-08T00:42:16Z", + "updated_at": "2023-07-08T00:42:16Z", + "additional_information": "user_41" }, { - "id": "3b5lgd42msjwl4ysvli52bm7ry", - "title": "Example Login Item 53", + "id": "a2zljydknkdommoj7pm7sxdciu", + "title": "Example Login Item 35", "tags": ["tag_2"], "version": 1, "vault": { @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:46Z", - "updated_at": "2023-02-24T17:56:46Z", - "additional_information": "user_53" + "created_at": "2023-07-08T00:42:11Z", + "updated_at": "2023-07-08T00:42:11Z", + "additional_information": "user_35" }, { - "id": "j6b77wlbwjskfub6nnidcfkeuy", - "title": "Example Login Item 23", + "id": "bcee26kozqfxz2x3ud2mod3owy", + "title": "Example Login Item 19", "tags": ["tag_2"], "version": 1, "vault": { @@ -220,13 +220,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:16Z", - "updated_at": "2023-02-24T17:56:16Z", - "additional_information": "user_23" + "created_at": "2023-07-08T00:41:56Z", + "updated_at": "2023-07-08T00:41:56Z", + "additional_information": "user_19" }, { - "id": "liadbfkaoetwbiu25ulkmbyb34", - "title": "Example Login Item 05", + "id": "eqkfmddqsger2ka453jnovpnl4", + "title": "Example Login Item 39", "tags": ["tag_2"], "version": 1, "vault": { @@ -235,13 +235,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:58Z", - "updated_at": "2023-02-24T17:55:58Z", - "additional_information": "user_05" + "created_at": "2023-07-08T00:42:14Z", + "updated_at": "2023-07-08T00:42:14Z", + "additional_information": "user_39" }, { - "id": "usyl6cc2juicjmhu7kpeek7jmi", - "title": "Example Login Item 11", + "id": "xjfktjshz2y6qugc43o6v6llh4", + "title": "Example Login Item 43", "tags": ["tag_2"], "version": 1, "vault": { @@ -250,13 +250,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:04Z", - "updated_at": "2023-02-24T17:56:04Z", - "additional_information": "user_11" + "created_at": "2023-07-08T00:42:18Z", + "updated_at": "2023-07-08T00:42:18Z", + "additional_information": "user_43" }, { - "id": "vuohfuqvpi5sqbrebhhcdpadsa", - "title": "Example Login Item 35", + "id": "mlocnwqdjqmmpy2ot2djpy5bnu", + "title": "Example Login Item 45", "tags": ["tag_2"], "version": 1, "vault": { @@ -265,13 +265,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:27Z", - "updated_at": "2023-02-24T17:56:27Z", - "additional_information": "user_35" + "created_at": "2023-07-08T00:42:20Z", + "updated_at": "2023-07-08T00:42:20Z", + "additional_information": "user_45" }, { - "id": "3cutouoilmxk3jduqjgmhe7ete", - "title": "Example Login Item 25", + "id": "2axi5b4g3sk4avnl326b4qd62u", + "title": "Example Login Item 51", "tags": ["tag_2"], "version": 1, "vault": { @@ -280,13 +280,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:18Z", - "updated_at": "2023-02-24T17:56:18Z", - "additional_information": "user_25" + "created_at": "2023-07-08T00:42:26Z", + "updated_at": "2023-07-08T00:42:26Z", + "additional_information": "user_51" }, { - "id": "gpdv3i52wgzgem7ahm6bmf2mgi", - "title": "Example Login Item 37", + "id": "gug2exuykefjqtltfae72nlax4", + "title": "Example Login Item 55", "tags": ["tag_2"], "version": 1, "vault": { @@ -295,13 +295,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:29Z", - "updated_at": "2023-02-24T17:56:29Z", - "additional_information": "user_37" + "created_at": "2023-07-08T00:42:29Z", + "updated_at": "2023-07-08T00:42:29Z", + "additional_information": "user_55" }, { - "id": "epd4ou34sowqb6tejdqhw6fsri", - "title": "Example Login Item 09", + "id": "fgqounewhbgxzqvenxabtrn22e", + "title": "Example Login Item 53", "tags": ["tag_2"], "version": 1, "vault": { @@ -310,13 +310,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:02Z", - "updated_at": "2023-02-24T17:56:02Z", - "additional_information": "user_09" + "created_at": "2023-07-08T00:42:27Z", + "updated_at": "2023-07-08T00:42:27Z", + "additional_information": "user_53" }, { - "id": "jx2p4scgtcgunh2byphba4aqmi", - "title": "Example Login Item 01", + "id": "xeite36sy64ubgy37pxkxikevi", + "title": "Example Login Item 47", "tags": ["tag_2"], "version": 1, "vault": { @@ -325,13 +325,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:54Z", - "updated_at": "2023-02-24T17:55:54Z", - "additional_information": "user_01" + "created_at": "2023-07-08T00:42:22Z", + "updated_at": "2023-07-08T00:42:22Z", + "additional_information": "user_47" }, { - "id": "d5sydookffvlkvgini5fuboykq", - "title": "Example Login Item 27", + "id": "polljyc4fzna3hka2itkaajpfm", + "title": "Example Login Item 57", "tags": ["tag_2"], "version": 1, "vault": { @@ -340,13 +340,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:20Z", - "updated_at": "2023-02-24T17:56:20Z", - "additional_information": "user_27" + "created_at": "2023-07-08T00:42:31Z", + "updated_at": "2023-07-08T00:42:31Z", + "additional_information": "user_57" }, { - "id": "bpdpbvqa6mpook6f6kezzdbqkm", - "title": "Example Login Item 03", + "id": "auwrga7ebnmq4mgjyeq4mggkm4", + "title": "Example Login Item 01", "tags": ["tag_2"], "version": 1, "vault": { @@ -355,13 +355,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:55:56Z", - "updated_at": "2023-02-24T17:55:56Z", - "additional_information": "user_03" + "created_at": "2023-07-08T00:41:39Z", + "updated_at": "2023-07-08T00:41:39Z", + "additional_information": "user_01" }, { - "id": "fxtwj6dy64gkpttwrkdmhe2qeu", - "title": "Example Login Item 31", + "id": "ghse4pcxazja4kaiblm6esidc4", + "title": "Example Login Item 27", "tags": ["tag_2"], "version": 1, "vault": { @@ -370,13 +370,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:23Z", - "updated_at": "2023-02-24T17:56:23Z", - "additional_information": "user_31" + "created_at": "2023-07-08T00:42:03Z", + "updated_at": "2023-07-08T00:42:03Z", + "additional_information": "user_27" }, { - "id": "5qbtlgx3q4jedrxvvnjljvpm44", - "title": "Example Login Item 33", + "id": "xtaesbnq5quulprnggw3rbifqm", + "title": "Example Login Item 25", "tags": ["tag_2"], "version": 1, "vault": { @@ -385,13 +385,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:25Z", - "updated_at": "2023-02-24T17:56:25Z", - "additional_information": "user_33" + "created_at": "2023-07-08T00:42:01Z", + "updated_at": "2023-07-08T00:42:01Z", + "additional_information": "user_25" }, { - "id": "fcliwcb2kaxvttvdyx2llubdby", - "title": "Example Login Item 39", + "id": "gxiweo5d3wmjl26yqwghjlwkca", + "title": "Example Login Item 05", "tags": ["tag_2"], "version": 1, "vault": { @@ -400,13 +400,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:31Z", - "updated_at": "2023-02-24T17:56:31Z", - "additional_information": "user_39" + "created_at": "2023-07-08T00:41:43Z", + "updated_at": "2023-07-08T00:41:43Z", + "additional_information": "user_05" }, { - "id": "xf77ka63em7xpkkbfuuu4fihjq", - "title": "Example Login Item 55", + "id": "euwilsrjdmoc72oeq55mn26aua", + "title": "Example Login Item 07", "tags": ["tag_2"], "version": 1, "vault": { @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:48Z", - "updated_at": "2023-02-24T17:56:48Z", - "additional_information": "user_55" + "created_at": "2023-07-08T00:41:45Z", + "updated_at": "2023-07-08T00:41:45Z", + "additional_information": "user_07" }, { - "id": "gcquu2t47uk3p2547jm7gckxk4", - "title": "Example Login Item 41", + "id": "ea43m2fxsdxoqkfchnyjhf3mu4", + "title": "Example Login Item 03", "tags": ["tag_2"], "version": 1, "vault": { @@ -430,13 +430,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:33Z", - "updated_at": "2023-02-24T17:56:33Z", - "additional_information": "user_41" + "created_at": "2023-07-08T00:41:41Z", + "updated_at": "2023-07-08T00:41:41Z", + "additional_information": "user_03" }, { - "id": "y22pqwjet5zuj7prax6lupmmye", - "title": "Example Login Item 57", + "id": "464gghlcyuzukmb6mvcibbqjqi", + "title": "Example Login Item 09", "tags": ["tag_2"], "version": 1, "vault": { @@ -445,8 +445,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-24T17:56:50Z", - "updated_at": "2023-02-24T17:56:50Z", - "additional_information": "user_57" + "created_at": "2023-07-08T00:41:47Z", + "updated_at": "2023-07-08T00:41:47Z", + "additional_information": "user_09" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-2/list-signed-in-accounts/output b/tests/config/mock-op/responses-item-delete-multiple/responses-2/list-signed-in-accounts/output index f5134399..5ba8ce9e 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-2/list-signed-in-accounts/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-2/list-signed-in-accounts/output @@ -1,14 +1,20 @@ [ - { - "url": "example-account.1password.com", - "email": "example_user@example.email", - "user_uuid": "5GHHPJK5HZC5BAT7WDUXW57G44", - "account_uuid": "GRXJAN4BY5DPROISKYL55IRCPY" - }, { "url": "my.1password.com", "email": "guest_user@example.email", "user_uuid": "DJGTGRFRM5C4BHNUXQLJXQJAOE", "account_uuid": "6J7RFGQWONBVJHIHJUVICO2C3Q" + }, + { + "url": "pyonepassword.1password.com", + "email": "uid000@gmail.com", + "user_uuid": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57" + }, + { + "url": "example-account.1password.com", + "email": "example_user@example.email", + "user_uuid": "5GHHPJK5HZC5BAT7WDUXW57G44", + "account_uuid": "GRXJAN4BY5DPROISKYL55IRCPY" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-3/cli-version/output b/tests/config/mock-op/responses-item-delete-multiple/responses-3/cli-version/output index edcfe40d..c22d404b 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-3/cli-version/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-3/cli-version/output @@ -1 +1 @@ -2.14.0 +2.19.0-beta.01 diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-alt-title-glob/output b/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-alt-title-glob/output index 8dbdb253..df812b58 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-alt-title-glob/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-alt-title-glob/output @@ -1,7 +1,7 @@ [ { - "id": "yz7he5wzrjib3k3weha3ucrztu", - "title": "Example Login Item 14", + "id": "a3yqf7j2zv63oevqyx7f5ny5wy", + "title": "Example Login Item 02", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -9,13 +9,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:08Z", - "updated_at": "2023-02-26T21:53:08Z", - "additional_information": "user_14" + "created_at": "2023-07-10T20:54:16Z", + "updated_at": "2023-07-10T20:54:16Z", + "additional_information": "user_02" }, { - "id": "gpzd5x33hnfgom4a6tv4ef42me", - "title": "Example Login Item 31", + "id": "y6j7bbkqbbqubjcmtjnnu5jycu", + "title": "Example Login Item 12", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -23,13 +23,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:30Z", - "updated_at": "2023-02-26T21:53:30Z", - "additional_information": "user_31" + "created_at": "2023-07-10T20:54:28Z", + "updated_at": "2023-07-10T20:54:28Z", + "additional_information": "user_12" }, { - "id": "6bcqblmxbrsisisb2eupjq7avm", - "title": "Example Login Item 25", + "id": "radxxrqumaqtnvqozslekl6nhy", + "title": "Example Login Item 00", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -37,13 +37,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:23Z", - "updated_at": "2023-02-26T21:53:23Z", - "additional_information": "user_25" + "created_at": "2023-07-10T20:54:14Z", + "updated_at": "2023-07-10T20:54:14Z", + "additional_information": "user_00" }, { - "id": "ddqvqxnlbobjaaijpf5nmp2iiq", - "title": "Example Login Item 00", + "id": "vtb5xljhrjfe42tzqchi3qrnpy", + "title": "Example Login Item 03", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -51,13 +51,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:53Z", - "updated_at": "2023-02-26T21:52:53Z", - "additional_information": "user_00" + "created_at": "2023-07-10T20:54:17Z", + "updated_at": "2023-07-10T20:54:17Z", + "additional_information": "user_03" }, { - "id": "zayggylnibccqhvzmv3hgrgy4u", - "title": "Example Login Item 27", + "id": "r2vmvbmc3akdnmuuxlbfxzbu3y", + "title": "Example Login Item 09", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -65,13 +65,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:26Z", - "updated_at": "2023-02-26T21:53:26Z", - "additional_information": "user_27" + "created_at": "2023-07-10T20:54:24Z", + "updated_at": "2023-07-10T20:54:24Z", + "additional_information": "user_09" }, { - "id": "5wmqz5qe24km7fmgttklkx7p5a", - "title": "Example Login Item 20", + "id": "i2c3us2sfq6gbh2u5n46hca7he", + "title": "Example Login Item 11", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -79,13 +79,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:16Z", - "updated_at": "2023-02-26T21:53:16Z", - "additional_information": "user_20" + "created_at": "2023-07-10T20:54:27Z", + "updated_at": "2023-07-10T20:54:27Z", + "additional_information": "user_11" }, { - "id": "kzpfqniu26tatmtzgk2wu377oe", - "title": "Example Login Item 19", + "id": "setr26pmay3wwsmmtyqnop43ru", + "title": "Example Login Item 06", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -93,13 +93,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:14Z", - "updated_at": "2023-02-26T21:53:14Z", - "additional_information": "user_19" + "created_at": "2023-07-10T20:54:20Z", + "updated_at": "2023-07-10T20:54:20Z", + "additional_information": "user_06" }, { - "id": "tkofaqsvxmpfdkvvzeftlw4a3e", - "title": "Example Login Item 01", + "id": "ofcl4plyaa63y2qkesp3vtmohi", + "title": "Example Login Item 08", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -107,13 +107,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:54Z", - "updated_at": "2023-02-26T21:52:54Z", - "additional_information": "user_01" + "created_at": "2023-07-10T20:54:23Z", + "updated_at": "2023-07-10T20:54:23Z", + "additional_information": "user_08" }, { - "id": "lsujgnao5vw4lrjuhqoiovaxnq", - "title": "Example Login Item 21", + "id": "3csk5dtmupjjuph5durmxgpvvq", + "title": "Example Login Item 36", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -121,13 +121,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:17Z", - "updated_at": "2023-02-26T21:53:17Z", - "additional_information": "user_21" + "created_at": "2023-07-10T20:54:54Z", + "updated_at": "2023-07-10T20:54:54Z", + "additional_information": "user_36" }, { - "id": "ps2fpw422sjzfgmmibbh2ryp54", - "title": "Example Login Item 15", + "id": "vbvaznvghvau55d4hfalcqcg2u", + "title": "Example Login Item 24", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -135,13 +135,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:09Z", - "updated_at": "2023-02-26T21:53:09Z", - "additional_information": "user_15" + "created_at": "2023-07-10T20:54:42Z", + "updated_at": "2023-07-10T20:54:42Z", + "additional_information": "user_24" }, { - "id": "p35gttx2rad2tr5ah7mwesj7ea", - "title": "Example Login Item 26", + "id": "fh7byzemtipjjmb65irgewmlwq", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -149,13 +149,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:24Z", - "updated_at": "2023-02-26T21:53:24Z", - "additional_information": "user_26" + "created_at": "2023-07-10T20:54:48Z", + "updated_at": "2023-07-10T20:54:48Z", + "additional_information": "user_30" }, { - "id": "ry46ke2h3hmg6ukkfbkwgzgk4a", - "title": "Example Login Item 02", + "id": "3bxulcvnt2afmuuc5rrfd3t3su", + "title": "Example Login Item 04", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -163,13 +163,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:55Z", - "updated_at": "2023-02-26T21:52:55Z", - "additional_information": "user_02" + "created_at": "2023-07-10T20:54:18Z", + "updated_at": "2023-07-10T20:54:18Z", + "additional_information": "user_04" }, { - "id": "umsfsqt3pd7oms46lsgcdfkoeq", - "title": "Example Login Item 16", + "id": "z6kmzdaj64wyzq7yuuqjaubimm", + "title": "Example Login Item 07", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -177,13 +177,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:10Z", - "updated_at": "2023-02-26T21:53:10Z", - "additional_information": "user_16" + "created_at": "2023-07-10T20:54:21Z", + "updated_at": "2023-07-10T20:54:21Z", + "additional_information": "user_07" }, { - "id": "2gxm222kpezqumb5ib57hk24ny", - "title": "Example Login Item 22", + "id": "6cdyz752d4i4qmoenn4hhn5qaa", + "title": "Example Login Item 05", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -191,13 +191,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:18Z", - "updated_at": "2023-02-26T21:53:18Z", - "additional_information": "user_22" + "created_at": "2023-07-10T20:54:19Z", + "updated_at": "2023-07-10T20:54:19Z", + "additional_information": "user_05" }, { - "id": "biugqc2uuuehj355seh6ej7moy", - "title": "Example Login Item 32", + "id": "daukcdlqtkrqqwqcz7alkoa6em", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:32Z", - "updated_at": "2023-02-26T21:53:32Z", - "additional_information": "user_32" + "created_at": "2023-07-10T20:54:49Z", + "updated_at": "2023-07-10T20:54:49Z", + "additional_information": "user_31" }, { - "id": "fazkwyxnaownqxgenf67btguwy", - "title": "Example Login Item 17", + "id": "ltgvl3h7j6o6qk6bkyabxc2dbm", + "title": "Example Login Item 25", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -219,13 +219,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:12Z", - "updated_at": "2023-02-26T21:53:12Z", - "additional_information": "user_17" + "created_at": "2023-07-10T20:54:43Z", + "updated_at": "2023-07-10T20:54:43Z", + "additional_information": "user_25" }, { - "id": "ioskuz642omqnvrq6tqknqghg4", - "title": "Example Login Item 03", + "id": "rm6dpqwxh7huf62a4un4rbp7ki", + "title": "Example Login Item 27", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -233,13 +233,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:56Z", - "updated_at": "2023-02-26T21:52:56Z", - "additional_information": "user_03" + "created_at": "2023-07-10T20:54:45Z", + "updated_at": "2023-07-10T20:54:45Z", + "additional_information": "user_27" }, { - "id": "a76ldek4tcny3fggu3u7cq456u", - "title": "Example Login Item 23", + "id": "bk3vqleti5rk5yvgk2iyl7r4ue", + "title": "Example Login Item 32", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -247,13 +247,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:21Z", - "updated_at": "2023-02-26T21:53:21Z", - "additional_information": "user_23" + "created_at": "2023-07-10T20:54:50Z", + "updated_at": "2023-07-10T20:54:50Z", + "additional_information": "user_32" }, { - "id": "wtvxlb5cml5ihumatxubfo5quq", - "title": "Example Login Item 08", + "id": "m7jprtjz3v3zkxx4sgm5fh5ske", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -261,13 +261,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:01Z", - "updated_at": "2023-02-26T21:53:01Z", - "additional_information": "user_08" + "created_at": "2023-07-10T20:54:37Z", + "updated_at": "2023-07-10T20:54:37Z", + "additional_information": "user_19" }, { - "id": "6br5ex37daswo5xzdbi6chkjlu", - "title": "Example Login Item 18", + "id": "qtfbp6zwnhwxmirbpziekhuf7y", + "title": "Example Login Item 29", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -275,13 +275,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:13Z", - "updated_at": "2023-02-26T21:53:13Z", - "additional_information": "user_18" + "created_at": "2023-07-10T20:54:47Z", + "updated_at": "2023-07-10T20:54:47Z", + "additional_information": "user_29" }, { - "id": "we5iwz2cqhf73y3bzrcfvzcz2m", - "title": "Example Login Item 09", + "id": "3aqwi56gkv2wonw5w35naruroa", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -289,13 +289,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:02Z", - "updated_at": "2023-02-26T21:53:02Z", - "additional_information": "user_09" + "created_at": "2023-07-10T20:54:46Z", + "updated_at": "2023-07-10T20:54:46Z", + "additional_information": "user_28" }, { - "id": "zz655vi3xlv2alllq7cjlyrxyu", - "title": "Example Login Item 24", + "id": "7huqr4d5mvpmjov6aa2kl4wcnq", + "title": "Example Login Item 34", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -303,13 +303,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:22Z", - "updated_at": "2023-02-26T21:53:22Z", - "additional_information": "user_24" + "created_at": "2023-07-10T20:54:52Z", + "updated_at": "2023-07-10T20:54:52Z", + "additional_information": "user_34" }, { - "id": "x2b52i4kzkumd6r3mbko3ordwy", - "title": "Example Login Item 04", + "id": "fexqrzfidz53w4jzn7cveprqsy", + "title": "Example Login Item 21", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -317,13 +317,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:57Z", - "updated_at": "2023-02-26T21:52:57Z", - "additional_information": "user_04" + "created_at": "2023-07-10T20:54:39Z", + "updated_at": "2023-07-10T20:54:39Z", + "additional_information": "user_21" }, { - "id": "rczlhdg7pum7wrhrf7euoeyatu", - "title": "Example Login Item 36", + "id": "b35tdije6oiozyogleflhhwhwy", + "title": "Example Login Item 01", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -331,13 +331,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:37Z", - "updated_at": "2023-02-26T21:53:37Z", - "additional_information": "user_36" + "created_at": "2023-07-10T20:54:15Z", + "updated_at": "2023-07-10T20:54:15Z", + "additional_information": "user_01" }, { - "id": "6hlvskty5s72ljkn333iy445wi", - "title": "Example Login Item 28", + "id": "qez2yursmmkx5yqb5rgpwomblm", + "title": "Example Login Item 15", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -345,13 +345,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:27Z", - "updated_at": "2023-02-26T21:53:27Z", - "additional_information": "user_28" + "created_at": "2023-07-10T20:54:32Z", + "updated_at": "2023-07-10T20:54:32Z", + "additional_information": "user_15" }, { - "id": "eibsbn332mmexisxv73gt6ifky", - "title": "Example Login Item 10", + "id": "wviqh7wfazdguizm3xm5ydfrvu", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -359,13 +359,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:03Z", - "updated_at": "2023-02-26T21:53:03Z", - "additional_information": "user_10" + "created_at": "2023-07-10T20:54:33Z", + "updated_at": "2023-07-10T20:54:33Z", + "additional_information": "user_16" }, { - "id": "bu4pinbfu72ze2rbh2ekhu47jy", - "title": "Example Login Item 05", + "id": "rhe6yevalei4fvcgkzdzgx5ihm", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -373,13 +373,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:58Z", - "updated_at": "2023-02-26T21:52:58Z", - "additional_information": "user_05" + "created_at": "2023-07-10T20:54:30Z", + "updated_at": "2023-07-10T20:54:30Z", + "additional_information": "user_14" }, { - "id": "5h3qe4bqekt4ugxkobdha2fsli", - "title": "Example Login Item 29", + "id": "irpmzvyube7obnjz37s4nhyhf4", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -387,13 +387,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:28Z", - "updated_at": "2023-02-26T21:53:28Z", - "additional_information": "user_29" + "created_at": "2023-07-10T20:54:34Z", + "updated_at": "2023-07-10T20:54:34Z", + "additional_information": "user_17" }, { - "id": "6zh4myb3d6rwtv3hfhg6qp2ncm", - "title": "Example Login Item 06", + "id": "kib7zokx5oyeizss5pdci5b6p4", + "title": "Example Login Item 35", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -401,13 +401,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:59Z", - "updated_at": "2023-02-26T21:52:59Z", - "additional_information": "user_06" + "created_at": "2023-07-10T20:54:53Z", + "updated_at": "2023-07-10T20:54:53Z", + "additional_information": "user_35" }, { - "id": "bmqdjbf54c7zor4jfnfdal7nva", - "title": "Example Login Item 35", + "id": "ijkrebl72abwl2w32fx53c56km", + "title": "Example Login Item 23", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:36Z", - "updated_at": "2023-02-26T21:53:36Z", - "additional_information": "user_35" + "created_at": "2023-07-10T20:54:41Z", + "updated_at": "2023-07-10T20:54:41Z", + "additional_information": "user_23" }, { - "id": "tzxbkgrpxjk47z52fvgpmfaoe4", - "title": "Example Login Item 07", + "id": "xteh3aypnin5nopio67vywhg4q", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -429,13 +429,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:00Z", - "updated_at": "2023-02-26T21:53:00Z", - "additional_information": "user_07" + "created_at": "2023-07-10T20:54:35Z", + "updated_at": "2023-07-10T20:54:35Z", + "additional_information": "user_18" }, { - "id": "rgc4nh6iekiye7cqdi2mfhpqpa", - "title": "Example Login Item 11", + "id": "aa3myi6s2xqobqrw3o4zhkcwru", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -443,13 +443,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:05Z", - "updated_at": "2023-02-26T21:53:05Z", - "additional_information": "user_11" + "created_at": "2023-07-10T20:54:38Z", + "updated_at": "2023-07-10T20:54:38Z", + "additional_information": "user_20" }, { - "id": "v4edzqxgzcquq2ru4kihrzhowy", - "title": "Example Login Item 12", + "id": "dwfs73h3uvazlqv6s5lpcqwcpu", + "title": "Example Login Item 22", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -457,13 +457,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:06Z", - "updated_at": "2023-02-26T21:53:06Z", - "additional_information": "user_12" + "created_at": "2023-07-10T20:54:40Z", + "updated_at": "2023-07-10T20:54:40Z", + "additional_information": "user_22" }, { - "id": "jhckzqn275tslogsidxcby3qwi", - "title": "Example Login Item 30", + "id": "o3vbuksseuhovpmizkgvlut7ma", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -471,13 +471,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:29Z", - "updated_at": "2023-02-26T21:53:29Z", - "additional_information": "user_30" + "created_at": "2023-07-10T20:54:29Z", + "updated_at": "2023-07-10T20:54:29Z", + "additional_information": "user_13" }, { - "id": "shybm7klvq3wkek3fxwuakyk5i", - "title": "Example Login Item 13", + "id": "koo45d6jts4pkuck2n5aordmny", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -485,13 +485,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:07Z", - "updated_at": "2023-02-26T21:53:07Z", - "additional_information": "user_13" + "created_at": "2023-07-10T20:54:51Z", + "updated_at": "2023-07-10T20:54:51Z", + "additional_information": "user_33" }, { - "id": "pqmb32ew7sirfqkrlgpehcd6gm", - "title": "Example Login Item 34", + "id": "5m5ezfrtkzbyzkngiy3nb3xzdq", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -499,13 +499,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:35Z", - "updated_at": "2023-02-26T21:53:35Z", - "additional_information": "user_34" + "created_at": "2023-07-10T20:54:44Z", + "updated_at": "2023-07-10T20:54:44Z", + "additional_information": "user_26" }, { - "id": "xeaybnnl3tvisws5jvwcwpsvey", - "title": "Example Login Item 33", + "id": "kb7vgcvv3qyjkvbhm6em2f6hzy", + "title": "Example Login Item 10", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -513,8 +513,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:33Z", - "updated_at": "2023-02-26T21:53:33Z", - "additional_information": "user_33" + "created_at": "2023-07-10T20:54:25Z", + "updated_at": "2023-07-10T20:54:25Z", + "additional_information": "user_10" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-title-glob/output b/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-title-glob/output index 5f70c95d..6c1580e4 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-title-glob/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3-title-glob/output @@ -1,7 +1,7 @@ [ { - "id": "x2b52i4kzkumd6r3mbko3ordwy", - "title": "Example Login Item 04", + "id": "3csk5dtmupjjuph5durmxgpvvq", + "title": "Example Login Item 36", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -9,13 +9,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:57Z", - "updated_at": "2023-02-26T21:52:57Z", - "additional_information": "user_04" + "created_at": "2023-07-10T20:54:54Z", + "updated_at": "2023-07-10T20:54:54Z", + "additional_information": "user_36" }, { - "id": "eibsbn332mmexisxv73gt6ifky", - "title": "Example Login Item 10", + "id": "qez2yursmmkx5yqb5rgpwomblm", + "title": "Example Login Item 15", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -23,13 +23,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:03Z", - "updated_at": "2023-02-26T21:53:03Z", - "additional_information": "user_10" + "created_at": "2023-07-10T20:54:32Z", + "updated_at": "2023-07-10T20:54:32Z", + "additional_information": "user_15" }, { - "id": "tkofaqsvxmpfdkvvzeftlw4a3e", - "title": "Example Login Item 01", + "id": "wviqh7wfazdguizm3xm5ydfrvu", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -37,13 +37,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:54Z", - "updated_at": "2023-02-26T21:52:54Z", - "additional_information": "user_01" + "created_at": "2023-07-10T20:54:33Z", + "updated_at": "2023-07-10T20:54:33Z", + "additional_information": "user_16" }, { - "id": "ry46ke2h3hmg6ukkfbkwgzgk4a", - "title": "Example Login Item 02", + "id": "irpmzvyube7obnjz37s4nhyhf4", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -51,13 +51,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:55Z", - "updated_at": "2023-02-26T21:52:55Z", - "additional_information": "user_02" + "created_at": "2023-07-10T20:54:34Z", + "updated_at": "2023-07-10T20:54:34Z", + "additional_information": "user_17" }, { - "id": "ioskuz642omqnvrq6tqknqghg4", - "title": "Example Login Item 03", + "id": "xteh3aypnin5nopio67vywhg4q", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -65,13 +65,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:56Z", - "updated_at": "2023-02-26T21:52:56Z", - "additional_information": "user_03" + "created_at": "2023-07-10T20:54:35Z", + "updated_at": "2023-07-10T20:54:35Z", + "additional_information": "user_18" }, { - "id": "we5iwz2cqhf73y3bzrcfvzcz2m", - "title": "Example Login Item 09", + "id": "m7jprtjz3v3zkxx4sgm5fh5ske", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -79,13 +79,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:02Z", - "updated_at": "2023-02-26T21:53:02Z", - "additional_information": "user_09" + "created_at": "2023-07-10T20:54:37Z", + "updated_at": "2023-07-10T20:54:37Z", + "additional_information": "user_19" }, { - "id": "wtvxlb5cml5ihumatxubfo5quq", - "title": "Example Login Item 08", + "id": "aa3myi6s2xqobqrw3o4zhkcwru", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -93,13 +93,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:01Z", - "updated_at": "2023-02-26T21:53:01Z", - "additional_information": "user_08" + "created_at": "2023-07-10T20:54:38Z", + "updated_at": "2023-07-10T20:54:38Z", + "additional_information": "user_20" }, { - "id": "6br5ex37daswo5xzdbi6chkjlu", - "title": "Example Login Item 18", + "id": "fexqrzfidz53w4jzn7cveprqsy", + "title": "Example Login Item 21", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -107,13 +107,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:13Z", - "updated_at": "2023-02-26T21:53:13Z", - "additional_information": "user_18" + "created_at": "2023-07-10T20:54:39Z", + "updated_at": "2023-07-10T20:54:39Z", + "additional_information": "user_21" }, { - "id": "5wmqz5qe24km7fmgttklkx7p5a", - "title": "Example Login Item 20", + "id": "dwfs73h3uvazlqv6s5lpcqwcpu", + "title": "Example Login Item 22", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -121,13 +121,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:16Z", - "updated_at": "2023-02-26T21:53:16Z", - "additional_information": "user_20" + "created_at": "2023-07-10T20:54:40Z", + "updated_at": "2023-07-10T20:54:40Z", + "additional_information": "user_22" }, { - "id": "ps2fpw422sjzfgmmibbh2ryp54", - "title": "Example Login Item 15", + "id": "ijkrebl72abwl2w32fx53c56km", + "title": "Example Login Item 23", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -135,13 +135,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:09Z", - "updated_at": "2023-02-26T21:53:09Z", - "additional_information": "user_15" + "created_at": "2023-07-10T20:54:41Z", + "updated_at": "2023-07-10T20:54:41Z", + "additional_information": "user_23" }, { - "id": "umsfsqt3pd7oms46lsgcdfkoeq", - "title": "Example Login Item 16", + "id": "vbvaznvghvau55d4hfalcqcg2u", + "title": "Example Login Item 24", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -149,13 +149,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:10Z", - "updated_at": "2023-02-26T21:53:10Z", - "additional_information": "user_16" + "created_at": "2023-07-10T20:54:42Z", + "updated_at": "2023-07-10T20:54:42Z", + "additional_information": "user_24" }, { - "id": "p35gttx2rad2tr5ah7mwesj7ea", - "title": "Example Login Item 26", + "id": "setr26pmay3wwsmmtyqnop43ru", + "title": "Example Login Item 06", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -163,13 +163,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:24Z", - "updated_at": "2023-02-26T21:53:24Z", - "additional_information": "user_26" + "created_at": "2023-07-10T20:54:20Z", + "updated_at": "2023-07-10T20:54:20Z", + "additional_information": "user_06" }, { - "id": "kzpfqniu26tatmtzgk2wu377oe", - "title": "Example Login Item 19", + "id": "ltgvl3h7j6o6qk6bkyabxc2dbm", + "title": "Example Login Item 25", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -177,13 +177,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:14Z", - "updated_at": "2023-02-26T21:53:14Z", - "additional_information": "user_19" + "created_at": "2023-07-10T20:54:43Z", + "updated_at": "2023-07-10T20:54:43Z", + "additional_information": "user_25" }, { - "id": "yz7he5wzrjib3k3weha3ucrztu", - "title": "Example Login Item 14", + "id": "5m5ezfrtkzbyzkngiy3nb3xzdq", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -191,13 +191,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:08Z", - "updated_at": "2023-02-26T21:53:08Z", - "additional_information": "user_14" + "created_at": "2023-07-10T20:54:44Z", + "updated_at": "2023-07-10T20:54:44Z", + "additional_information": "user_26" }, { - "id": "5h3qe4bqekt4ugxkobdha2fsli", - "title": "Example Login Item 29", + "id": "bk3vqleti5rk5yvgk2iyl7r4ue", + "title": "Example Login Item 32", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:28Z", - "updated_at": "2023-02-26T21:53:28Z", - "additional_information": "user_29" + "created_at": "2023-07-10T20:54:50Z", + "updated_at": "2023-07-10T20:54:50Z", + "additional_information": "user_32" }, { - "id": "zz655vi3xlv2alllq7cjlyrxyu", - "title": "Example Login Item 24", + "id": "daukcdlqtkrqqwqcz7alkoa6em", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -219,13 +219,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:22Z", - "updated_at": "2023-02-26T21:53:22Z", - "additional_information": "user_24" + "created_at": "2023-07-10T20:54:49Z", + "updated_at": "2023-07-10T20:54:49Z", + "additional_information": "user_31" }, { - "id": "fazkwyxnaownqxgenf67btguwy", - "title": "Example Login Item 17", + "id": "koo45d6jts4pkuck2n5aordmny", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -233,12 +233,12 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:12Z", - "updated_at": "2023-02-26T21:53:12Z", - "additional_information": "user_17" + "created_at": "2023-07-10T20:54:51Z", + "updated_at": "2023-07-10T20:54:51Z", + "additional_information": "user_33" }, { - "id": "zayggylnibccqhvzmv3hgrgy4u", + "id": "rm6dpqwxh7huf62a4un4rbp7ki", "title": "Example Login Item 27", "version": 1, "vault": { @@ -247,13 +247,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:26Z", - "updated_at": "2023-02-26T21:53:26Z", + "created_at": "2023-07-10T20:54:45Z", + "updated_at": "2023-07-10T20:54:45Z", "additional_information": "user_27" }, { - "id": "bu4pinbfu72ze2rbh2ekhu47jy", - "title": "Example Login Item 05", + "id": "7huqr4d5mvpmjov6aa2kl4wcnq", + "title": "Example Login Item 34", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -261,13 +261,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:58Z", - "updated_at": "2023-02-26T21:52:58Z", - "additional_information": "user_05" + "created_at": "2023-07-10T20:54:52Z", + "updated_at": "2023-07-10T20:54:52Z", + "additional_information": "user_34" }, { - "id": "biugqc2uuuehj355seh6ej7moy", - "title": "Example Login Item 32", + "id": "radxxrqumaqtnvqozslekl6nhy", + "title": "Example Login Item 00", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -275,13 +275,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:32Z", - "updated_at": "2023-02-26T21:53:32Z", - "additional_information": "user_32" + "created_at": "2023-07-10T20:54:14Z", + "updated_at": "2023-07-10T20:54:14Z", + "additional_information": "user_00" }, { - "id": "jhckzqn275tslogsidxcby3qwi", - "title": "Example Login Item 30", + "id": "3aqwi56gkv2wonw5w35naruroa", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -289,13 +289,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:29Z", - "updated_at": "2023-02-26T21:53:29Z", - "additional_information": "user_30" + "created_at": "2023-07-10T20:54:46Z", + "updated_at": "2023-07-10T20:54:46Z", + "additional_information": "user_28" }, { - "id": "6bcqblmxbrsisisb2eupjq7avm", - "title": "Example Login Item 25", + "id": "kib7zokx5oyeizss5pdci5b6p4", + "title": "Example Login Item 35", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -303,13 +303,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:23Z", - "updated_at": "2023-02-26T21:53:23Z", - "additional_information": "user_25" + "created_at": "2023-07-10T20:54:53Z", + "updated_at": "2023-07-10T20:54:53Z", + "additional_information": "user_35" }, { - "id": "gpzd5x33hnfgom4a6tv4ef42me", - "title": "Example Login Item 31", + "id": "b35tdije6oiozyogleflhhwhwy", + "title": "Example Login Item 01", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -317,13 +317,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:30Z", - "updated_at": "2023-02-26T21:53:30Z", - "additional_information": "user_31" + "created_at": "2023-07-10T20:54:15Z", + "updated_at": "2023-07-10T20:54:15Z", + "additional_information": "user_01" }, { - "id": "6hlvskty5s72ljkn333iy445wi", - "title": "Example Login Item 28", + "id": "z6kmzdaj64wyzq7yuuqjaubimm", + "title": "Example Login Item 07", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -331,13 +331,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:27Z", - "updated_at": "2023-02-26T21:53:27Z", - "additional_information": "user_28" + "created_at": "2023-07-10T20:54:21Z", + "updated_at": "2023-07-10T20:54:21Z", + "additional_information": "user_07" }, { - "id": "lsujgnao5vw4lrjuhqoiovaxnq", - "title": "Example Login Item 21", + "id": "a3yqf7j2zv63oevqyx7f5ny5wy", + "title": "Example Login Item 02", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -345,13 +345,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:17Z", - "updated_at": "2023-02-26T21:53:17Z", - "additional_information": "user_21" + "created_at": "2023-07-10T20:54:16Z", + "updated_at": "2023-07-10T20:54:16Z", + "additional_information": "user_02" }, { - "id": "rczlhdg7pum7wrhrf7euoeyatu", - "title": "Example Login Item 36", + "id": "vtb5xljhrjfe42tzqchi3qrnpy", + "title": "Example Login Item 03", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -359,13 +359,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:37Z", - "updated_at": "2023-02-26T21:53:37Z", - "additional_information": "user_36" + "created_at": "2023-07-10T20:54:17Z", + "updated_at": "2023-07-10T20:54:17Z", + "additional_information": "user_03" }, { - "id": "2gxm222kpezqumb5ib57hk24ny", - "title": "Example Login Item 22", + "id": "qtfbp6zwnhwxmirbpziekhuf7y", + "title": "Example Login Item 29", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -373,13 +373,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:18Z", - "updated_at": "2023-02-26T21:53:18Z", - "additional_information": "user_22" + "created_at": "2023-07-10T20:54:47Z", + "updated_at": "2023-07-10T20:54:47Z", + "additional_information": "user_29" }, { - "id": "pqmb32ew7sirfqkrlgpehcd6gm", - "title": "Example Login Item 34", + "id": "3bxulcvnt2afmuuc5rrfd3t3su", + "title": "Example Login Item 04", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -387,13 +387,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:35Z", - "updated_at": "2023-02-26T21:53:35Z", - "additional_information": "user_34" + "created_at": "2023-07-10T20:54:18Z", + "updated_at": "2023-07-10T20:54:18Z", + "additional_information": "user_04" }, { - "id": "ddqvqxnlbobjaaijpf5nmp2iiq", - "title": "Example Login Item 00", + "id": "ofcl4plyaa63y2qkesp3vtmohi", + "title": "Example Login Item 08", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -401,13 +401,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:53Z", - "updated_at": "2023-02-26T21:52:53Z", - "additional_information": "user_00" + "created_at": "2023-07-10T20:54:23Z", + "updated_at": "2023-07-10T20:54:23Z", + "additional_information": "user_08" }, { - "id": "bmqdjbf54c7zor4jfnfdal7nva", - "title": "Example Login Item 35", + "id": "r2vmvbmc3akdnmuuxlbfxzbu3y", + "title": "Example Login Item 09", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:36Z", - "updated_at": "2023-02-26T21:53:36Z", - "additional_information": "user_35" + "created_at": "2023-07-10T20:54:24Z", + "updated_at": "2023-07-10T20:54:24Z", + "additional_information": "user_09" }, { - "id": "xeaybnnl3tvisws5jvwcwpsvey", - "title": "Example Login Item 33", + "id": "kb7vgcvv3qyjkvbhm6em2f6hzy", + "title": "Example Login Item 10", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -429,13 +429,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:33Z", - "updated_at": "2023-02-26T21:53:33Z", - "additional_information": "user_33" + "created_at": "2023-07-10T20:54:25Z", + "updated_at": "2023-07-10T20:54:25Z", + "additional_information": "user_10" }, { - "id": "6zh4myb3d6rwtv3hfhg6qp2ncm", - "title": "Example Login Item 06", + "id": "i2c3us2sfq6gbh2u5n46hca7he", + "title": "Example Login Item 11", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -443,13 +443,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:59Z", - "updated_at": "2023-02-26T21:52:59Z", - "additional_information": "user_06" + "created_at": "2023-07-10T20:54:27Z", + "updated_at": "2023-07-10T20:54:27Z", + "additional_information": "user_11" }, { - "id": "tzxbkgrpxjk47z52fvgpmfaoe4", - "title": "Example Login Item 07", + "id": "y6j7bbkqbbqubjcmtjnnu5jycu", + "title": "Example Login Item 12", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -457,13 +457,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:00Z", - "updated_at": "2023-02-26T21:53:00Z", - "additional_information": "user_07" + "created_at": "2023-07-10T20:54:28Z", + "updated_at": "2023-07-10T20:54:28Z", + "additional_information": "user_12" }, { - "id": "v4edzqxgzcquq2ru4kihrzhowy", - "title": "Example Login Item 12", + "id": "o3vbuksseuhovpmizkgvlut7ma", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -471,13 +471,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:06Z", - "updated_at": "2023-02-26T21:53:06Z", - "additional_information": "user_12" + "created_at": "2023-07-10T20:54:29Z", + "updated_at": "2023-07-10T20:54:29Z", + "additional_information": "user_13" }, { - "id": "a76ldek4tcny3fggu3u7cq456u", - "title": "Example Login Item 23", + "id": "rhe6yevalei4fvcgkzdzgx5ihm", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -485,13 +485,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:21Z", - "updated_at": "2023-02-26T21:53:21Z", - "additional_information": "user_23" + "created_at": "2023-07-10T20:54:30Z", + "updated_at": "2023-07-10T20:54:30Z", + "additional_information": "user_14" }, { - "id": "rgc4nh6iekiye7cqdi2mfhpqpa", - "title": "Example Login Item 11", + "id": "fh7byzemtipjjmb65irgewmlwq", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -499,13 +499,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:05Z", - "updated_at": "2023-02-26T21:53:05Z", - "additional_information": "user_11" + "created_at": "2023-07-10T20:54:48Z", + "updated_at": "2023-07-10T20:54:48Z", + "additional_information": "user_30" }, { - "id": "shybm7klvq3wkek3fxwuakyk5i", - "title": "Example Login Item 13", + "id": "6cdyz752d4i4qmoenn4hhn5qaa", + "title": "Example Login Item 05", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -513,8 +513,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:07Z", - "updated_at": "2023-02-26T21:53:07Z", - "additional_information": "user_13" + "created_at": "2023-07-10T20:54:19Z", + "updated_at": "2023-07-10T20:54:19Z", + "additional_information": "user_05" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3/output b/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3/output index 7feb3df6..90289566 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-3/item-list-test-data-3/output @@ -1,7 +1,7 @@ [ { - "id": "ioskuz642omqnvrq6tqknqghg4", - "title": "Example Login Item 03", + "id": "3csk5dtmupjjuph5durmxgpvvq", + "title": "Example Login Item 36", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -9,13 +9,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:56Z", - "updated_at": "2023-02-26T21:52:56Z", - "additional_information": "user_03" + "created_at": "2023-07-10T20:54:54Z", + "updated_at": "2023-07-10T20:54:54Z", + "additional_information": "user_36" }, { - "id": "rczlhdg7pum7wrhrf7euoeyatu", - "title": "Example Login Item 36", + "id": "irpmzvyube7obnjz37s4nhyhf4", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -23,13 +23,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:37Z", - "updated_at": "2023-02-26T21:53:37Z", - "additional_information": "user_36" + "created_at": "2023-07-10T20:54:34Z", + "updated_at": "2023-07-10T20:54:34Z", + "additional_information": "user_17" }, { - "id": "tkofaqsvxmpfdkvvzeftlw4a3e", - "title": "Example Login Item 01", + "id": "radxxrqumaqtnvqozslekl6nhy", + "title": "Example Login Item 00", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -37,13 +37,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:54Z", - "updated_at": "2023-02-26T21:52:54Z", - "additional_information": "user_01" + "created_at": "2023-07-10T20:54:14Z", + "updated_at": "2023-07-10T20:54:14Z", + "additional_information": "user_00" }, { - "id": "x2b52i4kzkumd6r3mbko3ordwy", - "title": "Example Login Item 04", + "id": "xteh3aypnin5nopio67vywhg4q", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -51,13 +51,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:57Z", - "updated_at": "2023-02-26T21:52:57Z", - "additional_information": "user_04" + "created_at": "2023-07-10T20:54:35Z", + "updated_at": "2023-07-10T20:54:35Z", + "additional_information": "user_18" }, { - "id": "5h3qe4bqekt4ugxkobdha2fsli", - "title": "Example Login Item 29", + "id": "b35tdije6oiozyogleflhhwhwy", + "title": "Example Login Item 01", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -65,13 +65,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:28Z", - "updated_at": "2023-02-26T21:53:28Z", - "additional_information": "user_29" + "created_at": "2023-07-10T20:54:15Z", + "updated_at": "2023-07-10T20:54:15Z", + "additional_information": "user_01" }, { - "id": "ddqvqxnlbobjaaijpf5nmp2iiq", - "title": "Example Login Item 00", + "id": "a3yqf7j2zv63oevqyx7f5ny5wy", + "title": "Example Login Item 02", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -79,13 +79,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:53Z", - "updated_at": "2023-02-26T21:52:53Z", - "additional_information": "user_00" + "created_at": "2023-07-10T20:54:16Z", + "updated_at": "2023-07-10T20:54:16Z", + "additional_information": "user_02" }, { - "id": "6hlvskty5s72ljkn333iy445wi", - "title": "Example Login Item 28", + "id": "m7jprtjz3v3zkxx4sgm5fh5ske", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -93,13 +93,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:27Z", - "updated_at": "2023-02-26T21:53:27Z", - "additional_information": "user_28" + "created_at": "2023-07-10T20:54:37Z", + "updated_at": "2023-07-10T20:54:37Z", + "additional_information": "user_19" }, { - "id": "jhckzqn275tslogsidxcby3qwi", - "title": "Example Login Item 30", + "id": "vtb5xljhrjfe42tzqchi3qrnpy", + "title": "Example Login Item 03", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -107,13 +107,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:29Z", - "updated_at": "2023-02-26T21:53:29Z", - "additional_information": "user_30" + "created_at": "2023-07-10T20:54:17Z", + "updated_at": "2023-07-10T20:54:17Z", + "additional_information": "user_03" }, { - "id": "lsujgnao5vw4lrjuhqoiovaxnq", - "title": "Example Login Item 21", + "id": "aa3myi6s2xqobqrw3o4zhkcwru", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -121,13 +121,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:17Z", - "updated_at": "2023-02-26T21:53:17Z", - "additional_information": "user_21" + "created_at": "2023-07-10T20:54:38Z", + "updated_at": "2023-07-10T20:54:38Z", + "additional_information": "user_20" }, { - "id": "gpzd5x33hnfgom4a6tv4ef42me", - "title": "Example Login Item 31", + "id": "3bxulcvnt2afmuuc5rrfd3t3su", + "title": "Example Login Item 04", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -135,13 +135,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:30Z", - "updated_at": "2023-02-26T21:53:30Z", - "additional_information": "user_31" + "created_at": "2023-07-10T20:54:18Z", + "updated_at": "2023-07-10T20:54:18Z", + "additional_information": "user_04" }, { - "id": "2gxm222kpezqumb5ib57hk24ny", - "title": "Example Login Item 22", + "id": "fexqrzfidz53w4jzn7cveprqsy", + "title": "Example Login Item 21", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -149,13 +149,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:18Z", - "updated_at": "2023-02-26T21:53:18Z", - "additional_information": "user_22" + "created_at": "2023-07-10T20:54:39Z", + "updated_at": "2023-07-10T20:54:39Z", + "additional_information": "user_21" }, { - "id": "biugqc2uuuehj355seh6ej7moy", - "title": "Example Login Item 32", + "id": "dwfs73h3uvazlqv6s5lpcqwcpu", + "title": "Example Login Item 22", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -163,13 +163,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:32Z", - "updated_at": "2023-02-26T21:53:32Z", - "additional_information": "user_32" + "created_at": "2023-07-10T20:54:40Z", + "updated_at": "2023-07-10T20:54:40Z", + "additional_information": "user_22" }, { - "id": "v4edzqxgzcquq2ru4kihrzhowy", - "title": "Example Login Item 12", + "id": "ijkrebl72abwl2w32fx53c56km", + "title": "Example Login Item 23", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -177,13 +177,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:06Z", - "updated_at": "2023-02-26T21:53:06Z", - "additional_information": "user_12" + "created_at": "2023-07-10T20:54:41Z", + "updated_at": "2023-07-10T20:54:41Z", + "additional_information": "user_23" }, { - "id": "a76ldek4tcny3fggu3u7cq456u", - "title": "Example Login Item 23", + "id": "6cdyz752d4i4qmoenn4hhn5qaa", + "title": "Example Login Item 05", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -191,13 +191,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:21Z", - "updated_at": "2023-02-26T21:53:21Z", - "additional_information": "user_23" + "created_at": "2023-07-10T20:54:19Z", + "updated_at": "2023-07-10T20:54:19Z", + "additional_information": "user_05" }, { - "id": "xeaybnnl3tvisws5jvwcwpsvey", - "title": "Example Login Item 33", + "id": "vbvaznvghvau55d4hfalcqcg2u", + "title": "Example Login Item 24", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:33Z", - "updated_at": "2023-02-26T21:53:33Z", - "additional_information": "user_33" + "created_at": "2023-07-10T20:54:42Z", + "updated_at": "2023-07-10T20:54:42Z", + "additional_information": "user_24" }, { - "id": "we5iwz2cqhf73y3bzrcfvzcz2m", - "title": "Example Login Item 09", + "id": "ltgvl3h7j6o6qk6bkyabxc2dbm", + "title": "Example Login Item 25", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -219,13 +219,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:02Z", - "updated_at": "2023-02-26T21:53:02Z", - "additional_information": "user_09" + "created_at": "2023-07-10T20:54:43Z", + "updated_at": "2023-07-10T20:54:43Z", + "additional_information": "user_25" }, { - "id": "zz655vi3xlv2alllq7cjlyrxyu", - "title": "Example Login Item 24", + "id": "setr26pmay3wwsmmtyqnop43ru", + "title": "Example Login Item 06", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -233,13 +233,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:22Z", - "updated_at": "2023-02-26T21:53:22Z", - "additional_information": "user_24" + "created_at": "2023-07-10T20:54:20Z", + "updated_at": "2023-07-10T20:54:20Z", + "additional_information": "user_06" }, { - "id": "5wmqz5qe24km7fmgttklkx7p5a", - "title": "Example Login Item 20", + "id": "5m5ezfrtkzbyzkngiy3nb3xzdq", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -247,13 +247,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:16Z", - "updated_at": "2023-02-26T21:53:16Z", - "additional_information": "user_20" + "created_at": "2023-07-10T20:54:44Z", + "updated_at": "2023-07-10T20:54:44Z", + "additional_information": "user_26" }, { - "id": "pqmb32ew7sirfqkrlgpehcd6gm", - "title": "Example Login Item 34", + "id": "z6kmzdaj64wyzq7yuuqjaubimm", + "title": "Example Login Item 07", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -261,13 +261,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:35Z", - "updated_at": "2023-02-26T21:53:35Z", - "additional_information": "user_34" + "created_at": "2023-07-10T20:54:21Z", + "updated_at": "2023-07-10T20:54:21Z", + "additional_information": "user_07" }, { - "id": "zayggylnibccqhvzmv3hgrgy4u", - "title": "Example Login Item 27", + "id": "ofcl4plyaa63y2qkesp3vtmohi", + "title": "Example Login Item 08", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -275,13 +275,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:26Z", - "updated_at": "2023-02-26T21:53:26Z", - "additional_information": "user_27" + "created_at": "2023-07-10T20:54:23Z", + "updated_at": "2023-07-10T20:54:23Z", + "additional_information": "user_08" }, { - "id": "ry46ke2h3hmg6ukkfbkwgzgk4a", - "title": "Example Login Item 02", + "id": "o3vbuksseuhovpmizkgvlut7ma", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -289,13 +289,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:55Z", - "updated_at": "2023-02-26T21:52:55Z", - "additional_information": "user_02" + "created_at": "2023-07-10T20:54:29Z", + "updated_at": "2023-07-10T20:54:29Z", + "additional_information": "user_13" }, { - "id": "eibsbn332mmexisxv73gt6ifky", - "title": "Example Login Item 10", + "id": "y6j7bbkqbbqubjcmtjnnu5jycu", + "title": "Example Login Item 12", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -303,13 +303,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:03Z", - "updated_at": "2023-02-26T21:53:03Z", - "additional_information": "user_10" + "created_at": "2023-07-10T20:54:28Z", + "updated_at": "2023-07-10T20:54:28Z", + "additional_information": "user_12" }, { - "id": "shybm7klvq3wkek3fxwuakyk5i", - "title": "Example Login Item 13", + "id": "rhe6yevalei4fvcgkzdzgx5ihm", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -317,13 +317,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:07Z", - "updated_at": "2023-02-26T21:53:07Z", - "additional_information": "user_13" + "created_at": "2023-07-10T20:54:30Z", + "updated_at": "2023-07-10T20:54:30Z", + "additional_information": "user_14" }, { - "id": "bmqdjbf54c7zor4jfnfdal7nva", - "title": "Example Login Item 35", + "id": "rm6dpqwxh7huf62a4un4rbp7ki", + "title": "Example Login Item 27", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -331,13 +331,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:36Z", - "updated_at": "2023-02-26T21:53:36Z", - "additional_information": "user_35" + "created_at": "2023-07-10T20:54:45Z", + "updated_at": "2023-07-10T20:54:45Z", + "additional_information": "user_27" }, { - "id": "rgc4nh6iekiye7cqdi2mfhpqpa", - "title": "Example Login Item 11", + "id": "r2vmvbmc3akdnmuuxlbfxzbu3y", + "title": "Example Login Item 09", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -345,13 +345,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:05Z", - "updated_at": "2023-02-26T21:53:05Z", - "additional_information": "user_11" + "created_at": "2023-07-10T20:54:24Z", + "updated_at": "2023-07-10T20:54:24Z", + "additional_information": "user_09" }, { - "id": "yz7he5wzrjib3k3weha3ucrztu", - "title": "Example Login Item 14", + "id": "qez2yursmmkx5yqb5rgpwomblm", + "title": "Example Login Item 15", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -359,13 +359,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:08Z", - "updated_at": "2023-02-26T21:53:08Z", - "additional_information": "user_14" + "created_at": "2023-07-10T20:54:32Z", + "updated_at": "2023-07-10T20:54:32Z", + "additional_information": "user_15" }, { - "id": "6br5ex37daswo5xzdbi6chkjlu", - "title": "Example Login Item 18", + "id": "i2c3us2sfq6gbh2u5n46hca7he", + "title": "Example Login Item 11", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -373,13 +373,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:13Z", - "updated_at": "2023-02-26T21:53:13Z", - "additional_information": "user_18" + "created_at": "2023-07-10T20:54:27Z", + "updated_at": "2023-07-10T20:54:27Z", + "additional_information": "user_11" }, { - "id": "6bcqblmxbrsisisb2eupjq7avm", - "title": "Example Login Item 25", + "id": "7huqr4d5mvpmjov6aa2kl4wcnq", + "title": "Example Login Item 34", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -387,13 +387,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:23Z", - "updated_at": "2023-02-26T21:53:23Z", - "additional_information": "user_25" + "created_at": "2023-07-10T20:54:52Z", + "updated_at": "2023-07-10T20:54:52Z", + "additional_information": "user_34" }, { - "id": "kzpfqniu26tatmtzgk2wu377oe", - "title": "Example Login Item 19", + "id": "wviqh7wfazdguizm3xm5ydfrvu", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -401,13 +401,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:14Z", - "updated_at": "2023-02-26T21:53:14Z", - "additional_information": "user_19" + "created_at": "2023-07-10T20:54:33Z", + "updated_at": "2023-07-10T20:54:33Z", + "additional_information": "user_16" }, { - "id": "tzxbkgrpxjk47z52fvgpmfaoe4", - "title": "Example Login Item 07", + "id": "koo45d6jts4pkuck2n5aordmny", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:00Z", - "updated_at": "2023-02-26T21:53:00Z", - "additional_information": "user_07" + "created_at": "2023-07-10T20:54:51Z", + "updated_at": "2023-07-10T20:54:51Z", + "additional_information": "user_33" }, { - "id": "ps2fpw422sjzfgmmibbh2ryp54", - "title": "Example Login Item 15", + "id": "kib7zokx5oyeizss5pdci5b6p4", + "title": "Example Login Item 35", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -429,13 +429,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:09Z", - "updated_at": "2023-02-26T21:53:09Z", - "additional_information": "user_15" + "created_at": "2023-07-10T20:54:53Z", + "updated_at": "2023-07-10T20:54:53Z", + "additional_information": "user_35" }, { - "id": "umsfsqt3pd7oms46lsgcdfkoeq", - "title": "Example Login Item 16", + "id": "daukcdlqtkrqqwqcz7alkoa6em", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -443,13 +443,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:10Z", - "updated_at": "2023-02-26T21:53:10Z", - "additional_information": "user_16" + "created_at": "2023-07-10T20:54:49Z", + "updated_at": "2023-07-10T20:54:49Z", + "additional_information": "user_31" }, { - "id": "6zh4myb3d6rwtv3hfhg6qp2ncm", - "title": "Example Login Item 06", + "id": "qtfbp6zwnhwxmirbpziekhuf7y", + "title": "Example Login Item 29", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -457,13 +457,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:59Z", - "updated_at": "2023-02-26T21:52:59Z", - "additional_information": "user_06" + "created_at": "2023-07-10T20:54:47Z", + "updated_at": "2023-07-10T20:54:47Z", + "additional_information": "user_29" }, { - "id": "wtvxlb5cml5ihumatxubfo5quq", - "title": "Example Login Item 08", + "id": "3aqwi56gkv2wonw5w35naruroa", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -471,13 +471,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:01Z", - "updated_at": "2023-02-26T21:53:01Z", - "additional_information": "user_08" + "created_at": "2023-07-10T20:54:46Z", + "updated_at": "2023-07-10T20:54:46Z", + "additional_information": "user_28" }, { - "id": "bu4pinbfu72ze2rbh2ekhu47jy", - "title": "Example Login Item 05", + "id": "fh7byzemtipjjmb65irgewmlwq", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -485,13 +485,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:58Z", - "updated_at": "2023-02-26T21:52:58Z", - "additional_information": "user_05" + "created_at": "2023-07-10T20:54:48Z", + "updated_at": "2023-07-10T20:54:48Z", + "additional_information": "user_30" }, { - "id": "p35gttx2rad2tr5ah7mwesj7ea", - "title": "Example Login Item 26", + "id": "bk3vqleti5rk5yvgk2iyl7r4ue", + "title": "Example Login Item 32", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -499,13 +499,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:24Z", - "updated_at": "2023-02-26T21:53:24Z", - "additional_information": "user_26" + "created_at": "2023-07-10T20:54:50Z", + "updated_at": "2023-07-10T20:54:50Z", + "additional_information": "user_32" }, { - "id": "fazkwyxnaownqxgenf67btguwy", - "title": "Example Login Item 17", + "id": "kb7vgcvv3qyjkvbhm6em2f6hzy", + "title": "Example Login Item 10", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -513,8 +513,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:12Z", - "updated_at": "2023-02-26T21:53:12Z", - "additional_information": "user_17" + "created_at": "2023-07-10T20:54:25Z", + "updated_at": "2023-07-10T20:54:25Z", + "additional_information": "user_10" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-3/list-signed-in-accounts/output b/tests/config/mock-op/responses-item-delete-multiple/responses-3/list-signed-in-accounts/output index f5134399..0f19f028 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-3/list-signed-in-accounts/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-3/list-signed-in-accounts/output @@ -1,4 +1,10 @@ [ + { + "url": "pyonepassword.1password.com", + "email": "uid000@gmail.com", + "user_uuid": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57" + }, { "url": "example-account.1password.com", "email": "example_user@example.email", diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-4/cli-version/output b/tests/config/mock-op/responses-item-delete-multiple/responses-4/cli-version/output index edcfe40d..c22d404b 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-4/cli-version/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-4/cli-version/output @@ -1 +1 @@ -2.14.0 +2.19.0-beta.01 diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-alt-title-glob/output b/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-alt-title-glob/output index 6a675eac..8e547970 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-alt-title-glob/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-alt-title-glob/output @@ -1,7 +1,7 @@ [ { - "id": "eibsbn332mmexisxv73gt6ifky", - "title": "Example Login Item 10", + "id": "3csk5dtmupjjuph5durmxgpvvq", + "title": "Example Login Item 36", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -9,13 +9,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:03Z", - "updated_at": "2023-02-26T21:53:03Z", - "additional_information": "user_10" + "created_at": "2023-07-10T20:54:54Z", + "updated_at": "2023-07-10T20:54:54Z", + "additional_information": "user_36" }, { - "id": "5h3qe4bqekt4ugxkobdha2fsli", - "title": "Example Login Item 29", + "id": "3bxulcvnt2afmuuc5rrfd3t3su", + "title": "Example Login Item 04", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -23,13 +23,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:28Z", - "updated_at": "2023-02-26T21:53:28Z", - "additional_information": "user_29" + "created_at": "2023-07-10T20:54:18Z", + "updated_at": "2023-07-10T20:54:18Z", + "additional_information": "user_04" }, { - "id": "tzxbkgrpxjk47z52fvgpmfaoe4", - "title": "Example Login Item 07", + "id": "6cdyz752d4i4qmoenn4hhn5qaa", + "title": "Example Login Item 05", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -37,13 +37,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:00Z", - "updated_at": "2023-02-26T21:53:00Z", - "additional_information": "user_07" + "created_at": "2023-07-10T20:54:19Z", + "updated_at": "2023-07-10T20:54:19Z", + "additional_information": "user_05" }, { - "id": "a76ldek4tcny3fggu3u7cq456u", - "title": "Example Login Item 23", + "id": "vtb5xljhrjfe42tzqchi3qrnpy", + "title": "Example Login Item 03", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -51,13 +51,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:21Z", - "updated_at": "2023-02-26T21:53:21Z", - "additional_information": "user_23" + "created_at": "2023-07-10T20:54:17Z", + "updated_at": "2023-07-10T20:54:17Z", + "additional_information": "user_03" }, { - "id": "rczlhdg7pum7wrhrf7euoeyatu", - "title": "Example Login Item 36", + "id": "setr26pmay3wwsmmtyqnop43ru", + "title": "Example Login Item 06", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -65,13 +65,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:37Z", - "updated_at": "2023-02-26T21:53:37Z", - "additional_information": "user_36" + "created_at": "2023-07-10T20:54:20Z", + "updated_at": "2023-07-10T20:54:20Z", + "additional_information": "user_06" }, { - "id": "6zh4myb3d6rwtv3hfhg6qp2ncm", - "title": "Example Login Item 06", + "id": "fexqrzfidz53w4jzn7cveprqsy", + "title": "Example Login Item 21", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -79,13 +79,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:59Z", - "updated_at": "2023-02-26T21:52:59Z", - "additional_information": "user_06" + "created_at": "2023-07-10T20:54:39Z", + "updated_at": "2023-07-10T20:54:39Z", + "additional_information": "user_21" }, { - "id": "shybm7klvq3wkek3fxwuakyk5i", - "title": "Example Login Item 13", + "id": "b35tdije6oiozyogleflhhwhwy", + "title": "Example Login Item 01", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -93,13 +93,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:07Z", - "updated_at": "2023-02-26T21:53:07Z", - "additional_information": "user_13" + "created_at": "2023-07-10T20:54:15Z", + "updated_at": "2023-07-10T20:54:15Z", + "additional_information": "user_01" }, { - "id": "zz655vi3xlv2alllq7cjlyrxyu", - "title": "Example Login Item 24", + "id": "ijkrebl72abwl2w32fx53c56km", + "title": "Example Login Item 23", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -107,13 +107,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:22Z", - "updated_at": "2023-02-26T21:53:22Z", - "additional_information": "user_24" + "created_at": "2023-07-10T20:54:41Z", + "updated_at": "2023-07-10T20:54:41Z", + "additional_information": "user_23" }, { - "id": "rgc4nh6iekiye7cqdi2mfhpqpa", - "title": "Example Login Item 11", + "id": "vbvaznvghvau55d4hfalcqcg2u", + "title": "Example Login Item 24", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -121,13 +121,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:05Z", - "updated_at": "2023-02-26T21:53:05Z", - "additional_information": "user_11" + "created_at": "2023-07-10T20:54:42Z", + "updated_at": "2023-07-10T20:54:42Z", + "additional_information": "user_24" }, { - "id": "jhckzqn275tslogsidxcby3qwi", - "title": "Example Login Item 30", + "id": "ltgvl3h7j6o6qk6bkyabxc2dbm", + "title": "Example Login Item 25", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -135,13 +135,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:29Z", - "updated_at": "2023-02-26T21:53:29Z", - "additional_information": "user_30" + "created_at": "2023-07-10T20:54:43Z", + "updated_at": "2023-07-10T20:54:43Z", + "additional_information": "user_25" }, { - "id": "we5iwz2cqhf73y3bzrcfvzcz2m", - "title": "Example Login Item 09", + "id": "5m5ezfrtkzbyzkngiy3nb3xzdq", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -149,13 +149,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:02Z", - "updated_at": "2023-02-26T21:53:02Z", - "additional_information": "user_09" + "created_at": "2023-07-10T20:54:44Z", + "updated_at": "2023-07-10T20:54:44Z", + "additional_information": "user_26" }, { - "id": "yz7he5wzrjib3k3weha3ucrztu", - "title": "Example Login Item 14", + "id": "rm6dpqwxh7huf62a4un4rbp7ki", + "title": "Example Login Item 27", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -163,13 +163,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:08Z", - "updated_at": "2023-02-26T21:53:08Z", - "additional_information": "user_14" + "created_at": "2023-07-10T20:54:45Z", + "updated_at": "2023-07-10T20:54:45Z", + "additional_information": "user_27" }, { - "id": "6bcqblmxbrsisisb2eupjq7avm", - "title": "Example Login Item 25", + "id": "radxxrqumaqtnvqozslekl6nhy", + "title": "Example Login Item 00", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -177,13 +177,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:23Z", - "updated_at": "2023-02-26T21:53:23Z", - "additional_information": "user_25" + "created_at": "2023-07-10T20:54:14Z", + "updated_at": "2023-07-10T20:54:14Z", + "additional_information": "user_00" }, { - "id": "ioskuz642omqnvrq6tqknqghg4", - "title": "Example Login Item 03", + "id": "3aqwi56gkv2wonw5w35naruroa", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -191,13 +191,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:56Z", - "updated_at": "2023-02-26T21:52:56Z", - "additional_information": "user_03" + "created_at": "2023-07-10T20:54:46Z", + "updated_at": "2023-07-10T20:54:46Z", + "additional_information": "user_28" }, { - "id": "gpzd5x33hnfgom4a6tv4ef42me", - "title": "Example Login Item 31", + "id": "qtfbp6zwnhwxmirbpziekhuf7y", + "title": "Example Login Item 29", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:30Z", - "updated_at": "2023-02-26T21:53:30Z", - "additional_information": "user_31" + "created_at": "2023-07-10T20:54:47Z", + "updated_at": "2023-07-10T20:54:47Z", + "additional_information": "user_29" }, { - "id": "pqmb32ew7sirfqkrlgpehcd6gm", - "title": "Example Login Item 34", + "id": "fh7byzemtipjjmb65irgewmlwq", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -219,13 +219,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:35Z", - "updated_at": "2023-02-26T21:53:35Z", - "additional_information": "user_34" + "created_at": "2023-07-10T20:54:48Z", + "updated_at": "2023-07-10T20:54:48Z", + "additional_information": "user_30" }, { - "id": "ps2fpw422sjzfgmmibbh2ryp54", - "title": "Example Login Item 15", + "id": "daukcdlqtkrqqwqcz7alkoa6em", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -233,13 +233,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:09Z", - "updated_at": "2023-02-26T21:53:09Z", - "additional_information": "user_15" + "created_at": "2023-07-10T20:54:49Z", + "updated_at": "2023-07-10T20:54:49Z", + "additional_information": "user_31" }, { - "id": "tkofaqsvxmpfdkvvzeftlw4a3e", - "title": "Example Login Item 01", + "id": "r2vmvbmc3akdnmuuxlbfxzbu3y", + "title": "Example Login Item 09", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -247,13 +247,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:54Z", - "updated_at": "2023-02-26T21:52:54Z", - "additional_information": "user_01" + "created_at": "2023-07-10T20:54:24Z", + "updated_at": "2023-07-10T20:54:24Z", + "additional_information": "user_09" }, { - "id": "p35gttx2rad2tr5ah7mwesj7ea", - "title": "Example Login Item 26", + "id": "aa3myi6s2xqobqrw3o4zhkcwru", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -261,13 +261,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:24Z", - "updated_at": "2023-02-26T21:53:24Z", - "additional_information": "user_26" + "created_at": "2023-07-10T20:54:38Z", + "updated_at": "2023-07-10T20:54:38Z", + "additional_information": "user_20" }, { - "id": "bmqdjbf54c7zor4jfnfdal7nva", - "title": "Example Login Item 35", + "id": "koo45d6jts4pkuck2n5aordmny", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -275,13 +275,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:36Z", - "updated_at": "2023-02-26T21:53:36Z", - "additional_information": "user_35" + "created_at": "2023-07-10T20:54:51Z", + "updated_at": "2023-07-10T20:54:51Z", + "additional_information": "user_33" }, { - "id": "xeaybnnl3tvisws5jvwcwpsvey", - "title": "Example Login Item 33", + "id": "kib7zokx5oyeizss5pdci5b6p4", + "title": "Example Login Item 35", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -289,13 +289,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:33Z", - "updated_at": "2023-02-26T21:53:33Z", - "additional_information": "user_33" + "created_at": "2023-07-10T20:54:53Z", + "updated_at": "2023-07-10T20:54:53Z", + "additional_information": "user_35" }, { - "id": "umsfsqt3pd7oms46lsgcdfkoeq", - "title": "Example Login Item 16", + "id": "z6kmzdaj64wyzq7yuuqjaubimm", + "title": "Example Login Item 07", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -303,13 +303,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:10Z", - "updated_at": "2023-02-26T21:53:10Z", - "additional_information": "user_16" + "created_at": "2023-07-10T20:54:21Z", + "updated_at": "2023-07-10T20:54:21Z", + "additional_information": "user_07" }, { - "id": "ddqvqxnlbobjaaijpf5nmp2iiq", - "title": "Example Login Item 00", + "id": "7huqr4d5mvpmjov6aa2kl4wcnq", + "title": "Example Login Item 34", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -317,13 +317,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:53Z", - "updated_at": "2023-02-26T21:52:53Z", - "additional_information": "user_00" + "created_at": "2023-07-10T20:54:52Z", + "updated_at": "2023-07-10T20:54:52Z", + "additional_information": "user_34" }, { - "id": "zayggylnibccqhvzmv3hgrgy4u", - "title": "Example Login Item 27", + "id": "rhe6yevalei4fvcgkzdzgx5ihm", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -331,13 +331,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:26Z", - "updated_at": "2023-02-26T21:53:26Z", - "additional_information": "user_27" + "created_at": "2023-07-10T20:54:30Z", + "updated_at": "2023-07-10T20:54:30Z", + "additional_information": "user_14" }, { - "id": "6hlvskty5s72ljkn333iy445wi", - "title": "Example Login Item 28", + "id": "kb7vgcvv3qyjkvbhm6em2f6hzy", + "title": "Example Login Item 10", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -345,13 +345,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:27Z", - "updated_at": "2023-02-26T21:53:27Z", - "additional_information": "user_28" + "created_at": "2023-07-10T20:54:25Z", + "updated_at": "2023-07-10T20:54:25Z", + "additional_information": "user_10" }, { - "id": "kzpfqniu26tatmtzgk2wu377oe", - "title": "Example Login Item 19", + "id": "irpmzvyube7obnjz37s4nhyhf4", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -359,13 +359,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:14Z", - "updated_at": "2023-02-26T21:53:14Z", - "additional_information": "user_19" + "created_at": "2023-07-10T20:54:34Z", + "updated_at": "2023-07-10T20:54:34Z", + "additional_information": "user_17" }, { - "id": "fazkwyxnaownqxgenf67btguwy", - "title": "Example Login Item 17", + "id": "wviqh7wfazdguizm3xm5ydfrvu", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -373,13 +373,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:12Z", - "updated_at": "2023-02-26T21:53:12Z", - "additional_information": "user_17" + "created_at": "2023-07-10T20:54:33Z", + "updated_at": "2023-07-10T20:54:33Z", + "additional_information": "user_16" }, { - "id": "5wmqz5qe24km7fmgttklkx7p5a", - "title": "Example Login Item 20", + "id": "i2c3us2sfq6gbh2u5n46hca7he", + "title": "Example Login Item 11", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -387,13 +387,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:16Z", - "updated_at": "2023-02-26T21:53:16Z", - "additional_information": "user_20" + "created_at": "2023-07-10T20:54:27Z", + "updated_at": "2023-07-10T20:54:27Z", + "additional_information": "user_11" }, { - "id": "6br5ex37daswo5xzdbi6chkjlu", - "title": "Example Login Item 18", + "id": "ofcl4plyaa63y2qkesp3vtmohi", + "title": "Example Login Item 08", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -401,13 +401,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:13Z", - "updated_at": "2023-02-26T21:53:13Z", - "additional_information": "user_18" + "created_at": "2023-07-10T20:54:23Z", + "updated_at": "2023-07-10T20:54:23Z", + "additional_information": "user_08" }, { - "id": "x2b52i4kzkumd6r3mbko3ordwy", - "title": "Example Login Item 04", + "id": "m7jprtjz3v3zkxx4sgm5fh5ske", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:57Z", - "updated_at": "2023-02-26T21:52:57Z", - "additional_information": "user_04" + "created_at": "2023-07-10T20:54:37Z", + "updated_at": "2023-07-10T20:54:37Z", + "additional_information": "user_19" }, { - "id": "lsujgnao5vw4lrjuhqoiovaxnq", - "title": "Example Login Item 21", + "id": "qez2yursmmkx5yqb5rgpwomblm", + "title": "Example Login Item 15", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -429,13 +429,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:17Z", - "updated_at": "2023-02-26T21:53:17Z", - "additional_information": "user_21" + "created_at": "2023-07-10T20:54:32Z", + "updated_at": "2023-07-10T20:54:32Z", + "additional_information": "user_15" }, { - "id": "bu4pinbfu72ze2rbh2ekhu47jy", - "title": "Example Login Item 05", + "id": "o3vbuksseuhovpmizkgvlut7ma", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -443,13 +443,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:58Z", - "updated_at": "2023-02-26T21:52:58Z", - "additional_information": "user_05" + "created_at": "2023-07-10T20:54:29Z", + "updated_at": "2023-07-10T20:54:29Z", + "additional_information": "user_13" }, { - "id": "wtvxlb5cml5ihumatxubfo5quq", - "title": "Example Login Item 08", + "id": "xteh3aypnin5nopio67vywhg4q", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -457,8 +457,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:01Z", - "updated_at": "2023-02-26T21:53:01Z", - "additional_information": "user_08" + "created_at": "2023-07-10T20:54:35Z", + "updated_at": "2023-07-10T20:54:35Z", + "additional_information": "user_18" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-title-glob/output b/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-title-glob/output index 372e61bf..2f2a906d 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-title-glob/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3-title-glob/output @@ -1,6 +1,6 @@ [ { - "id": "rczlhdg7pum7wrhrf7euoeyatu", + "id": "3csk5dtmupjjuph5durmxgpvvq", "title": "Example Login Item 36", "version": 1, "vault": { @@ -9,13 +9,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:37Z", - "updated_at": "2023-02-26T21:53:37Z", + "created_at": "2023-07-10T20:54:54Z", + "updated_at": "2023-07-10T20:54:54Z", "additional_information": "user_36" }, { - "id": "eibsbn332mmexisxv73gt6ifky", - "title": "Example Login Item 10", + "id": "z6kmzdaj64wyzq7yuuqjaubimm", + "title": "Example Login Item 07", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -23,13 +23,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:03Z", - "updated_at": "2023-02-26T21:53:03Z", - "additional_information": "user_10" + "created_at": "2023-07-10T20:54:21Z", + "updated_at": "2023-07-10T20:54:21Z", + "additional_information": "user_07" }, { - "id": "ddqvqxnlbobjaaijpf5nmp2iiq", - "title": "Example Login Item 00", + "id": "setr26pmay3wwsmmtyqnop43ru", + "title": "Example Login Item 06", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -37,13 +37,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:53Z", - "updated_at": "2023-02-26T21:52:53Z", - "additional_information": "user_00" + "created_at": "2023-07-10T20:54:20Z", + "updated_at": "2023-07-10T20:54:20Z", + "additional_information": "user_06" }, { - "id": "we5iwz2cqhf73y3bzrcfvzcz2m", - "title": "Example Login Item 09", + "id": "fexqrzfidz53w4jzn7cveprqsy", + "title": "Example Login Item 21", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -51,13 +51,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:02Z", - "updated_at": "2023-02-26T21:53:02Z", - "additional_information": "user_09" + "created_at": "2023-07-10T20:54:39Z", + "updated_at": "2023-07-10T20:54:39Z", + "additional_information": "user_21" }, { - "id": "wtvxlb5cml5ihumatxubfo5quq", - "title": "Example Login Item 08", + "id": "ijkrebl72abwl2w32fx53c56km", + "title": "Example Login Item 23", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -65,13 +65,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:01Z", - "updated_at": "2023-02-26T21:53:01Z", - "additional_information": "user_08" + "created_at": "2023-07-10T20:54:41Z", + "updated_at": "2023-07-10T20:54:41Z", + "additional_information": "user_23" }, { - "id": "rgc4nh6iekiye7cqdi2mfhpqpa", - "title": "Example Login Item 11", + "id": "ofcl4plyaa63y2qkesp3vtmohi", + "title": "Example Login Item 08", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -79,13 +79,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:05Z", - "updated_at": "2023-02-26T21:53:05Z", - "additional_information": "user_11" + "created_at": "2023-07-10T20:54:23Z", + "updated_at": "2023-07-10T20:54:23Z", + "additional_information": "user_08" }, { - "id": "tzxbkgrpxjk47z52fvgpmfaoe4", - "title": "Example Login Item 07", + "id": "vbvaznvghvau55d4hfalcqcg2u", + "title": "Example Login Item 24", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -93,13 +93,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:00Z", - "updated_at": "2023-02-26T21:53:00Z", - "additional_information": "user_07" + "created_at": "2023-07-10T20:54:42Z", + "updated_at": "2023-07-10T20:54:42Z", + "additional_information": "user_24" }, { - "id": "bu4pinbfu72ze2rbh2ekhu47jy", - "title": "Example Login Item 05", + "id": "ltgvl3h7j6o6qk6bkyabxc2dbm", + "title": "Example Login Item 25", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -107,13 +107,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:58Z", - "updated_at": "2023-02-26T21:52:58Z", - "additional_information": "user_05" + "created_at": "2023-07-10T20:54:43Z", + "updated_at": "2023-07-10T20:54:43Z", + "additional_information": "user_25" }, { - "id": "x2b52i4kzkumd6r3mbko3ordwy", - "title": "Example Login Item 04", + "id": "5m5ezfrtkzbyzkngiy3nb3xzdq", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -121,13 +121,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:57Z", - "updated_at": "2023-02-26T21:52:57Z", - "additional_information": "user_04" + "created_at": "2023-07-10T20:54:44Z", + "updated_at": "2023-07-10T20:54:44Z", + "additional_information": "user_26" }, { - "id": "fazkwyxnaownqxgenf67btguwy", - "title": "Example Login Item 17", + "id": "r2vmvbmc3akdnmuuxlbfxzbu3y", + "title": "Example Login Item 09", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -135,13 +135,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:12Z", - "updated_at": "2023-02-26T21:53:12Z", - "additional_information": "user_17" + "created_at": "2023-07-10T20:54:24Z", + "updated_at": "2023-07-10T20:54:24Z", + "additional_information": "user_09" }, { - "id": "zz655vi3xlv2alllq7cjlyrxyu", - "title": "Example Login Item 24", + "id": "rm6dpqwxh7huf62a4un4rbp7ki", + "title": "Example Login Item 27", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -149,13 +149,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:22Z", - "updated_at": "2023-02-26T21:53:22Z", - "additional_information": "user_24" + "created_at": "2023-07-10T20:54:45Z", + "updated_at": "2023-07-10T20:54:45Z", + "additional_information": "user_27" }, { - "id": "tkofaqsvxmpfdkvvzeftlw4a3e", - "title": "Example Login Item 01", + "id": "3aqwi56gkv2wonw5w35naruroa", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -163,13 +163,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:54Z", - "updated_at": "2023-02-26T21:52:54Z", - "additional_information": "user_01" + "created_at": "2023-07-10T20:54:46Z", + "updated_at": "2023-07-10T20:54:46Z", + "additional_information": "user_28" }, { - "id": "6bcqblmxbrsisisb2eupjq7avm", - "title": "Example Login Item 25", + "id": "kb7vgcvv3qyjkvbhm6em2f6hzy", + "title": "Example Login Item 10", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -177,13 +177,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:23Z", - "updated_at": "2023-02-26T21:53:23Z", - "additional_information": "user_25" + "created_at": "2023-07-10T20:54:25Z", + "updated_at": "2023-07-10T20:54:25Z", + "additional_information": "user_10" }, { - "id": "5wmqz5qe24km7fmgttklkx7p5a", - "title": "Example Login Item 20", + "id": "daukcdlqtkrqqwqcz7alkoa6em", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -191,13 +191,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:16Z", - "updated_at": "2023-02-26T21:53:16Z", - "additional_information": "user_20" + "created_at": "2023-07-10T20:54:49Z", + "updated_at": "2023-07-10T20:54:49Z", + "additional_information": "user_31" }, { - "id": "ioskuz642omqnvrq6tqknqghg4", - "title": "Example Login Item 03", + "id": "fh7byzemtipjjmb65irgewmlwq", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:56Z", - "updated_at": "2023-02-26T21:52:56Z", - "additional_information": "user_03" + "created_at": "2023-07-10T20:54:48Z", + "updated_at": "2023-07-10T20:54:48Z", + "additional_information": "user_30" }, { - "id": "6zh4myb3d6rwtv3hfhg6qp2ncm", - "title": "Example Login Item 06", + "id": "koo45d6jts4pkuck2n5aordmny", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -219,13 +219,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:59Z", - "updated_at": "2023-02-26T21:52:59Z", - "additional_information": "user_06" + "created_at": "2023-07-10T20:54:51Z", + "updated_at": "2023-07-10T20:54:51Z", + "additional_information": "user_33" }, { - "id": "shybm7klvq3wkek3fxwuakyk5i", - "title": "Example Login Item 13", + "id": "vtb5xljhrjfe42tzqchi3qrnpy", + "title": "Example Login Item 03", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -233,13 +233,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:07Z", - "updated_at": "2023-02-26T21:53:07Z", - "additional_information": "user_13" + "created_at": "2023-07-10T20:54:17Z", + "updated_at": "2023-07-10T20:54:17Z", + "additional_information": "user_03" }, { - "id": "lsujgnao5vw4lrjuhqoiovaxnq", - "title": "Example Login Item 21", + "id": "radxxrqumaqtnvqozslekl6nhy", + "title": "Example Login Item 00", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -247,13 +247,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:17Z", - "updated_at": "2023-02-26T21:53:17Z", - "additional_information": "user_21" + "created_at": "2023-07-10T20:54:14Z", + "updated_at": "2023-07-10T20:54:14Z", + "additional_information": "user_00" }, { - "id": "a76ldek4tcny3fggu3u7cq456u", - "title": "Example Login Item 23", + "id": "i2c3us2sfq6gbh2u5n46hca7he", + "title": "Example Login Item 11", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -261,13 +261,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:21Z", - "updated_at": "2023-02-26T21:53:21Z", - "additional_information": "user_23" + "created_at": "2023-07-10T20:54:27Z", + "updated_at": "2023-07-10T20:54:27Z", + "additional_information": "user_11" }, { - "id": "6br5ex37daswo5xzdbi6chkjlu", - "title": "Example Login Item 18", + "id": "b35tdije6oiozyogleflhhwhwy", + "title": "Example Login Item 01", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -275,13 +275,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:13Z", - "updated_at": "2023-02-26T21:53:13Z", - "additional_information": "user_18" + "created_at": "2023-07-10T20:54:15Z", + "updated_at": "2023-07-10T20:54:15Z", + "additional_information": "user_01" }, { - "id": "p35gttx2rad2tr5ah7mwesj7ea", - "title": "Example Login Item 26", + "id": "kib7zokx5oyeizss5pdci5b6p4", + "title": "Example Login Item 35", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -289,13 +289,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:24Z", - "updated_at": "2023-02-26T21:53:24Z", - "additional_information": "user_26" + "created_at": "2023-07-10T20:54:53Z", + "updated_at": "2023-07-10T20:54:53Z", + "additional_information": "user_35" }, { - "id": "yz7he5wzrjib3k3weha3ucrztu", - "title": "Example Login Item 14", + "id": "6cdyz752d4i4qmoenn4hhn5qaa", + "title": "Example Login Item 05", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -303,13 +303,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:08Z", - "updated_at": "2023-02-26T21:53:08Z", - "additional_information": "user_14" + "created_at": "2023-07-10T20:54:19Z", + "updated_at": "2023-07-10T20:54:19Z", + "additional_information": "user_05" }, { - "id": "ps2fpw422sjzfgmmibbh2ryp54", - "title": "Example Login Item 15", + "id": "qtfbp6zwnhwxmirbpziekhuf7y", + "title": "Example Login Item 29", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -317,13 +317,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:09Z", - "updated_at": "2023-02-26T21:53:09Z", - "additional_information": "user_15" + "created_at": "2023-07-10T20:54:47Z", + "updated_at": "2023-07-10T20:54:47Z", + "additional_information": "user_29" }, { - "id": "umsfsqt3pd7oms46lsgcdfkoeq", - "title": "Example Login Item 16", + "id": "3bxulcvnt2afmuuc5rrfd3t3su", + "title": "Example Login Item 04", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -331,13 +331,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:10Z", - "updated_at": "2023-02-26T21:53:10Z", - "additional_information": "user_16" + "created_at": "2023-07-10T20:54:18Z", + "updated_at": "2023-07-10T20:54:18Z", + "additional_information": "user_04" }, { - "id": "jhckzqn275tslogsidxcby3qwi", - "title": "Example Login Item 30", + "id": "7huqr4d5mvpmjov6aa2kl4wcnq", + "title": "Example Login Item 34", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -345,13 +345,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:29Z", - "updated_at": "2023-02-26T21:53:29Z", - "additional_information": "user_30" + "created_at": "2023-07-10T20:54:52Z", + "updated_at": "2023-07-10T20:54:52Z", + "additional_information": "user_34" }, { - "id": "kzpfqniu26tatmtzgk2wu377oe", - "title": "Example Login Item 19", + "id": "o3vbuksseuhovpmizkgvlut7ma", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -359,13 +359,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:14Z", - "updated_at": "2023-02-26T21:53:14Z", - "additional_information": "user_19" + "created_at": "2023-07-10T20:54:29Z", + "updated_at": "2023-07-10T20:54:29Z", + "additional_information": "user_13" }, { - "id": "6hlvskty5s72ljkn333iy445wi", - "title": "Example Login Item 28", + "id": "m7jprtjz3v3zkxx4sgm5fh5ske", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -373,13 +373,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:27Z", - "updated_at": "2023-02-26T21:53:27Z", - "additional_information": "user_28" + "created_at": "2023-07-10T20:54:37Z", + "updated_at": "2023-07-10T20:54:37Z", + "additional_information": "user_19" }, { - "id": "5h3qe4bqekt4ugxkobdha2fsli", - "title": "Example Login Item 29", + "id": "rhe6yevalei4fvcgkzdzgx5ihm", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -387,13 +387,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:28Z", - "updated_at": "2023-02-26T21:53:28Z", - "additional_information": "user_29" + "created_at": "2023-07-10T20:54:30Z", + "updated_at": "2023-07-10T20:54:30Z", + "additional_information": "user_14" }, { - "id": "gpzd5x33hnfgom4a6tv4ef42me", - "title": "Example Login Item 31", + "id": "wviqh7wfazdguizm3xm5ydfrvu", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -401,13 +401,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:30Z", - "updated_at": "2023-02-26T21:53:30Z", - "additional_information": "user_31" + "created_at": "2023-07-10T20:54:33Z", + "updated_at": "2023-07-10T20:54:33Z", + "additional_information": "user_16" }, { - "id": "pqmb32ew7sirfqkrlgpehcd6gm", - "title": "Example Login Item 34", + "id": "irpmzvyube7obnjz37s4nhyhf4", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:35Z", - "updated_at": "2023-02-26T21:53:35Z", - "additional_information": "user_34" + "created_at": "2023-07-10T20:54:34Z", + "updated_at": "2023-07-10T20:54:34Z", + "additional_information": "user_17" }, { - "id": "zayggylnibccqhvzmv3hgrgy4u", - "title": "Example Login Item 27", + "id": "xteh3aypnin5nopio67vywhg4q", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -429,13 +429,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:26Z", - "updated_at": "2023-02-26T21:53:26Z", - "additional_information": "user_27" + "created_at": "2023-07-10T20:54:35Z", + "updated_at": "2023-07-10T20:54:35Z", + "additional_information": "user_18" }, { - "id": "bmqdjbf54c7zor4jfnfdal7nva", - "title": "Example Login Item 35", + "id": "qez2yursmmkx5yqb5rgpwomblm", + "title": "Example Login Item 15", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -443,13 +443,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:36Z", - "updated_at": "2023-02-26T21:53:36Z", - "additional_information": "user_35" + "created_at": "2023-07-10T20:54:32Z", + "updated_at": "2023-07-10T20:54:32Z", + "additional_information": "user_15" }, { - "id": "xeaybnnl3tvisws5jvwcwpsvey", - "title": "Example Login Item 33", + "id": "aa3myi6s2xqobqrw3o4zhkcwru", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -457,8 +457,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:33Z", - "updated_at": "2023-02-26T21:53:33Z", - "additional_information": "user_33" + "created_at": "2023-07-10T20:54:38Z", + "updated_at": "2023-07-10T20:54:38Z", + "additional_information": "user_20" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3/output b/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3/output index a9c3f8b1..ebdfad1d 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-4/item-list-test-data-3/output @@ -1,7 +1,7 @@ [ { - "id": "bu4pinbfu72ze2rbh2ekhu47jy", - "title": "Example Login Item 05", + "id": "3csk5dtmupjjuph5durmxgpvvq", + "title": "Example Login Item 36", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -9,13 +9,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:58Z", - "updated_at": "2023-02-26T21:52:58Z", - "additional_information": "user_05" + "created_at": "2023-07-10T20:54:54Z", + "updated_at": "2023-07-10T20:54:54Z", + "additional_information": "user_36" }, { - "id": "rczlhdg7pum7wrhrf7euoeyatu", - "title": "Example Login Item 36", + "id": "setr26pmay3wwsmmtyqnop43ru", + "title": "Example Login Item 06", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -23,13 +23,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:37Z", - "updated_at": "2023-02-26T21:53:37Z", - "additional_information": "user_36" + "created_at": "2023-07-10T20:54:20Z", + "updated_at": "2023-07-10T20:54:20Z", + "additional_information": "user_06" }, { - "id": "ddqvqxnlbobjaaijpf5nmp2iiq", - "title": "Example Login Item 00", + "id": "6cdyz752d4i4qmoenn4hhn5qaa", + "title": "Example Login Item 05", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -37,13 +37,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:53Z", - "updated_at": "2023-02-26T21:52:53Z", - "additional_information": "user_00" + "created_at": "2023-07-10T20:54:19Z", + "updated_at": "2023-07-10T20:54:19Z", + "additional_information": "user_05" }, { - "id": "lsujgnao5vw4lrjuhqoiovaxnq", - "title": "Example Login Item 21", + "id": "z6kmzdaj64wyzq7yuuqjaubimm", + "title": "Example Login Item 07", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -51,13 +51,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:17Z", - "updated_at": "2023-02-26T21:53:17Z", - "additional_information": "user_21" + "created_at": "2023-07-10T20:54:21Z", + "updated_at": "2023-07-10T20:54:21Z", + "additional_information": "user_07" }, { - "id": "tkofaqsvxmpfdkvvzeftlw4a3e", - "title": "Example Login Item 01", + "id": "ofcl4plyaa63y2qkesp3vtmohi", + "title": "Example Login Item 08", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -65,13 +65,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:54Z", - "updated_at": "2023-02-26T21:52:54Z", - "additional_information": "user_01" + "created_at": "2023-07-10T20:54:23Z", + "updated_at": "2023-07-10T20:54:23Z", + "additional_information": "user_08" }, { - "id": "a76ldek4tcny3fggu3u7cq456u", - "title": "Example Login Item 23", + "id": "r2vmvbmc3akdnmuuxlbfxzbu3y", + "title": "Example Login Item 09", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -79,13 +79,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:21Z", - "updated_at": "2023-02-26T21:53:21Z", - "additional_information": "user_23" + "created_at": "2023-07-10T20:54:24Z", + "updated_at": "2023-07-10T20:54:24Z", + "additional_information": "user_09" }, { - "id": "5wmqz5qe24km7fmgttklkx7p5a", - "title": "Example Login Item 20", + "id": "kb7vgcvv3qyjkvbhm6em2f6hzy", + "title": "Example Login Item 10", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -93,13 +93,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:16Z", - "updated_at": "2023-02-26T21:53:16Z", - "additional_information": "user_20" + "created_at": "2023-07-10T20:54:25Z", + "updated_at": "2023-07-10T20:54:25Z", + "additional_information": "user_10" }, { - "id": "ioskuz642omqnvrq6tqknqghg4", - "title": "Example Login Item 03", + "id": "i2c3us2sfq6gbh2u5n46hca7he", + "title": "Example Login Item 11", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -107,13 +107,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:56Z", - "updated_at": "2023-02-26T21:52:56Z", - "additional_information": "user_03" + "created_at": "2023-07-10T20:54:27Z", + "updated_at": "2023-07-10T20:54:27Z", + "additional_information": "user_11" }, { - "id": "zz655vi3xlv2alllq7cjlyrxyu", - "title": "Example Login Item 24", + "id": "o3vbuksseuhovpmizkgvlut7ma", + "title": "Example Login Item 13", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -121,13 +121,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:22Z", - "updated_at": "2023-02-26T21:53:22Z", - "additional_information": "user_24" + "created_at": "2023-07-10T20:54:29Z", + "updated_at": "2023-07-10T20:54:29Z", + "additional_information": "user_13" }, { - "id": "x2b52i4kzkumd6r3mbko3ordwy", - "title": "Example Login Item 04", + "id": "rhe6yevalei4fvcgkzdzgx5ihm", + "title": "Example Login Item 14", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -135,13 +135,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:57Z", - "updated_at": "2023-02-26T21:52:57Z", - "additional_information": "user_04" + "created_at": "2023-07-10T20:54:30Z", + "updated_at": "2023-07-10T20:54:30Z", + "additional_information": "user_14" }, { - "id": "6bcqblmxbrsisisb2eupjq7avm", - "title": "Example Login Item 25", + "id": "qez2yursmmkx5yqb5rgpwomblm", + "title": "Example Login Item 15", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -149,13 +149,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:23Z", - "updated_at": "2023-02-26T21:53:23Z", - "additional_information": "user_25" + "created_at": "2023-07-10T20:54:32Z", + "updated_at": "2023-07-10T20:54:32Z", + "additional_information": "user_15" }, { - "id": "6zh4myb3d6rwtv3hfhg6qp2ncm", - "title": "Example Login Item 06", + "id": "5m5ezfrtkzbyzkngiy3nb3xzdq", + "title": "Example Login Item 26", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -163,13 +163,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:52:59Z", - "updated_at": "2023-02-26T21:52:59Z", - "additional_information": "user_06" + "created_at": "2023-07-10T20:54:44Z", + "updated_at": "2023-07-10T20:54:44Z", + "additional_information": "user_26" }, { - "id": "p35gttx2rad2tr5ah7mwesj7ea", - "title": "Example Login Item 26", + "id": "ltgvl3h7j6o6qk6bkyabxc2dbm", + "title": "Example Login Item 25", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -177,13 +177,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:24Z", - "updated_at": "2023-02-26T21:53:24Z", - "additional_information": "user_26" + "created_at": "2023-07-10T20:54:43Z", + "updated_at": "2023-07-10T20:54:43Z", + "additional_information": "user_25" }, { - "id": "shybm7klvq3wkek3fxwuakyk5i", - "title": "Example Login Item 13", + "id": "daukcdlqtkrqqwqcz7alkoa6em", + "title": "Example Login Item 31", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -191,13 +191,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:07Z", - "updated_at": "2023-02-26T21:53:07Z", - "additional_information": "user_13" + "created_at": "2023-07-10T20:54:49Z", + "updated_at": "2023-07-10T20:54:49Z", + "additional_information": "user_31" }, { - "id": "zayggylnibccqhvzmv3hgrgy4u", - "title": "Example Login Item 27", + "id": "wviqh7wfazdguizm3xm5ydfrvu", + "title": "Example Login Item 16", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -205,13 +205,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:26Z", - "updated_at": "2023-02-26T21:53:26Z", - "additional_information": "user_27" + "created_at": "2023-07-10T20:54:33Z", + "updated_at": "2023-07-10T20:54:33Z", + "additional_information": "user_16" }, { - "id": "yz7he5wzrjib3k3weha3ucrztu", - "title": "Example Login Item 14", + "id": "fh7byzemtipjjmb65irgewmlwq", + "title": "Example Login Item 30", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -219,13 +219,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:08Z", - "updated_at": "2023-02-26T21:53:08Z", - "additional_information": "user_14" + "created_at": "2023-07-10T20:54:48Z", + "updated_at": "2023-07-10T20:54:48Z", + "additional_information": "user_30" }, { - "id": "tzxbkgrpxjk47z52fvgpmfaoe4", - "title": "Example Login Item 07", + "id": "radxxrqumaqtnvqozslekl6nhy", + "title": "Example Login Item 00", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -233,13 +233,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:00Z", - "updated_at": "2023-02-26T21:53:00Z", - "additional_information": "user_07" + "created_at": "2023-07-10T20:54:14Z", + "updated_at": "2023-07-10T20:54:14Z", + "additional_information": "user_00" }, { - "id": "ps2fpw422sjzfgmmibbh2ryp54", - "title": "Example Login Item 15", + "id": "koo45d6jts4pkuck2n5aordmny", + "title": "Example Login Item 33", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -247,13 +247,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:09Z", - "updated_at": "2023-02-26T21:53:09Z", - "additional_information": "user_15" + "created_at": "2023-07-10T20:54:51Z", + "updated_at": "2023-07-10T20:54:51Z", + "additional_information": "user_33" }, { - "id": "6hlvskty5s72ljkn333iy445wi", - "title": "Example Login Item 28", + "id": "irpmzvyube7obnjz37s4nhyhf4", + "title": "Example Login Item 17", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -261,13 +261,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:27Z", - "updated_at": "2023-02-26T21:53:27Z", - "additional_information": "user_28" + "created_at": "2023-07-10T20:54:34Z", + "updated_at": "2023-07-10T20:54:34Z", + "additional_information": "user_17" }, { - "id": "eibsbn332mmexisxv73gt6ifky", - "title": "Example Login Item 10", + "id": "rm6dpqwxh7huf62a4un4rbp7ki", + "title": "Example Login Item 27", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -275,13 +275,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:03Z", - "updated_at": "2023-02-26T21:53:03Z", - "additional_information": "user_10" + "created_at": "2023-07-10T20:54:45Z", + "updated_at": "2023-07-10T20:54:45Z", + "additional_information": "user_27" }, { - "id": "umsfsqt3pd7oms46lsgcdfkoeq", - "title": "Example Login Item 16", + "id": "b35tdije6oiozyogleflhhwhwy", + "title": "Example Login Item 01", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -289,13 +289,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:10Z", - "updated_at": "2023-02-26T21:53:10Z", - "additional_information": "user_16" + "created_at": "2023-07-10T20:54:15Z", + "updated_at": "2023-07-10T20:54:15Z", + "additional_information": "user_01" }, { - "id": "5h3qe4bqekt4ugxkobdha2fsli", - "title": "Example Login Item 29", + "id": "7huqr4d5mvpmjov6aa2kl4wcnq", + "title": "Example Login Item 34", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -303,13 +303,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:28Z", - "updated_at": "2023-02-26T21:53:28Z", - "additional_information": "user_29" + "created_at": "2023-07-10T20:54:52Z", + "updated_at": "2023-07-10T20:54:52Z", + "additional_information": "user_34" }, { - "id": "rgc4nh6iekiye7cqdi2mfhpqpa", - "title": "Example Login Item 11", + "id": "xteh3aypnin5nopio67vywhg4q", + "title": "Example Login Item 18", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -317,13 +317,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:05Z", - "updated_at": "2023-02-26T21:53:05Z", - "additional_information": "user_11" + "created_at": "2023-07-10T20:54:35Z", + "updated_at": "2023-07-10T20:54:35Z", + "additional_information": "user_18" }, { - "id": "fazkwyxnaownqxgenf67btguwy", - "title": "Example Login Item 17", + "id": "3aqwi56gkv2wonw5w35naruroa", + "title": "Example Login Item 28", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -331,13 +331,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:12Z", - "updated_at": "2023-02-26T21:53:12Z", - "additional_information": "user_17" + "created_at": "2023-07-10T20:54:46Z", + "updated_at": "2023-07-10T20:54:46Z", + "additional_information": "user_28" }, { - "id": "pqmb32ew7sirfqkrlgpehcd6gm", - "title": "Example Login Item 34", + "id": "vtb5xljhrjfe42tzqchi3qrnpy", + "title": "Example Login Item 03", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -345,13 +345,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:35Z", - "updated_at": "2023-02-26T21:53:35Z", - "additional_information": "user_34" + "created_at": "2023-07-10T20:54:17Z", + "updated_at": "2023-07-10T20:54:17Z", + "additional_information": "user_03" }, { - "id": "6br5ex37daswo5xzdbi6chkjlu", - "title": "Example Login Item 18", + "id": "kib7zokx5oyeizss5pdci5b6p4", + "title": "Example Login Item 35", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -359,13 +359,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:13Z", - "updated_at": "2023-02-26T21:53:13Z", - "additional_information": "user_18" + "created_at": "2023-07-10T20:54:53Z", + "updated_at": "2023-07-10T20:54:53Z", + "additional_information": "user_35" }, { - "id": "we5iwz2cqhf73y3bzrcfvzcz2m", - "title": "Example Login Item 09", + "id": "m7jprtjz3v3zkxx4sgm5fh5ske", + "title": "Example Login Item 19", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -373,13 +373,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:02Z", - "updated_at": "2023-02-26T21:53:02Z", - "additional_information": "user_09" + "created_at": "2023-07-10T20:54:37Z", + "updated_at": "2023-07-10T20:54:37Z", + "additional_information": "user_19" }, { - "id": "kzpfqniu26tatmtzgk2wu377oe", - "title": "Example Login Item 19", + "id": "qtfbp6zwnhwxmirbpziekhuf7y", + "title": "Example Login Item 29", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -387,13 +387,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:14Z", - "updated_at": "2023-02-26T21:53:14Z", - "additional_information": "user_19" + "created_at": "2023-07-10T20:54:47Z", + "updated_at": "2023-07-10T20:54:47Z", + "additional_information": "user_29" }, { - "id": "xeaybnnl3tvisws5jvwcwpsvey", - "title": "Example Login Item 33", + "id": "3bxulcvnt2afmuuc5rrfd3t3su", + "title": "Example Login Item 04", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -401,13 +401,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:33Z", - "updated_at": "2023-02-26T21:53:33Z", - "additional_information": "user_33" + "created_at": "2023-07-10T20:54:18Z", + "updated_at": "2023-07-10T20:54:18Z", + "additional_information": "user_04" }, { - "id": "wtvxlb5cml5ihumatxubfo5quq", - "title": "Example Login Item 08", + "id": "aa3myi6s2xqobqrw3o4zhkcwru", + "title": "Example Login Item 20", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -415,13 +415,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:01Z", - "updated_at": "2023-02-26T21:53:01Z", - "additional_information": "user_08" + "created_at": "2023-07-10T20:54:38Z", + "updated_at": "2023-07-10T20:54:38Z", + "additional_information": "user_20" }, { - "id": "jhckzqn275tslogsidxcby3qwi", - "title": "Example Login Item 30", + "id": "fexqrzfidz53w4jzn7cveprqsy", + "title": "Example Login Item 21", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -429,13 +429,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:29Z", - "updated_at": "2023-02-26T21:53:29Z", - "additional_information": "user_30" + "created_at": "2023-07-10T20:54:39Z", + "updated_at": "2023-07-10T20:54:39Z", + "additional_information": "user_21" }, { - "id": "gpzd5x33hnfgom4a6tv4ef42me", - "title": "Example Login Item 31", + "id": "vbvaznvghvau55d4hfalcqcg2u", + "title": "Example Login Item 24", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -443,13 +443,13 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:30Z", - "updated_at": "2023-02-26T21:53:30Z", - "additional_information": "user_31" + "created_at": "2023-07-10T20:54:42Z", + "updated_at": "2023-07-10T20:54:42Z", + "additional_information": "user_24" }, { - "id": "bmqdjbf54c7zor4jfnfdal7nva", - "title": "Example Login Item 35", + "id": "ijkrebl72abwl2w32fx53c56km", + "title": "Example Login Item 23", "version": 1, "vault": { "id": "ptpmg6qseanbhoesdooqniehhy", @@ -457,8 +457,8 @@ }, "category": "LOGIN", "last_edited_by": "5GHHPJK5HZC5BAT7WDUXW57G44", - "created_at": "2023-02-26T21:53:36Z", - "updated_at": "2023-02-26T21:53:36Z", - "additional_information": "user_35" + "created_at": "2023-07-10T20:54:41Z", + "updated_at": "2023-07-10T20:54:41Z", + "additional_information": "user_23" } ] diff --git a/tests/config/mock-op/responses-item-delete-multiple/responses-4/list-signed-in-accounts/output b/tests/config/mock-op/responses-item-delete-multiple/responses-4/list-signed-in-accounts/output index f5134399..0f19f028 100644 --- a/tests/config/mock-op/responses-item-delete-multiple/responses-4/list-signed-in-accounts/output +++ b/tests/config/mock-op/responses-item-delete-multiple/responses-4/list-signed-in-accounts/output @@ -1,4 +1,10 @@ [ + { + "url": "pyonepassword.1password.com", + "email": "uid000@gmail.com", + "user_uuid": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57" + }, { "url": "example-account.1password.com", "email": "example_user@example.email", diff --git a/tests/config/mock-op/responses-item-edit/item-edit-state-config.json b/tests/config/mock-op/responses-item-edit/item-edit-state-config.json new file mode 100644 index 00000000..a066f029 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/item-edit-state-config.json @@ -0,0 +1,20 @@ +{ + "iteration": 0, + "max-iterations": 2, + "state-list": [ + { + "response-directory": "tests/config/mock-op/responses-item-edit/response-directory-1.json", + "env-vars": { + "set": {}, + "pop": [] + } + }, + { + "response-directory": "tests/config/mock-op/responses-item-edit/response-directory-2.json", + "env-vars": { + "set": {}, + "pop": [] + } + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/response-directory-1.json b/tests/config/mock-op/responses-item-edit/response-directory-1.json new file mode 100644 index 00000000..beb01d8c --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/response-directory-1.json @@ -0,0 +1,429 @@ +{ + "meta": { + "response_dir": "tests/config/mock-op/responses-item-edit/responses-1", + "input_dir": "input" + }, + "commands": { + "--account|5GHHPJK5HZC5BAT7WDUXW57G44|--format|json|whoami": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "whoami-account-uuid", + "changes_state": false + }, + "--version": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "cli-version", + "changes_state": false + }, + "--format|json|account|list": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "list-signed-in-accounts", + "changes_state": false + }, + "--format|json|whoami": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "whoami", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 00|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-00", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 00|password[password]=new password|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-00-set-password", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 01|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-01", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 01|--generate-password=20,letters,digits|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-01-generate-password", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 02|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-02", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 02|--title|Example Login Item 02 (New Title)|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-02-set-title", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 03|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-03", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 03|Example Section.password in a section[password]=new password in a section|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-03-set-password", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 04|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-04", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 04|--favorite=true|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-04-set-favorite", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 05|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-05", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 05|--favorite=false|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-05-set-favorite", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 06|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-06", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 06|--tags|tag_3,tag_4,tag_5|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-06-set-tags", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 07|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-07", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 07|--tags|tag_1,tag_2,tag_3|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-07-set-tags", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 08|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-08", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 08|--tags||--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-08-set-tags", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 08a|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-08a", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 08a|--tags|tag_1,tag_2,tag_3,tag_4,tag_5|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-08a-set-tags", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 09|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-09", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 09|--url|https://item-09-url.com/login.html|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-09-set-url", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 10|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-10", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 10|--url|https://item-10-url.com/login.html|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-10-set-url", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 11|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-11", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 11|--url|https://item-11-url.com/login.html|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-11-set-url", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 12|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-12", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 12|Section 01.Text Field 01[text]=new text field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-12-set-field-text", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 13|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-13", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 13|Section 01.URL Field 01[url]=https://new-url.com/login.html|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-13-set-field-url", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 14|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-14", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 14|Section 01.Password to Text 01[text]=new text field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-14-set-field-text", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 15|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-15", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 15|Section 01.Text field to be updated to URL 01[url]=https://new-url.com/login.html|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-15-set-field-url", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 16|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-16", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 17|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 17|Section 01.Text Field 01[text]=new text field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-17-add-text-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 18|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-18", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 18|Section 01.Password Field 01[password]=new password field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-18-add-password-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 17a|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17a", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 17a|Section 01.Text Field 01[text]=new text field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-17a-add-text-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 17b|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17b", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 17b|Section 01.Text Field 01[text]=new text field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-17b-add-text-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 17c|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17c", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 17c|Section 01.Text Field 01[text]=new text field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-17c-add-text-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 19|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-19", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 17d|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17d", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 17d|Text Field With no Section 01[text]=new text field value|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-17d-add-text-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 20|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-20", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 21a|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-21a", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 21a|Section 01.Text Field 01[delete]|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-21a-delete-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 21b|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-21b", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 21b|Text Field 01[delete]|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-21b-delete-field", + "changes_state": true + }, + "--format|json|item|get|Example Login Item 23|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-23", + "changes_state": false + }, + "--format|json|item|edit|Example Login Item 23|Section 01.URL Field 01[password]=https://new-url-field.com/|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-23-add-url-field", + "changes_state": true + }, + "--format|json|item|edit|Example Login Item 23|Section 01.URL Field 01[url]=https://new-url-field.com/|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-edit-example-login-23-add-url-field", + "changes_state": true + } + }, + "commands_with_input": {} +} \ No newline at end of file diff --git a/tests/config/mock-op/responses-item-edit/response-directory-2.json b/tests/config/mock-op/responses-item-edit/response-directory-2.json new file mode 100644 index 00000000..34bf24c5 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/response-directory-2.json @@ -0,0 +1,219 @@ +{ + "meta": { + "response_dir": "tests/config/mock-op/responses-item-edit/responses-2", + "input_dir": "input" + }, + "commands": { + "--account|5GHHPJK5HZC5BAT7WDUXW57G44|--format|json|whoami": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "whoami-account-uuid", + "changes_state": false + }, + "--version": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "cli-version", + "changes_state": false + }, + "--format|json|account|list": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "list-signed-in-accounts", + "changes_state": false + }, + "--format|json|whoami": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "whoami", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 00|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-00", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 01|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-01", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 02 (New Title)|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-02", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 03|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-03", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 04|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-04", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 05|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-05", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 06|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-06", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 07|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-07", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 08|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-08", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 08a|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-08a", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 09|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-09", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 10|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-10", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 11|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-11", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 12|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-12", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 13|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-13", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 14|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-14", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 15|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-15", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 17|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 18|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-18", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 17a|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17a", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 17b|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17b", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 17c|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17c", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 17d|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-17d", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 21a|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-21a", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 21b|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-21b", + "changes_state": false + }, + "--format|json|item|get|Example Login Item 23|--vault|Test Data 2": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-get-example-login-23", + "changes_state": false + } + }, + "commands_with_input": {} +} \ No newline at end of file diff --git a/tests/config/mock-op/responses-item-edit/responses-1/cli-version/error_output b/tests/config/mock-op/responses-item-edit/responses-1/cli-version/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/cli-version/output b/tests/config/mock-op/responses-item-edit/responses-1/cli-version/output new file mode 100644 index 00000000..c22d404b --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/cli-version/output @@ -0,0 +1 @@ +2.19.0-beta.01 diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-00-set-password/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-00-set-password/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-00-set-password/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-00-set-password/output new file mode 100644 index 00000000..af434846 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-00-set-password/output @@ -0,0 +1,43 @@ +{ + "id": "ssmrzws5zjt4ecmkagcnzzmy64", + "title": "Example Login Item 00", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:45Z", + "updated_at": "2023-08-22T15:17:35.359042-07:00", + "additional_information": "user_00", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_00", + "reference": "op://Test Data 2/Example Login Item 00/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "new password", + "reference": "op://Test Data 2/Example Login Item 00/password", + "password_details": { + "strength": "GOOD", + "history": ["-cpk8qcnV4tGpVahKenH"] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 00/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-01-generate-password/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-01-generate-password/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-01-generate-password/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-01-generate-password/output new file mode 100644 index 00000000..38e48cea --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-01-generate-password/output @@ -0,0 +1,46 @@ +{ + "id": "zvf66fm3j6qjhxqkryxnw6dv4q", + "title": "Example Login Item 01", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:46Z", + "updated_at": "2023-08-22T15:17:37.739917-07:00", + "additional_information": "user_01", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_01", + "reference": "op://Test Data 2/Example Login Item 01/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dRxrkayEh6Xb88UKVYpX", + "entropy": 115.52911376953125, + "reference": "op://Test Data 2/Example Login Item 01/password", + "password_details": { + "entropy": 115, + "generated": true, + "strength": "FANTASTIC", + "history": ["GN9Tsv..d7NB3vkh.Ucx"] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 01/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-02-set-title/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-02-set-title/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-02-set-title/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-02-set-title/output new file mode 100644 index 00000000..4e79a021 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-02-set-title/output @@ -0,0 +1,45 @@ +{ + "id": "wsvxtz2kulgqfberotkjdkpaby", + "title": "Example Login Item 02 (New Title)", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:47Z", + "updated_at": "2023-08-22T15:17:40.152167-07:00", + "additional_information": "user_02", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_02", + "reference": "op://Test Data 2/wsvxtz2kulgqfberotkjdkpaby/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "APT9U6frnY*7wbBWvdz3", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/wsvxtz2kulgqfberotkjdkpaby/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/wsvxtz2kulgqfberotkjdkpaby/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-03-set-password/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-03-set-password/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-03-set-password/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-03-set-password/output new file mode 100644 index 00000000..b35d08cd --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-03-set-password/output @@ -0,0 +1,62 @@ +{ + "id": "jaqdhlqiconk4wcekcpnuxzygq", + "title": "Example Login Item 03", + "version": 8, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:47Z", + "updated_at": "2023-08-22T19:54:41.937504-07:00", + "additional_information": "user_03", + "sections": [ + { + "id": "prs57pxzcifuuycv47h22fbmby", + "label": "Example Section" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_03", + "reference": "op://Test Data 2/Example Login Item 03/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dfc.p6vE@QeuViztbpin", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 03/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 03/notesPlain" + }, + { + "id": "fnefozhdxj4pohdnjv3wwrpfca", + "section": { + "id": "prs57pxzcifuuycv47h22fbmby", + "label": "Example Section" + }, + "type": "CONCEALED", + "label": "password in a section", + "value": "new password in a section", + "reference": "op://Test Data 2/Example Login Item 03/Example Section/password in a section" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-04-set-favorite/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-04-set-favorite/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-04-set-favorite/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-04-set-favorite/output new file mode 100644 index 00000000..3ed9e464 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-04-set-favorite/output @@ -0,0 +1,46 @@ +{ + "id": "4r6m3skmbelqbqibbs4a53mmay", + "title": "Example Login Item 04", + "favorite": true, + "version": 20, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:48Z", + "updated_at": "2023-08-28T21:00:00.268653-07:00", + "additional_information": "user_04", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_04", + "reference": "op://Test Data 2/Example Login Item 04/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "R2-cTGoQdrmBK6abuYBj", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 04/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 04/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-05-set-favorite/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-05-set-favorite/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-05-set-favorite/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-05-set-favorite/output new file mode 100644 index 00000000..31f1586f --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-05-set-favorite/output @@ -0,0 +1,45 @@ +{ + "id": "cqnwnsfixrmmiohto4thdtmpm4", + "title": "Example Login Item 05", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:49Z", + "updated_at": "2023-08-29T19:04:53.130478-07:00", + "additional_information": "user_05", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_05", + "reference": "op://Test Data 2/Example Login Item 05/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "tEE@@RvKHxMmV7VKPgbw", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 05/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 05/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-06-set-tags/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-06-set-tags/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-06-set-tags/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-06-set-tags/output new file mode 100644 index 00000000..6bff826e --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-06-set-tags/output @@ -0,0 +1,53 @@ +{ + "id": "2v5kevkbdt4g5k4ubyriqvgkge", + "title": "Example Login Item 06", + "tags": ["tag_3", "tag_4", "tag_5"], + "version": 9, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:50Z", + "updated_at": "2023-09-01T21:58:36.081212-07:00", + "additional_information": "user_06", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example-login-item-06/" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_06", + "reference": "op://Test Data 2/Example Login Item 06/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "vudKayDhwL*T!UfriF!7", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 06/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 06/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-07-set-tags/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-07-set-tags/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-07-set-tags/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-07-set-tags/output new file mode 100644 index 00000000..4083c2fb --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-07-set-tags/output @@ -0,0 +1,46 @@ +{ + "id": "hd4vn63li6sd7wfs53zwcpx5mq", + "title": "Example Login Item 07", + "tags": ["tag_1", "tag_2", "tag_3"], + "version": 13, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:51Z", + "updated_at": "2023-09-01T21:58:38.423206-07:00", + "additional_information": "user_07", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_07", + "reference": "op://Test Data 2/Example Login Item 07/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "_RPhBz3gTvz-fy8huq3e", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 07/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 07/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08-set-tags/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08-set-tags/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08-set-tags/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08-set-tags/output new file mode 100644 index 00000000..f2b695d8 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08-set-tags/output @@ -0,0 +1,45 @@ +{ + "id": "vmgepcg5kvjmvaoytxlrj5ovdq", + "title": "Example Login Item 08", + "version": 6, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:52Z", + "updated_at": "2023-09-04T19:24:14.601384-07:00", + "additional_information": "user_08", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_08", + "reference": "op://Test Data 2/Example Login Item 08/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "hKQNzuJ_zpLs_GhaK9yG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 08/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 08/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08a-set-tags/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08a-set-tags/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08a-set-tags/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08a-set-tags/output new file mode 100644 index 00000000..013995e9 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-08a-set-tags/output @@ -0,0 +1,46 @@ +{ + "id": "7btkxvemy7stw66piwx5mxnqai", + "title": "Example Login Item 08a", + "tags": ["tag_1", "tag_2", "tag_3", "tag_4", "tag_5"], + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:52Z", + "updated_at": "2023-09-04T20:23:01.786362-07:00", + "additional_information": "user_08", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_08", + "reference": "op://Test Data 2/Example Login Item 08a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "hKQNzuJ_zpLs_GhaK9yG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 08a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 08a/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-09-set-url/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-09-set-url/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-09-set-url/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-09-set-url/output new file mode 100644 index 00000000..058d2ebd --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-09-set-url/output @@ -0,0 +1,51 @@ +{ + "id": "rcotqz24dvaydkf74cwx4y6dsy", + "title": "Example Login Item 09", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:53Z", + "updated_at": "2023-09-07T13:43:31.347492-07:00", + "additional_information": "user_09", + "urls": [ + { + "primary": true, + "href": "https://item-09-url.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_09", + "reference": "op://Test Data 2/Example Login Item 09/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "PNwCwYyc8.eG3AnHKaFf", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 09/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 09/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-10-set-url/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-10-set-url/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-10-set-url/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-10-set-url/output new file mode 100644 index 00000000..b37aa7f6 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-10-set-url/output @@ -0,0 +1,51 @@ +{ + "id": "i3alx2zdreqy6qbg6mvqlflazy", + "title": "Example Login Item 10", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:30Z", + "updated_at": "2023-09-07T13:48:47.384716-07:00", + "additional_information": "user_10", + "urls": [ + { + "primary": true, + "href": "https://item-10-url.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_10", + "reference": "op://Test Data 2/Example Login Item 10/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "CMtJCnZ37!Nmncx2M@4Y", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 10/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 10/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-11-set-url/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-11-set-url/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-11-set-url/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-11-set-url/output new file mode 100644 index 00000000..da1fce74 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-11-set-url/output @@ -0,0 +1,55 @@ +{ + "id": "flljun7noqycy2twqr66nbjreu", + "title": "Example Login Item 11", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:31Z", + "updated_at": "2023-09-07T13:48:50.104181-07:00", + "additional_information": "user_11", + "urls": [ + { + "primary": true, + "href": "https://item-11-url.com/login.html" + }, + { + "label": "website", + "href": "https://second-website.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_11", + "reference": "op://Test Data 2/Example Login Item 11/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "ftgh@XvMduHE3U3WfX!!", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 11/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 11/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-12-set-field-text/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-12-set-field-text/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-12-set-field-text/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-12-set-field-text/output new file mode 100644 index 00000000..9508dae9 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-12-set-field-text/output @@ -0,0 +1,67 @@ +{ + "id": "ipifsyjdmyeg4e75ujmbkrefl4", + "title": "Example Login Item 12", + "version": 7, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-14T04:25:57Z", + "updated_at": "2023-09-26T18:53:19.202625-07:00", + "additional_information": "user_12", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "2osfud5e64s66tixoscjylr3fq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_12", + "reference": "op://Test Data 2/Example Login Item 12/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "oKfr2hck_VL482JFs9XP", + "reference": "op://Test Data 2/Example Login Item 12/password", + "password_details": { + "strength": "FANTASTIC", + "history": ["password"] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 12/notesPlain" + }, + { + "id": "h35qui6evukiodlevihezl7jgu", + "section": { + "id": "2osfud5e64s66tixoscjylr3fq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 12/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-13-set-field-url/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-13-set-field-url/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-13-set-field-url/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-13-set-field-url/output new file mode 100644 index 00000000..25b2bdaa --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-13-set-field-url/output @@ -0,0 +1,69 @@ +{ + "id": "63msonmzjvx7n27zqinjx4u5h4", + "title": "Example Login Item 13", + "version": 12, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:33Z", + "updated_at": "2023-10-06T10:52:44.448321-07:00", + "additional_information": "user_13", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "mx4kujb6faiznyhp4ymjvllydq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_13", + "reference": "op://Test Data 2/Example Login Item 13/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dWs36w-M-3tx-h9H-rmQ", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 13/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 13/notesPlain" + }, + { + "id": "62odajne7hsbr6wqoiztlqdjpy", + "section": { + "id": "mx4kujb6faiznyhp4ymjvllydq", + "label": "Section 01" + }, + "type": "URL", + "label": "URL Field 01", + "value": "https://new-url.com/login.html", + "reference": "op://Test Data 2/Example Login Item 13/Section 01/URL Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-14-set-field-text/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-14-set-field-text/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-14-set-field-text/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-14-set-field-text/output new file mode 100644 index 00000000..65fbd624 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-14-set-field-text/output @@ -0,0 +1,69 @@ +{ + "id": "2tnizxhowssne6cwpolz65ib3i", + "title": "Example Login Item 14", + "version": 10, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:34Z", + "updated_at": "2023-09-26T21:51:26.449926-07:00", + "additional_information": "user_14", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "k447btje43qwchrgyng4z4oqpm", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_14", + "reference": "op://Test Data 2/Example Login Item 14/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "YjCdQrXBX_hmxyb4Y8B6", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 14/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 14/notesPlain" + }, + { + "id": "7oxfe2moewfdbo2qj7u7nqh6im", + "section": { + "id": "k447btje43qwchrgyng4z4oqpm", + "label": "Section 01" + }, + "type": "STRING", + "label": "Password to Text 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 14/Section 01/Password to Text 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-15-set-field-url/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-15-set-field-url/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-15-set-field-url/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-15-set-field-url/output new file mode 100644 index 00000000..e459e4a6 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-15-set-field-url/output @@ -0,0 +1,69 @@ +{ + "id": "rgd62zizqblto72qzwascft66a", + "title": "Example Login Item 15", + "version": 6, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:35Z", + "updated_at": "2023-10-07T15:38:14.015489-07:00", + "additional_information": "user_15", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "u6evclctwauvlzfzyrre4b3bea", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_15", + "reference": "op://Test Data 2/Example Login Item 15/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "gB.iM7Mtkyypdj!.wADV", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 15/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 15/notesPlain" + }, + { + "id": "f2pwicstfapz3jyssurvokb6uy", + "section": { + "id": "u6evclctwauvlzfzyrre4b3bea", + "label": "Section 01" + }, + "type": "URL", + "label": "Text field to be updated to URL 01", + "value": "https://new-url.com/login.html", + "reference": "op://Test Data 2/Example Login Item 15/Section 01/Text field to be updated to URL 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17-add-text-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17-add-text-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17-add-text-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17-add-text-field/output new file mode 100644 index 00000000..bb78616e --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17-add-text-field/output @@ -0,0 +1,70 @@ +{ + "id": "hiy35xokn76r4qgyrty5sa4v3m", + "title": "Example Login Item 17", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-11T19:42:10.408811-07:00", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with no sections or fields. We will add a section and a field.", + "reference": "op://Test Data 2/Example Login Item 17/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17a-add-text-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17a-add-text-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17a-add-text-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17a-add-text-field/output new file mode 100644 index 00000000..c3aba913 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17a-add-text-field/output @@ -0,0 +1,85 @@ +{ + "id": "w247qmcyxsjwhbfmow3nx2br7i", + "title": "Example Login Item 17a", + "version": 5, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-12T20:29:55.454791-07:00", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_sqookysbfbbltgtlcd2fwip5im", + "label": "Section 01" + }, + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A field with the label we're trying to add\n- A section with a different label from what we're trying to add\n- We will add a section and a field that will be different that the existing section/field pairing", + "reference": "op://Test Data 2/Example Login Item 17a/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 02" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17a/Section 02/Text Field 01" + }, + { + "id": "epc7fzudrbykstzfn4tzrni4de", + "section": { + "id": "Section_sqookysbfbbltgtlcd2fwip5im", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17a/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17b-add-text-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17b-add-text-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17b-add-text-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17b-add-text-field/output new file mode 100644 index 00000000..b158a624 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17b-add-text-field/output @@ -0,0 +1,81 @@ +{ + "id": "qqptwa42kszxmtwsjlgf5io46q", + "title": "Example Login Item 17b", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-12T20:42:38.141343-07:00", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17b/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17b/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A section with the label from what we're trying to add\n- A field with associated with the above section but a different label we're trying to add\n- We will add a field and the existing section will have a new field for a total of two", + "reference": "op://Test Data 2/Example Login Item 17b/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 02", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17b/Section 01/Text Field 02" + }, + { + "id": "sov5o5wsfmsocflt3px7iftabi", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17b/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17c-add-text-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17c-add-text-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17c-add-text-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17c-add-text-field/output new file mode 100644 index 00000000..5765fe66 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17c-add-text-field/output @@ -0,0 +1,96 @@ +{ + "id": "74iwu2kqb4y2jfrzjl7wbuvyuq", + "title": "Example Login Item 17c", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T10:28:41.243968-07:00", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + { + "id": "cbfmyoy2yqyk5mzjrcqmua2nua", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17c/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17c/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A section with the label from what we're trying to add\n- A field with the label we're trying to add, but associated with a different section\n- We will add a field and the existing section will have a new field for a total of two", + "reference": "op://Test Data 2/Example Login Item 17c/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 02", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17c/Section 01/Text Field 02" + }, + { + "id": "uro7bsrmlovxptwnybn3wx5sru", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17c/Section 01/Text Field 01" + }, + { + "id": "7qfvsvf5bsmtqkadymzfnx7xam", + "section": { + "id": "cbfmyoy2yqyk5mzjrcqmua2nua", + "label": "Section 02" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "this is a different text field 01, so there's no collision", + "reference": "op://Test Data 2/Example Login Item 17c/Section 02/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17d-add-text-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17d-add-text-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17d-add-text-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17d-add-text-field/output new file mode 100644 index 00000000..514fa6ea --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-17d-add-text-field/output @@ -0,0 +1,60 @@ +{ + "id": "m3dazmnpma6to7ozkpvjdit3f4", + "title": "Example Login Item 17d", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-17T19:30:07.137522-07:00", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17d/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17d/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with no sections or fields. We will field but no section.", + "reference": "op://Test Data 2/Example Login Item 17d/notesPlain" + }, + { + "id": "4kfhnlrlycpecxspxfswkomrve", + "type": "STRING", + "label": "Text Field With no Section 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17d/Text Field With no Section 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-18-add-password-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-18-add-password-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-18-add-password-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-18-add-password-field/output new file mode 100644 index 00000000..0a9916df --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-18-add-password-field/output @@ -0,0 +1,69 @@ +{ + "id": "3oznm6vzf4bs5mfll62isfewca", + "title": "Example Login Item 18", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-12T19:36:39.776386-07:00", + "additional_information": "user_18", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_36gbxd5d7uw6uf4jbhgwrbj4da", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_18", + "reference": "op://Test Data 2/Example Login Item 18/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "XCtvmUt3sDdC9s*caACo", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 18/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 18/notesPlain" + }, + { + "id": "6motgcf7n7vq6wjxjwkpyne56y", + "section": { + "id": "Section_36gbxd5d7uw6uf4jbhgwrbj4da", + "label": "Section 01" + }, + "type": "CONCEALED", + "label": "Password Field 01", + "value": "new password field value", + "reference": "op://Test Data 2/Example Login Item 18/Section 01/Password Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21a-delete-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21a-delete-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21a-delete-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21a-delete-field/output new file mode 100644 index 00000000..9bc680c3 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21a-delete-field/output @@ -0,0 +1,52 @@ +{ + "id": "j3oytnhyz32hqz7t4aogyrfpqy", + "title": "Example Login Item 21a", + "version": 7, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-10-19T03:56:29Z", + "updated_at": "2023-10-19T20:22:12.760091-07:00", + "additional_information": "user_22", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_22", + "reference": "op://Test Data 2/Example Login Item 21a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "kUM.T2UQ7jqJYEkfGHg8", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 21a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 21a/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21b-delete-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21b-delete-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21b-delete-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21b-delete-field/output new file mode 100644 index 00000000..11184bdf --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-21b-delete-field/output @@ -0,0 +1,52 @@ +{ + "id": "lqr57j2hoqpthscrxebmrxi3zq", + "title": "Example Login Item 21b", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-10-20T04:07:03Z", + "updated_at": "2023-10-19T21:08:06.891601-07:00", + "additional_information": "user_21", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_21", + "reference": "op://Test Data 2/Example Login Item 21b/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "kUM.T2UQ7jqJYEkfGHg8", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 21b/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 21b/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-23-add-url-field/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-23-add-url-field/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-23-add-url-field/output b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-23-add-url-field/output new file mode 100644 index 00000000..f9390c4a --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-edit-example-login-23-add-url-field/output @@ -0,0 +1,69 @@ +{ + "id": "kpqpwgadvx35sllloe56us3o4q", + "title": "Example Login Item 23", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-10-19T03:56:29Z", + "updated_at": "2023-10-30T20:19:11.366466-07:00", + "additional_information": "user_23", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "sections": [ + { + "id": "Section_f3iomx2pymbvmpjiywbpbzbyem", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_23", + "reference": "op://Test Data 2/Example Login Item 23/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "2Eot7M.wk*hwDXCLEtPx", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 23/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 23/notesPlain" + }, + { + "id": "hz6v7d7uzhijvhtkwf2hbrbm3m", + "section": { + "id": "Section_f3iomx2pymbvmpjiywbpbzbyem", + "label": "Section 01" + }, + "type": "URL", + "label": "URL Field 01", + "value": "https://new-url-field.com/", + "reference": "op://Test Data 2/Example Login Item 23/Section 01/URL Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-00/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-00/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-00/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-00/output new file mode 100644 index 00000000..3250b2f2 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-00/output @@ -0,0 +1,45 @@ +{ + "id": "ssmrzws5zjt4ecmkagcnzzmy64", + "title": "Example Login Item 00", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:45Z", + "updated_at": "2023-08-22T22:14:45Z", + "additional_information": "user_00", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_00", + "reference": "op://Test Data 2/Example Login Item 00/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "-cpk8qcnV4tGpVahKenH", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 00/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 00/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-01/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-01/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-01/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-01/output new file mode 100644 index 00000000..4a38d22c --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-01/output @@ -0,0 +1,45 @@ +{ + "id": "zvf66fm3j6qjhxqkryxnw6dv4q", + "title": "Example Login Item 01", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:46Z", + "updated_at": "2023-08-22T22:14:46Z", + "additional_information": "user_01", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_01", + "reference": "op://Test Data 2/Example Login Item 01/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "GN9Tsv..d7NB3vkh.Ucx", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 01/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 01/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-02/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-02/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-02/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-02/output new file mode 100644 index 00000000..62fe496f --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-02/output @@ -0,0 +1,45 @@ +{ + "id": "wsvxtz2kulgqfberotkjdkpaby", + "title": "Example Login Item 02", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:47Z", + "updated_at": "2023-08-22T22:14:47Z", + "additional_information": "user_02", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_02", + "reference": "op://Test Data 2/Example Login Item 02/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "APT9U6frnY*7wbBWvdz3", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 02/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 02/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-03/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-03/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-03/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-03/output new file mode 100644 index 00000000..223fe642 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-03/output @@ -0,0 +1,62 @@ +{ + "id": "jaqdhlqiconk4wcekcpnuxzygq", + "title": "Example Login Item 03", + "version": 7, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:47Z", + "updated_at": "2023-08-23T02:52:36Z", + "additional_information": "user_03", + "sections": [ + { + "id": "prs57pxzcifuuycv47h22fbmby", + "label": "Example Section" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_03", + "reference": "op://Test Data 2/Example Login Item 03/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dfc.p6vE@QeuViztbpin", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 03/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 03/notesPlain" + }, + { + "id": "fnefozhdxj4pohdnjv3wwrpfca", + "section": { + "id": "prs57pxzcifuuycv47h22fbmby", + "label": "Example Section" + }, + "type": "CONCEALED", + "label": "password in a section", + "value": "original password", + "reference": "op://Test Data 2/Example Login Item 03/Example Section/password in a section" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-04/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-04/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-04/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-04/output new file mode 100644 index 00000000..c5a5de68 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-04/output @@ -0,0 +1,45 @@ +{ + "id": "4r6m3skmbelqbqibbs4a53mmay", + "title": "Example Login Item 04", + "version": 19, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:48Z", + "updated_at": "2023-08-29T03:59:52Z", + "additional_information": "user_04", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_04", + "reference": "op://Test Data 2/Example Login Item 04/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "R2-cTGoQdrmBK6abuYBj", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 04/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 04/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-05/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-05/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-05/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-05/output new file mode 100644 index 00000000..6dfa460d --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-05/output @@ -0,0 +1,46 @@ +{ + "id": "cqnwnsfixrmmiohto4thdtmpm4", + "title": "Example Login Item 05", + "favorite": true, + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:49Z", + "updated_at": "2023-08-30T01:58:30Z", + "additional_information": "user_05", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_05", + "reference": "op://Test Data 2/Example Login Item 05/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "tEE@@RvKHxMmV7VKPgbw", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 05/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 05/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-06/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-06/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-06/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-06/output new file mode 100644 index 00000000..ac65fd74 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-06/output @@ -0,0 +1,53 @@ +{ + "id": "2v5kevkbdt4g5k4ubyriqvgkge", + "title": "Example Login Item 06", + "tags": ["tag_1", "tag_2"], + "version": 8, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:50Z", + "updated_at": "2023-09-02T04:55:29Z", + "additional_information": "user_06", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example-login-item-06/" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_06", + "reference": "op://Test Data 2/Example Login Item 06/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "vudKayDhwL*T!UfriF!7", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 06/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 06/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-07/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-07/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-07/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-07/output new file mode 100644 index 00000000..771ec34c --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-07/output @@ -0,0 +1,45 @@ +{ + "id": "hd4vn63li6sd7wfs53zwcpx5mq", + "title": "Example Login Item 07", + "version": 12, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-08-22T22:14:51Z", + "updated_at": "2023-09-02T04:56:21Z", + "additional_information": "user_07", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_07", + "reference": "op://Test Data 2/Example Login Item 07/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "_RPhBz3gTvz-fy8huq3e", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 07/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 07/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08/output new file mode 100644 index 00000000..4d82208b --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08/output @@ -0,0 +1,46 @@ +{ + "id": "vmgepcg5kvjmvaoytxlrj5ovdq", + "title": "Example Login Item 08", + "tags": ["tag_1", "tag_2", "tag_3"], + "version": 5, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:52Z", + "updated_at": "2023-09-05T02:17:23Z", + "additional_information": "user_08", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_08", + "reference": "op://Test Data 2/Example Login Item 08/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "hKQNzuJ_zpLs_GhaK9yG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 08/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 08/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08a/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08a/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08a/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08a/output new file mode 100644 index 00000000..2e933c1f --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-08a/output @@ -0,0 +1,46 @@ +{ + "id": "7btkxvemy7stw66piwx5mxnqai", + "title": "Example Login Item 08a", + "tags": ["tag_1", "tag_2", "tag_3"], + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:52Z", + "updated_at": "2023-09-05T03:22:44Z", + "additional_information": "user_08", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_08", + "reference": "op://Test Data 2/Example Login Item 08a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "hKQNzuJ_zpLs_GhaK9yG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 08a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 08a/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-09/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-09/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-09/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-09/output new file mode 100644 index 00000000..af6b849d --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-09/output @@ -0,0 +1,45 @@ +{ + "id": "rcotqz24dvaydkf74cwx4y6dsy", + "title": "Example Login Item 09", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:53Z", + "updated_at": "2023-08-22T22:14:53Z", + "additional_information": "user_09", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_09", + "reference": "op://Test Data 2/Example Login Item 09/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "PNwCwYyc8.eG3AnHKaFf", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 09/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 09/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-10/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-10/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-10/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-10/output new file mode 100644 index 00000000..ce4eb912 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-10/output @@ -0,0 +1,52 @@ +{ + "id": "i3alx2zdreqy6qbg6mvqlflazy", + "title": "Example Login Item 10", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:30Z", + "updated_at": "2023-09-07T20:31:30Z", + "additional_information": "user_10", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_10", + "reference": "op://Test Data 2/Example Login Item 10/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "CMtJCnZ37!Nmncx2M@4Y", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 10/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 10/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-11/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-11/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-11/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-11/output new file mode 100644 index 00000000..d0adc815 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-11/output @@ -0,0 +1,56 @@ +{ + "id": "flljun7noqycy2twqr66nbjreu", + "title": "Example Login Item 11", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:31Z", + "updated_at": "2023-09-07T20:36:02Z", + "additional_information": "user_11", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + }, + { + "label": "website", + "href": "https://second-website.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_11", + "reference": "op://Test Data 2/Example Login Item 11/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "ftgh@XvMduHE3U3WfX!!", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 11/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 11/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-12/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-12/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-12/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-12/output new file mode 100644 index 00000000..3c0caa25 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-12/output @@ -0,0 +1,67 @@ +{ + "id": "ipifsyjdmyeg4e75ujmbkrefl4", + "title": "Example Login Item 12", + "version": 6, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-14T04:25:57Z", + "updated_at": "2023-09-27T01:50:38Z", + "additional_information": "user_12", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "2osfud5e64s66tixoscjylr3fq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_12", + "reference": "op://Test Data 2/Example Login Item 12/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "oKfr2hck_VL482JFs9XP", + "reference": "op://Test Data 2/Example Login Item 12/password", + "password_details": { + "strength": "FANTASTIC", + "history": ["password"] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 12/notesPlain" + }, + { + "id": "h35qui6evukiodlevihezl7jgu", + "section": { + "id": "2osfud5e64s66tixoscjylr3fq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "original text field value", + "reference": "op://Test Data 2/Example Login Item 12/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-13/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-13/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-13/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-13/output new file mode 100644 index 00000000..b93e2b0a --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-13/output @@ -0,0 +1,69 @@ +{ + "id": "63msonmzjvx7n27zqinjx4u5h4", + "title": "Example Login Item 13", + "version": 11, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:33Z", + "updated_at": "2023-10-06T17:52:02Z", + "additional_information": "user_13", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "mx4kujb6faiznyhp4ymjvllydq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_13", + "reference": "op://Test Data 2/Example Login Item 13/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dWs36w-M-3tx-h9H-rmQ", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 13/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 13/notesPlain" + }, + { + "id": "62odajne7hsbr6wqoiztlqdjpy", + "section": { + "id": "mx4kujb6faiznyhp4ymjvllydq", + "label": "Section 01" + }, + "type": "URL", + "label": "URL Field 01", + "value": "https://original-url.com/login.html", + "reference": "op://Test Data 2/Example Login Item 13/Section 01/URL Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-14/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-14/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-14/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-14/output new file mode 100644 index 00000000..b127fd7d --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-14/output @@ -0,0 +1,69 @@ +{ + "id": "2tnizxhowssne6cwpolz65ib3i", + "title": "Example Login Item 14", + "version": 9, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:34Z", + "updated_at": "2023-09-27T04:36:49Z", + "additional_information": "user_14", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "k447btje43qwchrgyng4z4oqpm", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_14", + "reference": "op://Test Data 2/Example Login Item 14/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "YjCdQrXBX_hmxyb4Y8B6", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 14/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 14/notesPlain" + }, + { + "id": "7oxfe2moewfdbo2qj7u7nqh6im", + "section": { + "id": "k447btje43qwchrgyng4z4oqpm", + "label": "Section 01" + }, + "type": "CONCEALED", + "label": "Password to Text 01", + "value": "terrible password", + "reference": "op://Test Data 2/Example Login Item 14/Section 01/Password to Text 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-15/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-15/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-15/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-15/output new file mode 100644 index 00000000..a8789dc2 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-15/output @@ -0,0 +1,69 @@ +{ + "id": "rgd62zizqblto72qzwascft66a", + "title": "Example Login Item 15", + "version": 5, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:35Z", + "updated_at": "2023-10-07T21:35:10Z", + "additional_information": "user_15", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "u6evclctwauvlzfzyrre4b3bea", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_15", + "reference": "op://Test Data 2/Example Login Item 15/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "gB.iM7Mtkyypdj!.wADV", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 15/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 15/notesPlain" + }, + { + "id": "f2pwicstfapz3jyssurvokb6uy", + "section": { + "id": "u6evclctwauvlzfzyrre4b3bea", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text field to be updated to URL 01", + "value": "Original text value", + "reference": "op://Test Data 2/Example Login Item 15/Section 01/Text field to be updated to URL 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-16/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-16/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-16/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-16/output new file mode 100644 index 00000000..511c808e --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-16/output @@ -0,0 +1,84 @@ +{ + "id": "4ikcuhuipjywspfdb5c2oiw5ei", + "title": "Example Login Item 16", + "version": 7, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:36Z", + "updated_at": "2023-10-11T02:54:17Z", + "additional_information": "user_16", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "4nrqrhktgpj2mrdyrgixucrote", + "label": "Section 01" + }, + { + "id": "ruk5nvk3dax2mcbzlnaglcikwu", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_16", + "reference": "op://Test Data 2/Example Login Item 16/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "P.Lkr67WcMef7NcyQotC", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 16/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 16/notesPlain" + }, + { + "id": "j4s6zh5tj24dcbu52bi5noxwym", + "section": { + "id": "4nrqrhktgpj2mrdyrgixucrote", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "example text 01", + "reference": "op://Test Data 2/Example Login Item 16/Section 01/Text Field 01" + }, + { + "id": "omfqzrqzediujtvcsv6njhkvry", + "section": { + "id": "ruk5nvk3dax2mcbzlnaglcikwu", + "label": "Section 02" + }, + "type": "STRING", + "label": "Text Field 02", + "value": "example text 02", + "reference": "op://Test Data 2/Example Login Item 16/Section 02/Text Field 02" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17/output new file mode 100644 index 00000000..1887ba9f --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17/output @@ -0,0 +1,53 @@ +{ + "id": "hiy35xokn76r4qgyrty5sa4v3m", + "title": "Example Login Item 17", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-12T02:25:18Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with no sections or fields. We will add a section and a field.", + "reference": "op://Test Data 2/Example Login Item 17/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17a/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17a/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17a/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17a/output new file mode 100644 index 00000000..5fc368c9 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17a/output @@ -0,0 +1,70 @@ +{ + "id": "w247qmcyxsjwhbfmow3nx2br7i", + "title": "Example Login Item 17a", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T03:25:35Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A field with the label we're trying to add\n- A section with a different label from what we're trying to add\n- We will add a section and a field that will be different that the existing section/field pairing", + "reference": "op://Test Data 2/Example Login Item 17a/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 02" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17a/Section 02/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17b/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17b/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17b/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17b/output new file mode 100644 index 00000000..7bde28e7 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17b/output @@ -0,0 +1,70 @@ +{ + "id": "qqptwa42kszxmtwsjlgf5io46q", + "title": "Example Login Item 17b", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T03:40:49Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17b/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17b/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A section with the label from what we're trying to add\n- A field with associated with the above section but a different label we're trying to add\n- We will add a field and the existing section will have a new field for a total of two", + "reference": "op://Test Data 2/Example Login Item 17b/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 02", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17b/Section 01/Text Field 02" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17c/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17c/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17c/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17c/output new file mode 100644 index 00000000..0e69e55e --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17c/output @@ -0,0 +1,85 @@ +{ + "id": "74iwu2kqb4y2jfrzjl7wbuvyuq", + "title": "Example Login Item 17c", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T17:25:15Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + { + "id": "cbfmyoy2yqyk5mzjrcqmua2nua", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17c/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17c/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A section with the label from what we're trying to add\n- A field with the label we're trying to add, but associated with a different section\n- We will add a field and the existing section will have a new field for a total of two", + "reference": "op://Test Data 2/Example Login Item 17c/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 02", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17c/Section 01/Text Field 02" + }, + { + "id": "7qfvsvf5bsmtqkadymzfnx7xam", + "section": { + "id": "cbfmyoy2yqyk5mzjrcqmua2nua", + "label": "Section 02" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "this is a different text field 01, so there's no collision", + "reference": "op://Test Data 2/Example Login Item 17c/Section 02/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17d/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17d/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17d/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17d/output new file mode 100644 index 00000000..80a70979 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-17d/output @@ -0,0 +1,53 @@ +{ + "id": "m3dazmnpma6to7ozkpvjdit3f4", + "title": "Example Login Item 17d", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-18T02:24:10Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17d/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17d/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with no sections or fields. We will field but no section.", + "reference": "op://Test Data 2/Example Login Item 17d/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-18/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-18/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-18/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-18/output new file mode 100644 index 00000000..25d03c1a --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-18/output @@ -0,0 +1,52 @@ +{ + "id": "3oznm6vzf4bs5mfll62isfewca", + "title": "Example Login Item 18", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-09-07T20:31:37Z", + "additional_information": "user_18", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_18", + "reference": "op://Test Data 2/Example Login Item 18/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "XCtvmUt3sDdC9s*caACo", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 18/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 18/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-19/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-19/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-19/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-19/output new file mode 100644 index 00000000..c2f7d265 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-19/output @@ -0,0 +1,84 @@ +{ + "id": "ditodi62v54v3cctlrgeyob4ay", + "title": "Example Login Item 19", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:38Z", + "updated_at": "2023-10-17T22:34:50Z", + "additional_information": "user_19", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "srad7gzaijhwguwdio6pavxdum", + "label": "Section 01" + }, + { + "id": "siangow5ffvhgnaro6ejdzfiiy", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_19", + "reference": "op://Test Data 2/Example Login Item 19/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "rFyo*4mVDDeUiRukKYxW", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 19/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 19/notesPlain" + }, + { + "id": "uyhdjin5xhy3swn6yl3wzgtrgy", + "section": { + "id": "srad7gzaijhwguwdio6pavxdum", + "label": "Section 01" + }, + "type": "STRING", + "label": "Ambiguous Field Match", + "value": "field text for first ambiguous field match", + "reference": "op://Test Data 2/Example Login Item 19/Section 01/Ambiguous Field Match" + }, + { + "id": "wcjcs5ogqsewrci3kmpssdcolq", + "section": { + "id": "siangow5ffvhgnaro6ejdzfiiy", + "label": "Section 02" + }, + "type": "STRING", + "label": "Ambiguous Field Match", + "value": "field text for second ambiguous field match", + "reference": "op://Test Data 2/Example Login Item 19/Section 02/Ambiguous Field Match" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-20/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-20/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-20/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-20/output new file mode 100644 index 00000000..12df5a8d --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-20/output @@ -0,0 +1,69 @@ +{ + "id": "7tm5rzkbqa2z24oojl7athfgie", + "title": "Example Login Item 20", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-09-07T20:31:38Z", + "updated_at": "2023-10-18T02:50:52Z", + "additional_information": "user_19", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "srad7gzaijhwguwdio6pavxdum", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_19", + "reference": "op://Test Data 2/Example Login Item 20/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "rFyo*4mVDDeUiRukKYxW", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 20/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 20/notesPlain" + }, + { + "id": "uyhdjin5xhy3swn6yl3wzgtrgy", + "section": { + "id": "srad7gzaijhwguwdio6pavxdum", + "label": "Section 01" + }, + "type": "STRING", + "label": "Field 01", + "value": "text for field 01", + "reference": "op://Test Data 2/Example Login Item 20/Section 01/Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21a/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21a/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21a/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21a/output new file mode 100644 index 00000000..18080d04 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21a/output @@ -0,0 +1,69 @@ +{ + "id": "j3oytnhyz32hqz7t4aogyrfpqy", + "title": "Example Login Item 21a", + "version": 6, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-10-19T03:56:29Z", + "updated_at": "2023-10-20T03:21:38Z", + "additional_information": "user_22", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "sections": [ + { + "id": "ardnsqhumkthcak3hbexy6hene", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_22", + "reference": "op://Test Data 2/Example Login Item 21a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "kUM.T2UQ7jqJYEkfGHg8", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 21a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 21a/notesPlain" + }, + { + "id": "li4lqu54aqwibedplafx5hpftu", + "section": { + "id": "ardnsqhumkthcak3hbexy6hene", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "example text 01", + "reference": "op://Test Data 2/Example Login Item 21a/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21b/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21b/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21b/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21b/output new file mode 100644 index 00000000..6a512ac8 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-21b/output @@ -0,0 +1,59 @@ +{ + "id": "lqr57j2hoqpthscrxebmrxi3zq", + "title": "Example Login Item 21b", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-10-20T04:07:03Z", + "updated_at": "2023-10-20T04:07:49Z", + "additional_information": "user_21", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_21", + "reference": "op://Test Data 2/Example Login Item 21b/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "kUM.T2UQ7jqJYEkfGHg8", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 21b/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 21b/notesPlain" + }, + { + "id": "b4ye77gtqegq7bqaks7jveup3a", + "type": "STRING", + "label": "Text Field 01", + "value": "example text 01", + "reference": "op://Test Data 2/Example Login Item 21b/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-23/error_output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-23/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-23/output b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-23/output new file mode 100644 index 00000000..0940032d --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/item-get-example-login-23/output @@ -0,0 +1,52 @@ +{ + "id": "kpqpwgadvx35sllloe56us3o4q", + "title": "Example Login Item 23", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "created_at": "2023-10-19T03:56:29Z", + "updated_at": "2023-10-31T03:16:52Z", + "additional_information": "user_23", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_23", + "reference": "op://Test Data 2/Example Login Item 23/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "2Eot7M.wk*hwDXCLEtPx", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 23/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 23/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/list-signed-in-accounts/error_output b/tests/config/mock-op/responses-item-edit/responses-1/list-signed-in-accounts/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/list-signed-in-accounts/output b/tests/config/mock-op/responses-item-edit/responses-1/list-signed-in-accounts/output new file mode 100644 index 00000000..e4d885fe --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/list-signed-in-accounts/output @@ -0,0 +1,20 @@ +[ + { + "url": "example-account.1password.com", + "email": "example_user@example.email", + "user_uuid": "5GHHPJK5HZC5BAT7WDUXW57G44", + "account_uuid": "GRXJAN4BY5DPROISKYL55IRCPY" + }, + { + "url": "my.1password.com", + "email": "guest_user@example.email", + "user_uuid": "DJGTGRFRM5C4BHNUXQLJXQJAOE", + "account_uuid": "6J7RFGQWONBVJHIHJUVICO2C3Q" + }, + { + "url": "pyonepassword.1password.com", + "email": "uid000@gmail.com", + "user_uuid": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57" + } +] diff --git a/tests/config/mock-op/responses-item-edit/responses-1/whoami-account-uuid/error_output b/tests/config/mock-op/responses-item-edit/responses-1/whoami-account-uuid/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/whoami-account-uuid/output b/tests/config/mock-op/responses-item-edit/responses-1/whoami-account-uuid/output new file mode 100644 index 00000000..b93856b6 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/whoami-account-uuid/output @@ -0,0 +1,4 @@ +{ + "URL": "https://pyonepassword.1password.com", + "ServiceAccountType": "SERVICE_ACCOUNT" +} diff --git a/tests/config/mock-op/responses-item-edit/responses-1/whoami/error_output b/tests/config/mock-op/responses-item-edit/responses-1/whoami/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-1/whoami/output b/tests/config/mock-op/responses-item-edit/responses-1/whoami/output new file mode 100644 index 00000000..b93856b6 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-1/whoami/output @@ -0,0 +1,4 @@ +{ + "URL": "https://pyonepassword.1password.com", + "ServiceAccountType": "SERVICE_ACCOUNT" +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/cli-version/error_output b/tests/config/mock-op/responses-item-edit/responses-2/cli-version/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/cli-version/output b/tests/config/mock-op/responses-item-edit/responses-2/cli-version/output new file mode 100644 index 00000000..c22d404b --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/cli-version/output @@ -0,0 +1 @@ +2.19.0-beta.01 diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-00/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-00/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-00/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-00/output new file mode 100644 index 00000000..c28ca662 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-00/output @@ -0,0 +1,46 @@ +{ + "id": "ssmrzws5zjt4ecmkagcnzzmy64", + "title": "Example Login Item 00", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:45Z", + "updated_at": "2023-08-22T22:17:35Z", + "additional_information": "user_00", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_00", + "reference": "op://Test Data 2/Example Login Item 00/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "new password", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 00/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "GOOD", + "history": ["-cpk8qcnV4tGpVahKenH"] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 00/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-01/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-01/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-01/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-01/output new file mode 100644 index 00000000..793f142a --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-01/output @@ -0,0 +1,46 @@ +{ + "id": "zvf66fm3j6qjhxqkryxnw6dv4q", + "title": "Example Login Item 01", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:46Z", + "updated_at": "2023-08-22T22:17:38Z", + "additional_information": "user_01", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_01", + "reference": "op://Test Data 2/Example Login Item 01/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dRxrkayEh6Xb88UKVYpX", + "entropy": 115.52911376953125, + "reference": "op://Test Data 2/Example Login Item 01/password", + "password_details": { + "entropy": 115, + "generated": true, + "strength": "FANTASTIC", + "history": ["GN9Tsv..d7NB3vkh.Ucx"] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 01/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-02/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-02/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-02/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-02/output new file mode 100644 index 00000000..dc073bf1 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-02/output @@ -0,0 +1,45 @@ +{ + "id": "wsvxtz2kulgqfberotkjdkpaby", + "title": "Example Login Item 02 (New Title)", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:47Z", + "updated_at": "2023-08-22T22:17:40Z", + "additional_information": "user_02", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_02", + "reference": "op://Test Data 2/wsvxtz2kulgqfberotkjdkpaby/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "APT9U6frnY*7wbBWvdz3", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/wsvxtz2kulgqfberotkjdkpaby/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/wsvxtz2kulgqfberotkjdkpaby/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-03/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-03/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-03/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-03/output new file mode 100644 index 00000000..f1462fac --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-03/output @@ -0,0 +1,62 @@ +{ + "id": "jaqdhlqiconk4wcekcpnuxzygq", + "title": "Example Login Item 03", + "version": 8, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:47Z", + "updated_at": "2023-08-23T02:54:42Z", + "additional_information": "user_03", + "sections": [ + { + "id": "prs57pxzcifuuycv47h22fbmby", + "label": "Example Section" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_03", + "reference": "op://Test Data 2/Example Login Item 03/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dfc.p6vE@QeuViztbpin", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 03/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 03/notesPlain" + }, + { + "id": "fnefozhdxj4pohdnjv3wwrpfca", + "section": { + "id": "prs57pxzcifuuycv47h22fbmby", + "label": "Example Section" + }, + "type": "CONCEALED", + "label": "password in a section", + "value": "new password in a section", + "reference": "op://Test Data 2/Example Login Item 03/Example Section/password in a section" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-04/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-04/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-04/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-04/output new file mode 100644 index 00000000..b23cec7a --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-04/output @@ -0,0 +1,46 @@ +{ + "id": "4r6m3skmbelqbqibbs4a53mmay", + "title": "Example Login Item 04", + "favorite": true, + "version": 18, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:48Z", + "updated_at": "2023-08-29T03:27:03Z", + "additional_information": "user_04", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_04", + "reference": "op://Test Data 2/Example Login Item 04/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "R2-cTGoQdrmBK6abuYBj", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 04/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 04/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-05/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-05/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-05/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-05/output new file mode 100644 index 00000000..feae2c1b --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-05/output @@ -0,0 +1,45 @@ +{ + "id": "cqnwnsfixrmmiohto4thdtmpm4", + "title": "Example Login Item 05", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:49Z", + "updated_at": "2023-08-30T02:04:53Z", + "additional_information": "user_05", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_05", + "reference": "op://Test Data 2/Example Login Item 05/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "tEE@@RvKHxMmV7VKPgbw", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 05/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 05/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-06/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-06/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-06/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-06/output new file mode 100644 index 00000000..21217311 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-06/output @@ -0,0 +1,53 @@ +{ + "id": "2v5kevkbdt4g5k4ubyriqvgkge", + "title": "Example Login Item 06", + "tags": ["tag_3", "tag_4", "tag_5"], + "version": 9, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:50Z", + "updated_at": "2023-09-02T04:58:36Z", + "additional_information": "user_06", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example-login-item-06/" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_06", + "reference": "op://Test Data 2/Example Login Item 06/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "vudKayDhwL*T!UfriF!7", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 06/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 06/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-07/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-07/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-07/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-07/output new file mode 100644 index 00000000..9b9a5886 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-07/output @@ -0,0 +1,46 @@ +{ + "id": "hd4vn63li6sd7wfs53zwcpx5mq", + "title": "Example Login Item 07", + "tags": ["tag_1", "tag_2", "tag_3"], + "version": 13, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:51Z", + "updated_at": "2023-09-02T04:58:38Z", + "additional_information": "user_07", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_07", + "reference": "op://Test Data 2/Example Login Item 07/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "_RPhBz3gTvz-fy8huq3e", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 07/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 07/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08/output new file mode 100644 index 00000000..62e77064 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08/output @@ -0,0 +1,45 @@ +{ + "id": "vmgepcg5kvjmvaoytxlrj5ovdq", + "title": "Example Login Item 08", + "version": 6, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:52Z", + "updated_at": "2023-09-05T02:24:15Z", + "additional_information": "user_08", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_08", + "reference": "op://Test Data 2/Example Login Item 08/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "hKQNzuJ_zpLs_GhaK9yG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 08/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 08/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08a/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08a/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08a/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08a/output new file mode 100644 index 00000000..48d016c1 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-08a/output @@ -0,0 +1,46 @@ +{ + "id": "7btkxvemy7stw66piwx5mxnqai", + "title": "Example Login Item 08a", + "tags": ["tag_1", "tag_2", "tag_3", "tag_4", "tag_5"], + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:52Z", + "updated_at": "2023-09-05T03:23:02Z", + "additional_information": "user_08", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_08", + "reference": "op://Test Data 2/Example Login Item 08a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "hKQNzuJ_zpLs_GhaK9yG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 08a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 08a/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-09/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-09/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-09/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-09/output new file mode 100644 index 00000000..fbf0cdc1 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-09/output @@ -0,0 +1,51 @@ +{ + "id": "rcotqz24dvaydkf74cwx4y6dsy", + "title": "Example Login Item 09", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:53Z", + "updated_at": "2023-09-07T02:42:27Z", + "additional_information": "user_09", + "urls": [ + { + "primary": true, + "href": "https://item-09-url.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_09", + "reference": "op://Test Data 2/Example Login Item 09/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "PNwCwYyc8.eG3AnHKaFf", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 09/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 09/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-10/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-10/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-10/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-10/output new file mode 100644 index 00000000..2236abc8 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-10/output @@ -0,0 +1,51 @@ +{ + "id": "i3alx2zdreqy6qbg6mvqlflazy", + "title": "Example Login Item 10", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:30Z", + "updated_at": "2023-09-07T20:48:47Z", + "additional_information": "user_10", + "urls": [ + { + "primary": true, + "href": "https://item-10-url.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_10", + "reference": "op://Test Data 2/Example Login Item 10/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "CMtJCnZ37!Nmncx2M@4Y", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 10/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 10/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-11/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-11/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-11/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-11/output new file mode 100644 index 00000000..c36a650c --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-11/output @@ -0,0 +1,55 @@ +{ + "id": "flljun7noqycy2twqr66nbjreu", + "title": "Example Login Item 11", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:31Z", + "updated_at": "2023-09-07T20:48:50Z", + "additional_information": "user_11", + "urls": [ + { + "primary": true, + "href": "https://item-11-url.com/login.html" + }, + { + "label": "website", + "href": "https://second-website.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_11", + "reference": "op://Test Data 2/Example Login Item 11/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "ftgh@XvMduHE3U3WfX!!", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 11/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 11/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-12/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-12/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-12/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-12/output new file mode 100644 index 00000000..f42dd044 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-12/output @@ -0,0 +1,67 @@ +{ + "id": "ipifsyjdmyeg4e75ujmbkrefl4", + "title": "Example Login Item 12", + "version": 7, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-14T04:25:57Z", + "updated_at": "2023-09-27T01:53:19Z", + "additional_information": "user_12", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "2osfud5e64s66tixoscjylr3fq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_12", + "reference": "op://Test Data 2/Example Login Item 12/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "oKfr2hck_VL482JFs9XP", + "reference": "op://Test Data 2/Example Login Item 12/password", + "password_details": { + "strength": "FANTASTIC", + "history": ["password"] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 12/notesPlain" + }, + { + "id": "h35qui6evukiodlevihezl7jgu", + "section": { + "id": "2osfud5e64s66tixoscjylr3fq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 12/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-13/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-13/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-13/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-13/output new file mode 100644 index 00000000..b8381cae --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-13/output @@ -0,0 +1,69 @@ +{ + "id": "63msonmzjvx7n27zqinjx4u5h4", + "title": "Example Login Item 13", + "version": 12, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:33Z", + "updated_at": "2023-10-06T17:52:44Z", + "additional_information": "user_13", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "mx4kujb6faiznyhp4ymjvllydq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_13", + "reference": "op://Test Data 2/Example Login Item 13/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dWs36w-M-3tx-h9H-rmQ", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 13/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 13/notesPlain" + }, + { + "id": "62odajne7hsbr6wqoiztlqdjpy", + "section": { + "id": "mx4kujb6faiznyhp4ymjvllydq", + "label": "Section 01" + }, + "type": "URL", + "label": "URL Field 01", + "value": "https://new-url.com/login.html", + "reference": "op://Test Data 2/Example Login Item 13/Section 01/URL Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-14/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-14/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-14/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-14/output new file mode 100644 index 00000000..a4e76b82 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-14/output @@ -0,0 +1,69 @@ +{ + "id": "2tnizxhowssne6cwpolz65ib3i", + "title": "Example Login Item 14", + "version": 10, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:34Z", + "updated_at": "2023-09-27T04:51:26Z", + "additional_information": "user_14", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "k447btje43qwchrgyng4z4oqpm", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_14", + "reference": "op://Test Data 2/Example Login Item 14/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "YjCdQrXBX_hmxyb4Y8B6", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 14/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 14/notesPlain" + }, + { + "id": "7oxfe2moewfdbo2qj7u7nqh6im", + "section": { + "id": "k447btje43qwchrgyng4z4oqpm", + "label": "Section 01" + }, + "type": "STRING", + "label": "Password to Text 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 14/Section 01/Password to Text 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-15/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-15/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-15/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-15/output new file mode 100644 index 00000000..2c7a8056 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-15/output @@ -0,0 +1,69 @@ +{ + "id": "rgd62zizqblto72qzwascft66a", + "title": "Example Login Item 15", + "version": 6, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:35Z", + "updated_at": "2023-10-07T22:38:14Z", + "additional_information": "user_15", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "u6evclctwauvlzfzyrre4b3bea", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_15", + "reference": "op://Test Data 2/Example Login Item 15/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "gB.iM7Mtkyypdj!.wADV", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 15/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 15/notesPlain" + }, + { + "id": "f2pwicstfapz3jyssurvokb6uy", + "section": { + "id": "u6evclctwauvlzfzyrre4b3bea", + "label": "Section 01" + }, + "type": "URL", + "label": "Text field to be updated to URL 01", + "value": "https://new-url.com/login.html", + "reference": "op://Test Data 2/Example Login Item 15/Section 01/Text field to be updated to URL 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17/output new file mode 100644 index 00000000..ea795d72 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17/output @@ -0,0 +1,70 @@ +{ + "id": "hiy35xokn76r4qgyrty5sa4v3m", + "title": "Example Login Item 17", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-12T02:42:10Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with no sections or fields. We will add a section and a field.", + "reference": "op://Test Data 2/Example Login Item 17/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17a/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17a/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17a/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17a/output new file mode 100644 index 00000000..15c5cf47 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17a/output @@ -0,0 +1,85 @@ +{ + "id": "w247qmcyxsjwhbfmow3nx2br7i", + "title": "Example Login Item 17a", + "version": 5, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T03:29:55Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_sqookysbfbbltgtlcd2fwip5im", + "label": "Section 01" + }, + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A field with the label we're trying to add\n- A section with a different label from what we're trying to add\n- We will add a section and a field that will be different that the existing section/field pairing", + "reference": "op://Test Data 2/Example Login Item 17a/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 02" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17a/Section 02/Text Field 01" + }, + { + "id": "epc7fzudrbykstzfn4tzrni4de", + "section": { + "id": "Section_sqookysbfbbltgtlcd2fwip5im", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17a/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17b/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17b/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17b/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17b/output new file mode 100644 index 00000000..13d8418c --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17b/output @@ -0,0 +1,81 @@ +{ + "id": "qqptwa42kszxmtwsjlgf5io46q", + "title": "Example Login Item 17b", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T03:42:38Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17b/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17b/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A section with the label from what we're trying to add\n- A field with associated with the above section but a different label we're trying to add\n- We will add a field and the existing section will have a new field for a total of two", + "reference": "op://Test Data 2/Example Login Item 17b/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 02", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17b/Section 01/Text Field 02" + }, + { + "id": "sov5o5wsfmsocflt3px7iftabi", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17b/Section 01/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17c/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17c/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17c/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17c/output new file mode 100644 index 00000000..0e9a2335 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17c/output @@ -0,0 +1,96 @@ +{ + "id": "74iwu2kqb4y2jfrzjl7wbuvyuq", + "title": "Example Login Item 17c", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T17:28:41Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + { + "id": "cbfmyoy2yqyk5mzjrcqmua2nua", + "label": "Section 02" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17c/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17c/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with:\n- A section with the label from what we're trying to add\n- A field with the label we're trying to add, but associated with a different section\n- We will add a field and the existing section will have a new field for a total of two", + "reference": "op://Test Data 2/Example Login Item 17c/notesPlain" + }, + { + "id": "zfe46cwnv5d6vq3vraxarj6lma", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 02", + "value": "not the text field you're looking for", + "reference": "op://Test Data 2/Example Login Item 17c/Section 01/Text Field 02" + }, + { + "id": "uro7bsrmlovxptwnybn3wx5sru", + "section": { + "id": "Section_pxz6aae5he4yqmzznmlonkpziq", + "label": "Section 01" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17c/Section 01/Text Field 01" + }, + { + "id": "7qfvsvf5bsmtqkadymzfnx7xam", + "section": { + "id": "cbfmyoy2yqyk5mzjrcqmua2nua", + "label": "Section 02" + }, + "type": "STRING", + "label": "Text Field 01", + "value": "this is a different text field 01, so there's no collision", + "reference": "op://Test Data 2/Example Login Item 17c/Section 02/Text Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17d/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17d/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17d/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17d/output new file mode 100644 index 00000000..cd168a20 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-17d/output @@ -0,0 +1,60 @@ +{ + "id": "m3dazmnpma6to7ozkpvjdit3f4", + "title": "Example Login Item 17d", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-18T02:30:07Z", + "additional_information": "user_17", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_17", + "reference": "op://Test Data 2/Example Login Item 17d/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "doAWeAgj8KQbZ!g82ZcG", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 17d/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "value": "This item is for testing `OP.item_edit_add_text_field()`\n\nIt starts out with no sections or fields. We will field but no section.", + "reference": "op://Test Data 2/Example Login Item 17d/notesPlain" + }, + { + "id": "4kfhnlrlycpecxspxfswkomrve", + "type": "STRING", + "label": "Text Field With no Section 01", + "value": "new text field value", + "reference": "op://Test Data 2/Example Login Item 17d/Text Field With no Section 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-18/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-18/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-18/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-18/output new file mode 100644 index 00000000..7abe9096 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-18/output @@ -0,0 +1,69 @@ +{ + "id": "3oznm6vzf4bs5mfll62isfewca", + "title": "Example Login Item 18", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-09-07T20:31:37Z", + "updated_at": "2023-10-13T02:36:40Z", + "additional_information": "user_18", + "urls": [ + { + "label": "website", + "primary": true, + "href": "https://example.com/login" + } + ], + "sections": [ + { + "id": "Section_36gbxd5d7uw6uf4jbhgwrbj4da", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_18", + "reference": "op://Test Data 2/Example Login Item 18/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "XCtvmUt3sDdC9s*caACo", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 18/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 18/notesPlain" + }, + { + "id": "6motgcf7n7vq6wjxjwkpyne56y", + "section": { + "id": "Section_36gbxd5d7uw6uf4jbhgwrbj4da", + "label": "Section 01" + }, + "type": "CONCEALED", + "label": "Password Field 01", + "value": "new password field value", + "reference": "op://Test Data 2/Example Login Item 18/Section 01/Password Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/output new file mode 100644 index 00000000..ea4743f1 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/output @@ -0,0 +1,52 @@ +{ + "id": "j3oytnhyz32hqz7t4aogyrfpqy", + "title": "Example Login Item 21a", + "version": 7, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "A47WW2CN6BEMDDS7RXRKBFQIZ4", + "created_at": "2023-10-19T03:56:29Z", + "updated_at": "2023-10-20T03:22:13Z", + "additional_information": "user_22", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_22", + "reference": "op://Test Data 2/Example Login Item 21a/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "kUM.T2UQ7jqJYEkfGHg8", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 21a/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 21a/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/output new file mode 100644 index 00000000..f86d7d76 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/output @@ -0,0 +1,52 @@ +{ + "id": "lqr57j2hoqpthscrxebmrxi3zq", + "title": "Example Login Item 21b", + "version": 3, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "A47WW2CN6BEMDDS7RXRKBFQIZ4", + "created_at": "2023-10-20T04:07:03Z", + "updated_at": "2023-10-20T04:08:07Z", + "additional_information": "user_21", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_21", + "reference": "op://Test Data 2/Example Login Item 21b/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "kUM.T2UQ7jqJYEkfGHg8", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 21b/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 21b/notesPlain" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/error_output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/output new file mode 100644 index 00000000..aef045f6 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/output @@ -0,0 +1,69 @@ +{ + "id": "kpqpwgadvx35sllloe56us3o4q", + "title": "Example Login Item 23", + "version": 4, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "A47WW2CN6BEMDDS7RXRKBFQIZ4", + "created_at": "2023-10-19T03:56:29Z", + "updated_at": "2023-10-31T03:19:11Z", + "additional_information": "user_23", + "urls": [ + { + "label": "website", + "primary": true, + "href": "http://example.com/login.html" + } + ], + "sections": [ + { + "id": "Section_f3iomx2pymbvmpjiywbpbzbyem", + "label": "Section 01" + } + ], + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_23", + "reference": "op://Test Data 2/Example Login Item 23/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "2Eot7M.wk*hwDXCLEtPx", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 23/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 23/notesPlain" + }, + { + "id": "hz6v7d7uzhijvhtkwf2hbrbm3m", + "section": { + "id": "Section_f3iomx2pymbvmpjiywbpbzbyem", + "label": "Section 01" + }, + "type": "URL", + "label": "URL Field 01", + "value": "https://new-url-field.com/", + "reference": "op://Test Data 2/Example Login Item 23/Section 01/URL Field 01" + } + ] +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/list-signed-in-accounts/error_output b/tests/config/mock-op/responses-item-edit/responses-2/list-signed-in-accounts/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/list-signed-in-accounts/output b/tests/config/mock-op/responses-item-edit/responses-2/list-signed-in-accounts/output new file mode 100644 index 00000000..e4d885fe --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/list-signed-in-accounts/output @@ -0,0 +1,20 @@ +[ + { + "url": "example-account.1password.com", + "email": "example_user@example.email", + "user_uuid": "5GHHPJK5HZC5BAT7WDUXW57G44", + "account_uuid": "GRXJAN4BY5DPROISKYL55IRCPY" + }, + { + "url": "my.1password.com", + "email": "guest_user@example.email", + "user_uuid": "DJGTGRFRM5C4BHNUXQLJXQJAOE", + "account_uuid": "6J7RFGQWONBVJHIHJUVICO2C3Q" + }, + { + "url": "pyonepassword.1password.com", + "email": "uid000@gmail.com", + "user_uuid": "4J4NLDK7GFAXJFOR7RF2KDUAMI", + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57" + } +] diff --git a/tests/config/mock-op/responses-item-edit/responses-2/whoami-account-uuid/error_output b/tests/config/mock-op/responses-item-edit/responses-2/whoami-account-uuid/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/whoami-account-uuid/output b/tests/config/mock-op/responses-item-edit/responses-2/whoami-account-uuid/output new file mode 100644 index 00000000..b93856b6 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/whoami-account-uuid/output @@ -0,0 +1,4 @@ +{ + "URL": "https://pyonepassword.1password.com", + "ServiceAccountType": "SERVICE_ACCOUNT" +} diff --git a/tests/config/mock-op/responses-item-edit/responses-2/whoami/error_output b/tests/config/mock-op/responses-item-edit/responses-2/whoami/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-item-edit/responses-2/whoami/output b/tests/config/mock-op/responses-item-edit/responses-2/whoami/output new file mode 100644 index 00000000..b93856b6 --- /dev/null +++ b/tests/config/mock-op/responses-item-edit/responses-2/whoami/output @@ -0,0 +1,4 @@ +{ + "URL": "https://pyonepassword.1password.com", + "ServiceAccountType": "SERVICE_ACCOUNT" +} diff --git a/tests/config/mock-op/responses-svc-acct-corrupt/list-signed-in-accounts/output b/tests/config/mock-op/responses-svc-acct-corrupt/list-signed-in-accounts/output index 96e77ec7..f83f2c73 100644 --- a/tests/config/mock-op/responses-svc-acct-corrupt/list-signed-in-accounts/output +++ b/tests/config/mock-op/responses-svc-acct-corrupt/list-signed-in-accounts/output @@ -9,7 +9,7 @@ "url": "pyonepassword.1password.com", "email": "uid000@gmail.com", "user_uuid": "4J4NLDK7GFAXJFOR7RF2KDUAMI", - "account_uuid": "EFXK4GL42ZAFJP2Q4ZPD6ECLEE" + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57" }, { "url": "my.1password.com", diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-1.json b/tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-1.json new file mode 100644 index 00000000..6044d31a --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-1.json @@ -0,0 +1,37 @@ +{ + "meta": { + "response_dir": "tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1", + "input_dir": "input" + }, + "commands": { + "--version": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "cli-version", + "changes_state": false + }, + "--format|json|account|list": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "list-signed-in-accounts", + "changes_state": false + }, + "--format|json|item|template|list": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-template-list", + "changes_state": true + }, + "--format|json|whoami": { + "exit_status": 1, + "stdout": "output", + "stderr": "error_output", + "name": "whoami", + "changes_state": false + } + }, + "commands_with_input": {} +} diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-2.json b/tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-2.json new file mode 100644 index 00000000..124879f2 --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-2.json @@ -0,0 +1,30 @@ +{ + "meta": { + "response_dir": "tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2", + "input_dir": "input" + }, + "commands": { + "--version": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "cli-version", + "changes_state": false + }, + "--format|json|account|list": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "list-signed-in-accounts", + "changes_state": false + }, + "--format|json|whoami": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "whoami", + "changes_state": false + } + }, + "commands_with_input": {} +} \ No newline at end of file diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/cli-version/error_output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/cli-version/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/cli-version/output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/cli-version/output new file mode 100644 index 00000000..7329e21c --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/cli-version/output @@ -0,0 +1 @@ +2.20.0 diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/item-template-list/error_output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/item-template-list/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/item-template-list/output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/item-template-list/output new file mode 100644 index 00000000..3c2cc672 --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/item-template-list/output @@ -0,0 +1,90 @@ +[ + { + "uuid": "106", + "name": "Passport" + }, + { + "uuid": "101", + "name": "Bank Account" + }, + { + "uuid": "102", + "name": "Database" + }, + { + "uuid": "004", + "name": "Identity" + }, + { + "uuid": "001", + "name": "Login" + }, + { + "uuid": "113", + "name": "Medical Record" + }, + { + "uuid": "105", + "name": "Membership" + }, + { + "uuid": "104", + "name": "Outdoor License" + }, + { + "uuid": "005", + "name": "Password" + }, + { + "uuid": "107", + "name": "Reward Program" + }, + { + "uuid": "100", + "name": "Software License" + }, + { + "uuid": "114", + "name": "SSH Key" + }, + { + "uuid": "112", + "name": "API Credential" + }, + { + "uuid": "002", + "name": "Credit Card" + }, + { + "uuid": "115", + "name": "Crypto Wallet" + }, + { + "uuid": "103", + "name": "Driver License" + }, + { + "uuid": "110", + "name": "Server" + }, + { + "uuid": "108", + "name": "Social Security Number" + }, + { + "uuid": "006", + "name": "Document" + }, + { + "uuid": "111", + "name": "Email Account" + }, + { + "uuid": "109", + "name": "Wireless Router" + }, + { + "uuid": "003", + "name": "Secure Note" + } +] diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/list-signed-in-accounts/error_output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/list-signed-in-accounts/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/list-signed-in-accounts/output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/list-signed-in-accounts/output new file mode 100644 index 00000000..f53aa7e1 --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/list-signed-in-accounts/output @@ -0,0 +1,9 @@ +[ + { + "url": "https://example-account.1password.com", + "email": "example_user@example.email", + "user_uuid": "5GHHPJK5HZC5BAT7WDUXW57G44", + "account_uuid": "GRXJAN4BY5DPROISKYL55IRCPY", + "shorthand": "example_shorthand" + } +] diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/whoami/error_output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/whoami/error_output new file mode 100644 index 00000000..b3a5258a --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/whoami/error_output @@ -0,0 +1 @@ +[ERROR] 2023/08/29 12:30:21 service account token set, but not authenticated yet diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/whoami/output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-1/whoami/output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/cli-version/error_output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/cli-version/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/cli-version/output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/cli-version/output new file mode 100644 index 00000000..7329e21c --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/cli-version/output @@ -0,0 +1 @@ +2.20.0 diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/list-signed-in-accounts/error_output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/list-signed-in-accounts/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/list-signed-in-accounts/output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/list-signed-in-accounts/output new file mode 100644 index 00000000..f53aa7e1 --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/list-signed-in-accounts/output @@ -0,0 +1,9 @@ +[ + { + "url": "https://example-account.1password.com", + "email": "example_user@example.email", + "user_uuid": "5GHHPJK5HZC5BAT7WDUXW57G44", + "account_uuid": "GRXJAN4BY5DPROISKYL55IRCPY", + "shorthand": "example_shorthand" + } +] diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/whoami/error_output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/whoami/error_output new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/whoami/output b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/whoami/output new file mode 100644 index 00000000..00835ca8 --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/responses-2/whoami/output @@ -0,0 +1,6 @@ +{ + "url": "https://pyonepassword.1password.com", + "user_uuid": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57", + "user_type": "SERVICE_ACCOUNT" +} diff --git a/tests/config/mock-op/responses-svc-acct-not-yet-auth/svc-acct-not-yet-auth-state-config.json b/tests/config/mock-op/responses-svc-acct-not-yet-auth/svc-acct-not-yet-auth-state-config.json new file mode 100644 index 00000000..692a5612 --- /dev/null +++ b/tests/config/mock-op/responses-svc-acct-not-yet-auth/svc-acct-not-yet-auth-state-config.json @@ -0,0 +1,20 @@ +{ + "iteration": 0, + "max-iterations": 2, + "state-list": [ + { + "response-directory": "tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-1.json", + "env-vars": { + "set": {}, + "pop": [] + } + }, + { + "response-directory": "tests/config/mock-op/responses-svc-acct-not-yet-auth/response-directory-2.json", + "env-vars": { + "set": {}, + "pop": [] + } + } + ] +} \ No newline at end of file diff --git a/tests/config/mock-op/responses-svc-acct-revoked-token/list-signed-in-accounts/output b/tests/config/mock-op/responses-svc-acct-revoked-token/list-signed-in-accounts/output index 70ad486a..b7541db9 100644 --- a/tests/config/mock-op/responses-svc-acct-revoked-token/list-signed-in-accounts/output +++ b/tests/config/mock-op/responses-svc-acct-revoked-token/list-signed-in-accounts/output @@ -15,6 +15,6 @@ "url": "pyonepassword.1password.com", "email": "uid000@gmail.com", "user_uuid": "4J4NLDK7GFAXJFOR7RF2KDUAMI", - "account_uuid": "EFXK4GL42ZAFJP2Q4ZPD6ECLEE" + "account_uuid": "M5C4BT3KMQ7HROISKYLWDUXW57" } ] diff --git a/tests/config/mock-op/svc-acct-not-yet-auth-directory.json b/tests/config/mock-op/svc-acct-not-yet-auth-directory.json new file mode 100644 index 00000000..3f93c802 --- /dev/null +++ b/tests/config/mock-op/svc-acct-not-yet-auth-directory.json @@ -0,0 +1,37 @@ +{ + "meta": { + "response_dir": "tests/config/mock-op/responses-svc-acct-not-yet-auth", + "input_dir": "input" + }, + "commands": { + "--version": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "cli-version", + "changes_state": false + }, + "--format|json|account|list": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "list-signed-in-accounts", + "changes_state": false + }, + "--format|json|whoami": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "whoami-authenticated", + "changes_state": false + }, + "--format|json|item|template|list": { + "exit_status": 0, + "stdout": "output", + "stderr": "error_output", + "name": "item-template-list", + "changes_state": false + } + }, + "commands_with_input": {} +} \ No newline at end of file diff --git a/tests/data/expected-data/expected-item-data/example-login-item-01-edited.json b/tests/data/expected-data/expected-item-data/example-login-item-01-edited.json new file mode 100644 index 00000000..c77a85c7 --- /dev/null +++ b/tests/data/expected-data/expected-item-data/example-login-item-01-edited.json @@ -0,0 +1,48 @@ +{ + "id": "zvf66fm3j6qjhxqkryxnw6dv4q", + "title": "Example Login Item 01", + "version": 2, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:46Z", + "updated_at": "2023-08-22T22:17:38Z", + "additional_information": "user_01", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_01", + "reference": "op://Test Data 2/Example Login Item 01/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "dRxrkayEh6Xb88UKVYpX", + "entropy": 115.52911376953125, + "reference": "op://Test Data 2/Example Login Item 01/password", + "password_details": { + "entropy": 115, + "generated": true, + "strength": "FANTASTIC", + "history": [ + "GN9Tsv..d7NB3vkh.Ucx" + ] + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 01/notesPlain" + } + ] +} diff --git a/tests/data/expected-data/expected-item-data/example-login-item-01-original.json b/tests/data/expected-data/expected-item-data/example-login-item-01-original.json new file mode 100644 index 00000000..4a38d22c --- /dev/null +++ b/tests/data/expected-data/expected-item-data/example-login-item-01-original.json @@ -0,0 +1,45 @@ +{ + "id": "zvf66fm3j6qjhxqkryxnw6dv4q", + "title": "Example Login Item 01", + "version": 1, + "vault": { + "id": "vkjyqsbkf63zycqigbg3yxd7ce", + "name": "Test Data 2" + }, + "category": "LOGIN", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", + "created_at": "2023-08-22T22:14:46Z", + "updated_at": "2023-08-22T22:14:46Z", + "additional_information": "user_01", + "fields": [ + { + "id": "username", + "type": "STRING", + "purpose": "USERNAME", + "label": "username", + "value": "user_01", + "reference": "op://Test Data 2/Example Login Item 01/username" + }, + { + "id": "password", + "type": "CONCEALED", + "purpose": "PASSWORD", + "label": "password", + "value": "GN9Tsv..d7NB3vkh.Ucx", + "entropy": 118.28331756591797, + "reference": "op://Test Data 2/Example Login Item 01/password", + "password_details": { + "entropy": 118, + "generated": true, + "strength": "FANTASTIC" + } + }, + { + "id": "notesPlain", + "type": "STRING", + "purpose": "NOTES", + "label": "notesPlain", + "reference": "op://Test Data 2/Example Login Item 01/notesPlain" + } + ] +} diff --git a/tests/data/expected-data/expected-item-data/registry.json b/tests/data/expected-data/expected-item-data/registry.json index 75ca8851..603f019d 100644 --- a/tests/data/expected-data/expected-item-data/registry.json +++ b/tests/data/expected-data/expected-item-data/registry.json @@ -122,5 +122,17 @@ "t4gp6e7s6xtsiu35xq5cewxqpi": { "name": "t4gp6e7s6xtsiu35xq5cewxqpi.json", "type": "json" + }, + "Example Login Item 01": { + "versions": [ + { + "name": "example-login-item-01-original.json", + "type": "json" + }, + { + "name": "example-login-item-01-edited.json", + "type": "json" + } + ] } } diff --git a/tests/fixtures/expected_login.py b/tests/fixtures/expected_login.py index 484e11a9..c8481035 100644 --- a/tests/fixtures/expected_login.py +++ b/tests/fixtures/expected_login.py @@ -25,7 +25,15 @@ def username(self) -> str: @property def password(self) -> str: - return self._data["password"] + password = None + try: + password = self._data["password"] + except KeyError: + # some expected data objects may not have a "password" key + # but may have a passsword field dictionary + password_field = self.field_by_id("password") + password = password_field.value + return password @property def urls(self): @@ -43,7 +51,7 @@ def primary_url(self): class ExpectedLoginItemData(ExpectedItemData): - def data_for_login(self, login_identifier) -> ExpectedLogin: - item_dict = self.data_for_name(login_identifier) + def data_for_login(self, login_identifier, version=0) -> ExpectedLogin: + item_dict = self.data_for_name(login_identifier, version=version) login_item = ExpectedLogin(item_dict) return login_item diff --git a/tests/fixtures/op_fixtures.py b/tests/fixtures/op_fixtures.py index 7d0c8b9c..fdb6a879 100644 --- a/tests/fixtures/op_fixtures.py +++ b/tests/fixtures/op_fixtures.py @@ -42,8 +42,10 @@ ALT_RESP_DIRECTORY_PATH, ITEM_DELETE_MULTIPLE_STATE_CONFIG_PATH, ITEM_DELETE_MULTIPLE_TITLE_GLOB_STATE_CONFIG_PATH, + ITEM_EDIT_STATE_CONFIG_PATH, RESP_DIRECTORY_PATH, SVC_ACCT_CORRUPT_RESP_DIRECTORY_PATH, + SVC_ACCT_NOT_YET_AUTH_STATE_CONFIG_PATH, SVC_ACCT_RESP_DIRECTORY_PATH, SVC_ACCT_REVOKED_RESP_DIRECTORY_PATH, UNAUTH_RESP_DIRECTORY_PATH @@ -157,15 +159,17 @@ def setup_stateful_item_delete_multiple(): # set up a temporary directory to copy the state config to, since it gets modified # during state iteration + config_file_name = ITEM_DELETE_MULTIPLE_STATE_CONFIG_PATH.name temp_dir = tempfile.TemporaryDirectory() state_config_dir = temp_dir.name - state_config_path = Path(state_config_dir, "config.json") + state_config_path = Path(state_config_dir, config_file_name) shutil.copyfile(ITEM_DELETE_MULTIPLE_STATE_CONFIG_PATH, state_config_path) # now pop MOCK_OP_RESPONSE_DIRECTORY to ensure it doesn't conflict with with # the stateful config old_mock_op_resp_dir = os.environ.pop("MOCK_OP_RESPONSE_DIRECTORY", None) - os.environ["MOCK_OP_STATE_DIR"] = state_config_dir + + os.environ["MOCK_OP_STATE_DIR"] = str(state_config_path) yield # pytest will return us here after the test runs # get rid of MOCK_OP_STATE_DIR os.environ.pop("MOCK_OP_STATE_DIR") @@ -182,16 +186,71 @@ def setup_stateful_item_delete_multiple_title_glob(): # set up a temporary directory to copy the state config to, since it gets modified # during state iteration + config_file_name = ITEM_DELETE_MULTIPLE_TITLE_GLOB_STATE_CONFIG_PATH.name temp_dir = tempfile.TemporaryDirectory() state_config_dir = temp_dir.name - state_config_path = Path(state_config_dir, "config.json") + state_config_path = Path(state_config_dir, config_file_name) shutil.copyfile( ITEM_DELETE_MULTIPLE_TITLE_GLOB_STATE_CONFIG_PATH, state_config_path) # now pop MOCK_OP_RESPONSE_DIRECTORY to ensure it doesn't conflict with with # the stateful config old_mock_op_resp_dir = os.environ.pop("MOCK_OP_RESPONSE_DIRECTORY", None) - os.environ["MOCK_OP_STATE_DIR"] = state_config_dir + os.environ["MOCK_OP_STATE_DIR"] = str(state_config_path) + yield # pytest will return us here after the test runs + # get rid of MOCK_OP_STATE_DIR + os.environ.pop("MOCK_OP_STATE_DIR") + + # restore MOCK_OP_RESPONSE_DIRECTORY if it was previously set + if old_mock_op_resp_dir is not None: + os.environ["MOCK_OP_RESPONSE_DIRECTORY"] = old_mock_op_resp_dir + + # temp_dir will get cleaned up once we return + + +@fixture +def setup_stateful_item_edit(): + + # set up a temporary directory to copy the state config to, since it gets modified + # during state iteration + config_file_name = ITEM_EDIT_STATE_CONFIG_PATH.name + temp_dir = tempfile.TemporaryDirectory() + state_config_dir = temp_dir.name + state_config_path = Path(state_config_dir, config_file_name) + shutil.copyfile( + ITEM_EDIT_STATE_CONFIG_PATH, state_config_path) + + # now pop MOCK_OP_RESPONSE_DIRECTORY to ensure it doesn't conflict with with + # the stateful config + old_mock_op_resp_dir = os.environ.pop("MOCK_OP_RESPONSE_DIRECTORY", None) + os.environ["MOCK_OP_STATE_DIR"] = str(state_config_path) + yield # pytest will return us here after the test runs + # get rid of MOCK_OP_STATE_DIR + os.environ.pop("MOCK_OP_STATE_DIR") + + # restore MOCK_OP_RESPONSE_DIRECTORY if it was previously set + if old_mock_op_resp_dir is not None: + os.environ["MOCK_OP_RESPONSE_DIRECTORY"] = old_mock_op_resp_dir + + # temp_dir will get cleaned up once we return + + +@fixture +def setup_stateful_svc_acct_auth(): + config_file_name = SVC_ACCT_NOT_YET_AUTH_STATE_CONFIG_PATH.name + temp_dir = tempfile.TemporaryDirectory() + state_config_dir = temp_dir.name + state_config_path = Path(state_config_dir, config_file_name) + shutil.copyfile(SVC_ACCT_NOT_YET_AUTH_STATE_CONFIG_PATH, state_config_path) + + # now pop MOCK_OP_RESPONSE_DIRECTORY to ensure it doesn't conflict with with + # the stateful config + old_mock_op_resp_dir = os.environ.pop("MOCK_OP_RESPONSE_DIRECTORY", None) + os.environ["MOCK_OP_STATE_DIR"] = str(state_config_path) + + svc_account_token = os.environ["PYTEST_SVC_ACCT_TOKEN"] + os.environ["OP_SERVICE_ACCOUNT_TOKEN"] = svc_account_token + os.environ["LOG_OP_ERR"] = "1" yield # pytest will return us here after the test runs # get rid of MOCK_OP_STATE_DIR os.environ.pop("MOCK_OP_STATE_DIR") diff --git a/tests/fixtures/paths.py b/tests/fixtures/paths.py index ddd44acc..eb198359 100644 --- a/tests/fixtures/paths.py +++ b/tests/fixtures/paths.py @@ -16,6 +16,14 @@ ITEM_DELETE_MULTIPLE_TITLE_GLOB_STATE_CONFIG_PATH = Path( ITEM_DELETE_MULTIPLE_RESP_PATH, "mock-op-state-config-2.json") +ITEM_EDIT_RESP_PATH = Path( + MOCK_OP_CONFIG_PATH, "responses-item-edit" +) +ITEM_EDIT_STATE_CONFIG_PATH = Path( + ITEM_EDIT_RESP_PATH, "item-edit-state-config.json" +) + + UNAUTH_RESP_DIRECTORY_PATH = Path( MOCK_OP_CONFIG_PATH, "unauth-response-directory.json") @@ -28,6 +36,12 @@ SVC_ACCT_REVOKED_RESP_DIRECTORY_PATH = Path( MOCK_OP_CONFIG_PATH, "svc-acct-revoked-token-directory.json" ) +SVC_ACCT_NOT_YET_AUTH_RESP_PATH = Path( + MOCK_OP_CONFIG_PATH, "responses-svc-acct-not-yet-auth" +) +SVC_ACCT_NOT_YET_AUTH_STATE_CONFIG_PATH = Path( + SVC_ACCT_NOT_YET_AUTH_RESP_PATH, "svc-acct-not-yet-auth-state-config.json" +) VALID_DATA_REGISTRY_PATH = Path( TEST_INPUT_DATA_PATH, "valid-data-registry.json") diff --git a/tests/fixtures/valid_data.py b/tests/fixtures/valid_data.py index a9dab4fd..7cbc5a88 100644 --- a/tests/fixtures/valid_data.py +++ b/tests/fixtures/valid_data.py @@ -41,8 +41,11 @@ def _load_text_or_json(self, item_path, item_type, strip): data = data.rstrip() return data - def data_for_name(self, entry_name): + def data_for_name(self, entry_name, version=0): entry: Dict = self._registry[entry_name] + if "versions" in entry: + entry = entry["versions"][version] + item_filename = entry["name"] item_type = entry["type"] strip = entry.get("strip", False) diff --git a/tests/test_auth_scenarios/test_existing_auth.py b/tests/test_auth_scenarios/test_existing_auth.py index 44ff0d74..8701b793 100644 --- a/tests/test_auth_scenarios/test_existing_auth.py +++ b/tests/test_auth_scenarios/test_existing_auth.py @@ -20,7 +20,7 @@ @pytest.mark.usefixtures("valid_op_cli_config_homedir") @pytest.mark.usefixtures("setup_unauth_op_env") -def test_use_existing_session_01(): +def test_existing_auth_01(): """ Simulate an pyonepassword environment that doesn't use biometric auth, and doesn't have OP_SESSION_ env variable set @@ -32,19 +32,19 @@ def test_use_existing_session_01(): @pytest.mark.usefixtures("valid_op_cli_config_homedir") @pytest.mark.usefixtures("setup_op_sess_var_alt_env") -def test_use_existing_session_02(): +def test_existing_auth_02(): """ Simulate a pyonepassword environment that: - doesn't use biometric - DOES have OP_SESSION_ env variable set - Check that OP(use_existing_session=True) succeeds + Check that OP(existing_auth=EXISTING_AUTH_AVAIL) succeeds """ OP(op_path='mock-op', existing_auth=EXISTING_AUTH_AVAIL, password_prompt=False) @pytest.mark.usefixtures("valid_op_cli_config_homedir") @pytest.mark.usefixtures("setup_op_sess_var_unauth_env") -def test_use_existing_session_03(): +def test_existing_auth_03(): """ Simulate a pyonepassword environment that: - doesn't use biometric @@ -52,7 +52,7 @@ def test_use_existing_session_03(): - session token not valid Tell OP to use an exsiting session if available, but don't provide a password - Check that OP(use_existing_session=True) fails + Check that OP(existing_auth=EXISTING_AUTH_AVAIL) fails """ with pytest.raises(OPAuthenticationException): _ = OP(op_path='mock-op', existing_auth=EXISTING_AUTH_AVAIL, @@ -61,7 +61,7 @@ def test_use_existing_session_03(): @pytest.mark.usefixtures("valid_op_cli_config_no_shorthand") @pytest.mark.usefixtures("setup_op_sess_var_alt_env") -def test_use_existing_session_04(): +def test_existing_auth_04(): """ Simulate a pyonepassword environment that: - no "latest_signin" to infer account identifier from @@ -77,14 +77,14 @@ def test_use_existing_session_04(): @pytest.mark.usefixtures("valid_op_cli_config_homedir") @pytest.mark.usefixtures("setup_op_sess_var_unauth_env") -def test_use_existing_session_05(): +def test_existing_auth_05(): """ Simulate a pyonepassword environment that: - doesn't use biometric - DOES have OP_SESSION_ env variable set - session token not valid Tell OP it MUST use an existing session. - Check that OP(use_existing_session=True) fails + Check that OP(existing_auth=EXISTING_AUTH_REQD) fails """ with pytest.raises(OPAuthenticationException): OP(op_path='mock-op', existing_auth=EXISTING_AUTH_REQD, diff --git a/tests/test_auth_scenarios/test_svc_account.py b/tests/test_auth_scenarios/test_svc_account.py index 95c95a69..4c7dd435 100644 --- a/tests/test_auth_scenarios/test_svc_account.py +++ b/tests/test_auth_scenarios/test_svc_account.py @@ -5,12 +5,13 @@ import pytest from pyonepassword import OP +from pyonepassword.api.authentication import EXISTING_AUTH_REQD from pyonepassword.api.exceptions import OPCmdFailedException @pytest.mark.usefixtures("valid_op_cli_config_homedir") @pytest.mark.usefixtures("setup_svc_acct_env") -def test_svc_acct_auth_01(console_logger): +def test_svc_acct_auth_010(console_logger): """ Simulate an pyonepassword environment that has a service account token set via the OP_SERVICE_ACCOUNT_TOKEN environment variable @@ -23,3 +24,28 @@ def test_svc_acct_auth_01(console_logger): except OPCmdFailedException as e: print(e.err_output) assert False, f"OP() raised an exception {e}" + + +@pytest.mark.usefixtures("valid_op_cli_config_homedir") +@pytest.mark.usefixtures("setup_stateful_svc_acct_auth") +def test_svc_account_not_yet_auth_020(console_logger): + """ + In 'op' version >= 2.20.0, if a successful operation hasn't been completed in the past + 30 minutes, 'whoami' will fail with "not yet authenticated" + + Simulate a pyonepassword environment that has a service account token set + via the OP_SERVICE_ACCOUNT_TOKEN environment variable + + Using a stateful response directory, simulate: + - 'op whoami' failing with a "not yet authenticated" error + - 'op item template list' triggering svc account authentication + - 'op whoami' succeeding + + Verify that an OP() object can be instantiated + + NOTE: This test currently doesn't ensure that: + - 'op whoami' fails the first itme + - the 'op item template list' followed by a second 'op whoami' get executed + """ + assert OP(op_path="mock-op", logger=console_logger, + existing_auth=EXISTING_AUTH_REQD) diff --git a/tests/test_deprecation_warnings.py b/tests/test_deprecation_warnings.py index cd46f4f0..1dee9f9f 100644 --- a/tests/test_deprecation_warnings.py +++ b/tests/test_deprecation_warnings.py @@ -1,27 +1,55 @@ +from __future__ import annotations + import warnings +from typing import TYPE_CHECKING +from pyonepassword.api.object_types import OPLoginItem -def test_api_deprecation_01(): - """ - Import deprecated OPNotSignedInException class from - pyonepassword.api.exceptions +if TYPE_CHECKING: + from .fixtures.valid_data import ValidData +# disabled but left as example +# def example_test_import_deprecation_01(): +# """ +# Import deprecated OPNotSignedInException class from +# pyonepassword.api.exceptions - Ensure there is a deprecation warning - """ - with warnings.catch_warnings(record=True) as warning_list: - from pyonepassword.api.exceptions import \ - OPNotSignedInException # noqa: F401 - assert warning_list +# Ensure there is a deprecation warning +# """ +# with warnings.catch_warnings(record=True) as warning_list: +# from pyonepassword.api.exceptions import \ +# OPNotSignedInException # noqa: F401 +# assert warning_list +# disabled but left as example +# @pytest.mark.usefixtures("valid_op_cli_config_homedir") +# @pytest.mark.usefixtures("setup_op_sess_var_alt_env") +# def example_test_kwarg_deprecation_01(): +# """ +# Simulate a pyonepassword environment that: +# - doesn't use biometric +# - DOES have OP_SESSION_ env variable set +# Check that OP(use_existing_session=True) produces deprecation warnings +# """ +# with warnings.catch_warnings(record=True) as warning_list: +# OP(op_path='mock-op', use_existing_session=True, password_prompt=False) +# assert warning_list +# print(f"warning_list: {len(warning_list)}") -def test_api_deprecation_02(): + +def test_deprecated_method_01(valid_data: ValidData, expected_login_item_data): """ - Import deprecated OPNotSignedInException class from - pyonepassword.py_op_exceptions + OPAbstractItem.field_value_by_section_title() has been replaced with + field_value_by_section_label() - Ensure there is a deprecation warning + Verify a deprecation warning is generated """ - with warnings.catch_warnings(record=True) as warning_list: - from pyonepassword.py_op_exceptions import \ - OPNotSignedInException # noqa: F401 - assert warning_list + field_label = "Example Field" + section_label = "Example Section 1" + + valid_item_dict = valid_data.data_for_name("example-login-with-fields") + result_login_item = OPLoginItem(valid_item_dict) + + with warnings.catch_warnings(record=True) as warnings_list: + result_login_item.field_value_by_section_title( + section_label, field_label) + assert len(warnings_list) > 0 diff --git a/tests/test_item_edit/test_field_assignment.py b/tests/test_item_edit/test_field_assignment.py new file mode 100644 index 00000000..2bbb6ab4 --- /dev/null +++ b/tests/test_item_edit/test_field_assignment.py @@ -0,0 +1,225 @@ +from pyonepassword._field_assignment import ( + OPFieldAssignmentDelete, + OPFieldAssignmentPassword, + OPFieldAssignmentText, + OPFieldAssignmentURL +) + + +def test_field_type_030(): + """ + Create a field assignment string using: + - a section label + - a field label + - field type "url" + Verify: + the resulting field assignment string matches the expected string + """ + expected_assignment_str = "Section 030.Field 030[url]=https://fake-url/etc.etc.etc." + + section_label = "Section 030" + field_label = "Field 030" + value = "https://fake-url/etc.etc.etc." + + assignment = OPFieldAssignmentURL( + field_label, value, section_label=section_label) + + assert expected_assignment_str == assignment + + +def test_field_type_password_040(): + """ + Create a field assignment string using: + - a section label + - a field label + - OPFieldAssignmentPassword class + Verify: + the resulting field assignment string matches the expected string + """ + expected_assignment_str = "Section 040.Field 040[password]=Password 040" + + section_label = "Section 040" + field_label = "Field 040" + value = "Password 040" + + assignment = OPFieldAssignmentPassword( + field_label, value, section_label=section_label) + + assert expected_assignment_str == assignment + + +def test_field_type_password_050(): + """ + Create a field assignment string using: + - No section label + - a field label + - OPFieldAssignmentPassword class + Verify: + the resulting field assignment string matches the expected string + """ + expected_assignment_str = "Field 050[password]=Password 050" + + field_label = "Field 050" + value = "Password 050" + + assignment = OPFieldAssignmentPassword(field_label, value) + + assert expected_assignment_str == assignment + + +def test_field_type_text_060(): + """ + Create a field assignment string using: + - a section label + - a field label + - field type "text" + Verify: + the resulting field assignment string matches the expected string + """ + expected_assignment_str = "Section 060.Field 060[text]=String 060" + + section_label = "Section 060" + field_label = "Field 060" + value = "String 060" + + assignment = OPFieldAssignmentText( + field_label, value, section_label=section_label) + + assert expected_assignment_str == assignment + + +def test_field_assignment_escape_100(): + """ + Create a field assignment string using: + - a section label containing '=' characters + - a field label + - a password containing '=' characters + - OPFieldAssignmentPassword class + Verify: + - The resulting field assignment contains properly escaped '=' characters in the section label + - The '=' characters in the password are not escaped + + Note: Part of the purpose of this test case is to exercise character escaping in section labels + separately from character escaping in field labels + """ + section_label = "Section=With=Equals" + field_label = "Field 100" + value = "Password=With=Equals 100" + + expected_escaped_string = r"Section\=With\=Equals.Field 100[password]=Password=With=Equals 100" + assignment = OPFieldAssignmentPassword( + field_label, value, section_label=section_label) + + assert expected_escaped_string == assignment + + +def test_field_assignment_escape_110(): + """ + Create a field assignment string using: + - a section label + - a field label containting '=' characters + - a password containing '=' characters + - OPFieldAssignmentPassword class + Verify: + - The resulting field assignment contains properly escaped '=' characters in the field label + - The '=' characters in the password are not escaped + Note: Part of the purpose of this test case is to exercise character escaping in field labels + separately from character escaping in section labels + """ + section_label = "Section 110" + field_label = "Field=With=Equals 110" + value = "Password=With=Equals 110" + + expected_escaped_string = r"Section 110.Field\=With\=Equals 110[password]=Password=With=Equals 110" + assignment = OPFieldAssignmentPassword( + field_label, value, section_label=section_label) + + assert expected_escaped_string == assignment + + +def test_field_assignment_escape_120(): + """ + Create a field assignment string using: + - a section label containing '.' characters + - a field label containting '.' characters + - OPFieldAssignmentPassword class + Verify: + - The resulting field assignment contains properly escaped '.' characters in the + field and section labels + """ + section_label = "Section.With.Periods 120" + field_label = "Field.With.Periods 120" + value = "Password 120" + + expected_escaped_string = r"Section\.With\.Periods 120.Field\.With\.Periods 120[password]=Password 120" + + assignment = OPFieldAssignmentPassword( + field_label, value, section_label=section_label) + + assert expected_escaped_string == assignment + + +def test_field_assignment_escape_130(): + """ + Create a field assignment string using: + - a section label containing backslash characters + - a field label containting backslash characters + - OPFieldAssignmentPassword class + Verify: + - The resulting field assignment contains properly escaped '.' characters in the + field and section labels + """ + section_label = r"Section\With\Backslashes 120" + field_label = r"Field\With\Backslashes 120" + + value = "Password 120" + + expected_escaped_string = r"Section\\With\\Backslashes 120.Field\\With\\Backslashes 120[password]=Password 120" + + assignment = OPFieldAssignmentPassword( + field_label, value, section_label=section_label) + + assert expected_escaped_string == assignment + + +def test_field_type_password_redaction_140(): + """ + Create a field assignment string using: + - A section label + - A field label + - OPFieldAssignmentPassword class + Verify: + A string copy of the resulting field assignment appropriately redacts the password + """ + # this is intentially an equals emoji + # to prevent the redacted string from + # accidentally being used as an assignment -------------v + expected_redacted_str = "Section 140.Field 140[password]🟰************" + + section_label = "Section 140" + field_label = "Field 140" + value = "Password 140" + + assignment = OPFieldAssignmentPassword( + field_label, value, section_label=section_label) + + assert expected_redacted_str == str(assignment) + + +def test_field_assignment_delete_150(): + """ + Create a field assignment string using: + - a section label + - a field label + - OPFieldAssignmentDelete class + Verify: + the resulting field assignment string matches the expected string + """ + section_label = "Section 150" + field_label = "Field 150" + expected_assignment_str = "Section 150.Field 150[delete]" + + assignment = OPFieldAssignmentDelete( + field_label, section_label=section_label) + + assert expected_assignment_str == assignment diff --git a/tests/test_item_edit/test_item_edit.py b/tests/test_item_edit/test_item_edit.py new file mode 100644 index 00000000..57c7c079 --- /dev/null +++ b/tests/test_item_edit/test_item_edit.py @@ -0,0 +1,516 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from pyonepassword.api.object_types import OPPasswordRecipe + +if TYPE_CHECKING: + from pyonepassword import OP + from pyonepassword.api.object_types import OPLoginItem + + from ..fixtures.expected_login import ExpectedLogin, ExpectedLoginItemData + +# ensure HOME env variable is set, and there's a valid op config present +pytestmark = pytest.mark.usefixtures("valid_op_cli_config_homedir") + + +def _get_item_password(item: OPLoginItem, field_label: str = "password", section_label: str = None): + section = None + if section_label: + section = item.first_section_by_label(section_label) + + if section: + field = section.first_field_by_label(field_label) + else: + field = item.first_field_by_label(field_label) + + password = field.value + return password + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_password_010(signed_in_op: OP): + """ + Test: OP.item_edit_set_password() + - Retrieve an item via OP.item_get() + - Call item_edit_set_password(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's password is not equal to the desired new password + - The returned edited item's password is the same as newly retrieved item's password + - The newly retrieved item's password is the same as the desired new password + + """ + + item_name = "Example Login Item 00" + field_label = "password" + new_password = "new password" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert item_get_1.password != new_password + + edited_item = signed_in_op.item_edit_set_password(item_name, + new_password, + field_label=field_label, + insecure_operation=True, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert edited_item.password == item_get_2.password + assert item_get_2.password == new_password + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_password_015(signed_in_op: OP): + """ + Test: OP.item_edit_set_password() + - Retrieve an item via OP.item_get() + - Call item_edit_set_password(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's password is not equal to the desired new password + - The returned edited item's password is the same as newly retrieved item's password + - The newly retrieved item's password is the same as the desired new password + + """ + + item_name = "Example Login Item 03" + section_label = "Example Section" + field_label = "password in a section" + new_password = "new password in a section" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + item_get_password_1 = _get_item_password( + item_get_1, field_label=field_label, section_label=section_label) + + assert item_get_password_1 != new_password + + edited_item = signed_in_op.item_edit_set_password(item_name, + new_password, + field_label=field_label, + section_label=section_label, + insecure_operation=True, + vault=vault) + + edited_item_password = _get_item_password( + edited_item, field_label=field_label, section_label=section_label) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + item_get_password_2 = _get_item_password( + item_get_2, field_label=field_label, section_label=section_label) + + assert edited_item_password == item_get_password_2 + assert item_get_password_2 == new_password + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_gen_password_020(signed_in_op: OP, + expected_login_item_data: ExpectedLoginItemData): + """ + Test: OP.item_edit_generate_password() + - Retrieve an item via OP.item_get() + - Call item_edit_generate_password(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's password matches the expected original password + - The returned edited item's password is not the same as the original item's password + - The newly retrieved item's password matches the expected edited item's password + """ + item_name = "Example Login Item 01" + vault = "Test Data 2" + + password_recipe = OPPasswordRecipe(20, symbols=False) + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + expected_item_original: ExpectedLogin = expected_login_item_data.data_for_login( + item_name) + expected_item_edited: ExpectedLogin = expected_login_item_data.data_for_login( + item_name, version=1) + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert item_get_1.password == expected_item_original.password + + edited_item = signed_in_op.item_edit_generate_password(item_name, + password_recipe, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert edited_item.password != item_get_1.password + assert item_get_2.password == expected_item_edited.password + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_title_030(signed_in_op: OP): + """ + Test: OP.item_edit_title() + - Retrieve an item via OP.item_get() using the original title + - Call item_edit_title(), saving returned object + - Retreive the same item a second time using the new title + + Verify: + - The original item's password matches the expected original password + - The returned edited item's password is not the same as the original item's password + - The newly retrieved item's password matches the expected edited item's password + """ + item_name = "Example Login Item 02" + item_name_new = "Example Login Item 02 (New Title)" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # sort of obvious since we retrieved using the old title, but for the sake of completeness + assert item_get_1.title != item_name_new + edited_item = signed_in_op.item_edit_title( + item_name, item_name_new, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name_new, vault=vault) + + assert edited_item.title == item_get_2.title + assert item_get_2.title == item_name_new + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_favorite_040(signed_in_op: OP): + """ + Test: OP.item_edit_favorite() setting favorite to True + - Retrieve an item via OP.item_get() + - Call item_edit_favorite(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's favorite flag is False + - The returned edited item's favorite flag matches the newly retrieved item's favorite flag + - The newly retrieved item's favorite flag is True + """ + item_name = "Example Login Item 04" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert item_get_1.favorite is False + + edited_item = signed_in_op.item_edit_favorite( + item_name, True, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert edited_item.favorite == item_get_2.favorite + assert item_get_2.favorite is True + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_favorite_050(signed_in_op: OP): + """ + Test: OP.item_edit_favorite() setting favorite to False + - Retrieve an item via OP.item_get() + - Call item_edit_favorite(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's favorite flag is True + - The returned edited item's favorite flag matches the newly retrieved item's favorite flag + - The newly retrieved item's favorite flag is False + """ + item_name = "Example Login Item 05" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert item_get_1.favorite is True + + edited_item = signed_in_op.item_edit_favorite( + item_name, False, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert edited_item.favorite == item_get_2.favorite + assert item_get_2.favorite is False + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_tags_060(signed_in_op: OP): + """ + Test: OP.item_edit_tags() to replace an items set of tags with a different set of tags + - Retrieve an item via OP.item_get() + - Call item_edit_tags(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's tags match the expected original set of tags + - The returned edited item's tags match the newly retrieved item's set of tags + - The newly retrieved item's set of tags match the expected new set of tags + """ + item_name = "Example Login Item 06" + vault = "Test Data 2" + original_tag_set = {"tag_1", "tag_2"} + + new_tags = ["tag_3", "tag_4", "tag_5"] + new_tag_set = set(new_tags) + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert set(item_get_1.tags) == original_tag_set + + edited_item = signed_in_op.item_edit_tags( + item_name, new_tags, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert set(edited_item.tags) == set(item_get_2.tags) + assert set(item_get_2.tags) == new_tag_set + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_tags_070(signed_in_op: OP): + """ + Test: OP.item_edit_tags() to set tags on an item with no existing tags + - Retrieve an item via OP.item_get() + - Call item_edit_tags(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's set of tags is empty + - The returned edited item's tags match the newly retrieved item's set of tags + - The newly retrieved item's set of tags match the expected new set of tags + """ + item_name = "Example Login Item 07" + vault = "Test Data 2" + original_tag_set = set([]) + + new_tags = ["tag_1", "tag_2", "tag_3"] + new_tag_set = set(new_tags) + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert set(item_get_1.tags) == original_tag_set + + edited_item = signed_in_op.item_edit_tags( + item_name, new_tags, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert set(edited_item.tags) == set(item_get_2.tags) + assert set(item_get_2.tags) == new_tag_set + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_tags_080(signed_in_op: OP): + """ + Test: OP.item_edit_tags() to remove tags on an item that already has tags + - Retrieve an item via OP.item_get() + - Call item_edit_tags(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's set of tags is empty + - The returned edited item's tags match the newly retrieved item's set of tags + - The newly retrieved item's set of tags match the expected new set of tags + """ + item_name = "Example Login Item 08" + vault = "Test Data 2" + + original_tag_set = set(["tag_1", "tag_2", "tag_3"]) + new_tags = set([]) + new_tag_set = set(new_tags) + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert set(item_get_1.tags) == original_tag_set + + edited_item = signed_in_op.item_edit_tags( + item_name, new_tags, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert set(edited_item.tags) == set(item_get_2.tags) + assert set(item_get_2.tags) == new_tag_set + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_tags_085(signed_in_op: OP): + """ + Test: OP.item_edit_tags() append tags to an item's existing set of tags + - Retrieve an item via OP.item_get() + - Call item_edit_tags(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item's set of tags match the expected original set of tags + - The returned edited item's tags match the newly retrieved item's set of tags + - The newly retrieved item's set of tags match the expected combined set of tags + """ + item_name = "Example Login Item 08a" + vault = "Test Data 2" + + original_tag_set = set(["tag_1", "tag_2", "tag_3"]) + new_tags = ["tag_3", "tag_4", "tag_5"] + + # set of unique tags from original and new set + new_tag_set = set(["tag_1", "tag_2", "tag_3"] + new_tags) + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + assert set(item_get_1.tags) == original_tag_set + + edited_item = signed_in_op.item_edit_tags( + item_name, new_tags, append_tags=True, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + assert set(edited_item.tags) == set(item_get_2.tags) + assert set(item_get_2.tags) == new_tag_set + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_url_090(signed_in_op: OP): + """ + Test: OP.item_edit_url() to set an item's URL + - Retrieve an item via OP.item_get() + - Call item_edit_url(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has no URLs set + - The returned edited item has the same number of URLs as the newly retrieved item + - The newly retrieved item's primary URL's href matches the new URL + """ + item_name = "Example Login Item 09" + vault = "Test Data 2" + + new_url = "https://item-09-url.com/login.html" + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1: OPLoginItem = signed_in_op.item_get(item_name, vault=vault) + + # sort of obvious since we retrieved using the old title, but for the sake of completeness + assert len(item_get_1.urls) == 0 + + edited_item: OPLoginItem = signed_in_op.item_edit_url( + item_name, new_url, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2: OPLoginItem = signed_in_op.item_get(item_name, vault=vault) + + assert len(edited_item.urls) == len(item_get_2.urls) + assert len(item_get_2.urls) == 1 + assert item_get_2.primary_url.href == new_url + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_url_100(signed_in_op: OP): + """ + Test: OP.item_edit_url() to set an item's URL + - Retrieve an item via OP.item_get() + - Call item_edit_url(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has 1 URL set + - The returned edited item has the same number of URLs as the newly retrieved item + - The newly retrieved item's primary URL's href matches the new URL + """ + item_name = "Example Login Item 10" + vault = "Test Data 2" + + new_url = "https://item-10-url.com/login.html" + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1: OPLoginItem = signed_in_op.item_get(item_name, vault=vault) + + # sort of obvious since we retrieved using the old title, but for the sake of completeness + assert len(item_get_1.urls) == 1 + + edited_item: OPLoginItem = signed_in_op.item_edit_url( + item_name, new_url, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2: OPLoginItem = signed_in_op.item_get(item_name, vault=vault) + + assert len(edited_item.urls) == len(item_get_2.urls) + assert len(item_get_2.urls) == 1 + assert item_get_2.primary_url.href == new_url + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_url_110(signed_in_op: OP): + """ + Test: OP.item_edit_url() to set an item's URL + - Retrieve an item via OP.item_get() + - Call item_edit_url(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has 2 URLs set + - The returned edited item has the same number of URLs as the newly retrieved item + - The newly retrieved item continues to have 2 URLs set + - The newly retrieved item's primary URL's href matches the new URL + """ + item_name = "Example Login Item 11" + vault = "Test Data 2" + + new_url = "https://item-11-url.com/login.html" + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1: OPLoginItem = signed_in_op.item_get(item_name, vault=vault) + + # sort of obvious since we retrieved using the old title, but for the sake of completeness + assert len(item_get_1.urls) == 2 + + edited_item: OPLoginItem = signed_in_op.item_edit_url( + item_name, new_url, vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2: OPLoginItem = signed_in_op.item_get(item_name, vault=vault) + + assert len(edited_item.urls) == len(item_get_2.urls) + assert len(item_get_2.urls) == 2 + assert item_get_2.primary_url.href == new_url diff --git a/tests/test_item_edit/test_item_edit_add_field.py b/tests/test_item_edit/test_item_edit_add_field.py new file mode 100644 index 00000000..c862271f --- /dev/null +++ b/tests/test_item_edit/test_item_edit_add_field.py @@ -0,0 +1,498 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from pyonepassword.api.exceptions import ( + OPFieldNotFoundException, + OPSectionNotFoundException +) + +if TYPE_CHECKING: + from pyonepassword import OP + from pyonepassword.api.object_types import OPAbstractItem + +# ensure HOME env variable is set, and there's a valid op config present +pytestmark = pytest.mark.usefixtures("valid_op_cli_config_homedir") + + +def _get_field_value(item: OPAbstractItem, field_label: str, section_label: str = None): + """ + Given a field label and optionally a section label, return the field's value + """ + + if section_label: + section = item.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + else: + field = item.first_field_by_label(field_label) + + field_value = field.value + return field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_text_field_010(signed_in_op: OP): + """ + Test: OP.item_edit_add_text_field() + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_add_text_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has no sections matching the requested section label + - The original item has no fields matching the requested field label + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 17" + field_label = "Text Field 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should not have the requested section + with pytest.raises(OPSectionNotFoundException): + item_get_1.sections_by_label(section_label) + + # item should not have the requested field + with pytest.raises(OPFieldNotFoundException): + item_get_1.fields_by_label(field_label) + + edited_item = signed_in_op.item_edit_add_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_text_field_020(signed_in_op: OP): + """ + Scenario: + - adding a section/text field pairing when: + - Matching section does not exist + - Matching text field does exist + - Existing text field belongs to a non-matching section + + This should succeed because the new (section, field) pairing does not + match any existing (section, field) pairing + + Test: OP.item_edit_add_text_field(), + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_add_text_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has no sections matching the requested section label + - The original item has at least one field matching the requested field label + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 17a" + field_label = "Text Field 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should not have the requested section + with pytest.raises(OPSectionNotFoundException): + item_get_1.sections_by_label(section_label) + + # item SHOULD have the requested field + try: + item_get_1.fields_by_label(field_label) + except OPFieldNotFoundException: + assert False, f"Item SHOULD have the field: {field_label}" + + edited_item = signed_in_op.item_edit_add_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_text_field_030(signed_in_op: OP): + """ + Scenario: + - adding a section/text field pairing when: + - Matching section does exist + - Matching text field does not exist + + This should succeed because the new (section, field) pairing does not + match any existing (section, field) pairing + + Test: OP.item_edit_add_text_field(), + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_add_text_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has at least one section matching the requested section label + - The original item has no fields matching the requested field label + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 17b" + field_label = "Text Field 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should have the requested section + + try: + item_get_1.sections_by_label(section_label) + except OPSectionNotFoundException: + assert False, f"Item SHOULD have the section: {section_label}" + + # item should not have the requested field + with pytest.raises(OPFieldNotFoundException): + item_get_1.fields_by_label(field_label) + + edited_item = signed_in_op.item_edit_add_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_text_field_040(signed_in_op: OP): + """ + Scenario: + - adding a section/text field pairing when: + - Matching section exists + - Matching text field exists + - Existing text field belongs to a non-matching section + + This should succeed because the new (section, field) pairing does not + match any existing (section, field) pairing + + Test: OP.item_edit_add_text_field(), + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_add_text_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has at least one section matching the requested section label + - The original item has at least one field matching the requested field label + - The original item does not have a (section, field) pairing matching what is to be added + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 17c" + field_label = "Text Field 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should have the requested section + + try: + item_get_1.sections_by_label(section_label) + except OPSectionNotFoundException: + assert False, f"Item SHOULD have the section: {section_label}" + + # item should have the requested field + try: + item_get_1.fields_by_label(field_label) + except OPFieldNotFoundException: + assert False, f"Item SHOULD have the field: {field_label}" + + with pytest.raises(OPFieldNotFoundException): + # even though there is a matching section and a matching field, + # the two are not paired, so an exception is raised + _get_field_value(item_get_1, field_label, section_label=section_label) + + edited_item = signed_in_op.item_edit_add_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_text_field_045(signed_in_op: OP): + """ + Scenario: + - adding a text field with no section when: + - Item has no existing sections + - No fields other than the default fields + This should succeed because: + - the (, field) pairing does not exist + - no ambiguosly matching fields exist belonging to a section + + Test: OP.item_edit_add_text_field(), + - Retrieve an item via OP.item_get() + - Access original item's sections property + - Look up fields based on requested field label + - Call item_edit_add_text_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has no sections + - The original item has no fields matching the requested field label + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 17d" + field_label = "Text Field With no Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should have the requested section + + assert not item_get_1.sections, "Item should have no sections" + + # item should have no fields other than the default + # no public access to fields, so we'll have to settle for this + with pytest.raises(OPFieldNotFoundException): + item_get_1.first_field_by_label(field_label) + + edited_item = signed_in_op.item_edit_add_text_field(item_name, + new_field_value, + field_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value(edited_item, field_label) + item_2_field_value = _get_field_value(item_get_2, field_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_password_field_050(signed_in_op: OP): + """ + Test: OP.item_edit_add_password_field() + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_add_password_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has no sections matching the requested section label + - The original item has no fields matching the requested field label + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 18" + field_label = "Password Field 01" + section_label = "Section 01" + new_field_value = "new password field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should not have the requested section + try: + item_get_1.sections_by_label(section_label) + assert False, f"Item should not have the section: {section_label}" + except OPSectionNotFoundException: + pass + + # item should not have the requested field + try: + item_get_1.fields_by_label(field_label) + assert False, f"Item should not have the field: {field_label}" + except OPFieldNotFoundException: + pass + + edited_item = signed_in_op.item_edit_add_password_field(item_name, + new_field_value, + field_label, + section_label=section_label, + insecure_operation=True, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_url_field_060(signed_in_op: OP): + """ + Test: OP.item_edit_add_url_field() + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_add_url_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item has no sections matching the requested section label + - The original item has no fields matching the requested field label + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 23" + field_label = "URL Field 01" + section_label = "Section 01" + new_field_value = "https://new-url-field.com/" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should not have the requested section + try: + item_get_1.sections_by_label(section_label) + assert False, f"Item should not have the section: {section_label}" + except OPSectionNotFoundException: + pass + + # item should not have the requested field + try: + item_get_1.fields_by_label(field_label) + assert False, f"Item should not have the field: {field_label}" + except OPFieldNotFoundException: + pass + + edited_item = signed_in_op.item_edit_add_url_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value diff --git a/tests/test_item_edit/test_item_edit_delete_field.py b/tests/test_item_edit/test_item_edit_delete_field.py new file mode 100644 index 00000000..92ee081c --- /dev/null +++ b/tests/test_item_edit/test_item_edit_delete_field.py @@ -0,0 +1,141 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from pyonepassword.api.exceptions import ( + OPFieldNotFoundException, + OPSectionNotFoundException +) + +if TYPE_CHECKING: + from pyonepassword import OP + from pyonepassword.api.object_types import OPAbstractItem + +# ensure HOME env variable is set, and there's a valid op config present +pytestmark = pytest.mark.usefixtures("valid_op_cli_config_homedir") + + +def _get_field_value(item: OPAbstractItem, field_label: str, section_label: str = None): + """ + Given a field label and optionally a section label, return the field's value + """ + + if section_label: + section = item.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + else: + field = item.first_field_by_label(field_label) + + field_value = field.value + return field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_delete_field_010(signed_in_op: OP): + """ + Scenario: + - deleting a section/text field pairing when: + - Exactly one matching section exists + - Exactly one matching field exists + - Matching field belongs to matching section + + Test: OP.item_edit_delete_field() + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_delete_field(), saving returned object + - Retreive the same item a second time + Verify: + - The original item has a section matching the requested section label + - The original item has a field matching the requested field label + - The returned edited item has no matching section + - The returned edited item has no matching field + - The newly retrieved item has no matching section + - The newly retrieved item has no matching field + """ + + item_name = "Example Login Item 21a" + field_label = "Text Field 01" + section_label = "Section 01" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should have the requested section + section = item_get_1.first_section_by_label(section_label) + + # item should have the requested field + section.first_field_by_label(field_label) + + edited_item = signed_in_op.item_edit_delete_field(item_name, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + with pytest.raises(OPSectionNotFoundException): + edited_item.first_section_by_label(section_label) + with pytest.raises(OPFieldNotFoundException): + edited_item.first_field_by_label(field_label) + + with pytest.raises(OPSectionNotFoundException): + item_get_2.first_section_by_label(section_label) + with pytest.raises(OPFieldNotFoundException): + item_get_2.first_field_by_label(field_label) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_delete_field_020(signed_in_op: OP): + """ + Scenario: + - deleting a text field when: + - No matching sections exist + - Exactly one matching field exists + - Matching field belongs to no section + + Test: OP.item_edit_delete_field() + - Retrieve an item via OP.item_get() + - Look up sections based on requested section label + - Look up fields based on requested field label + - Call item_edit_delete_field(), saving returned object + - Retreive the same item a second time + Verify: + - The original item has exactly one field matching the requested field label + - The original item's matching field has no section + - The returned edited item has no matching field + - The newly retrieved item has no matching field + """ + + item_name = "Example Login Item 21b" + field_label = "Text Field 01" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should have the requested field + fields = item_get_1.fields_by_label(field_label) + assert len(fields) == 1 + assert fields[0].section_id is None + + edited_item = signed_in_op.item_edit_delete_field(item_name, + field_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + with pytest.raises(OPFieldNotFoundException): + edited_item.first_field_by_label(field_label) + + with pytest.raises(OPFieldNotFoundException): + item_get_2.first_field_by_label(field_label) diff --git a/tests/test_item_edit/test_item_edit_errors.py b/tests/test_item_edit/test_item_edit_errors.py new file mode 100644 index 00000000..71a8791f --- /dev/null +++ b/tests/test_item_edit/test_item_edit_errors.py @@ -0,0 +1,286 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from pyonepassword.api.exceptions import ( + OPFieldNotFoundException, + OPSectionNotFoundException +) +from pyonepassword.py_op_exceptions import ( + OPFieldExistsException, + OPInsecureOperationException +) + +if TYPE_CHECKING: + from pyonepassword import OP + +# ensure HOME env variable is set, and there's a valid op config present +pytestmark = pytest.mark.usefixtures("valid_op_cli_config_homedir") + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_password_no_insecure_acknowledge_010(signed_in_op: OP): + """ + Test: OP.item_edit_set_password() raises OPInsecureOperationException appropriately + - Attempt to call item_edit_set_password() without passing insecure_operation = True + Verify: + - OPInsecureOperationException is raised + """ + + item_name = "Example Login Item 00" + new_password = "new password" + vault = "Test Data 2" + + # item_edit_set_password() is inherently insecure, so + # requires insecure_operation=True + # This is expected to fail + with pytest.raises(OPInsecureOperationException): + signed_in_op.item_edit_set_password(item_name, + new_password, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_password_invalid_section_020(signed_in_op: OP): + """ + Test: OPSectionNotFoundException is raised appropriately + - Attempt to call item_edit_set_password() passing a non-existent section name + Verify: + - OPSectionNotFoundException is raised + """ + + item_name = "Example Login Item 03" + new_password = "new password" + field_label = "password" + section_label = "no-such-section" + vault = "Test Data 2" + with pytest.raises(OPSectionNotFoundException): + signed_in_op.item_edit_set_password(item_name, + new_password, + field_label=field_label, + section_label=section_label, + insecure_operation=True, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_password_invalid_field_030(signed_in_op: OP): + """ + Test: looking up an invalid field on a valid section + - Attempt to call item_edit_set_password() + - Pass a valid section name + - Pass an invalid field name + Verify: + - OPFieldNotFoundException is raised + """ + + item_name = "Example Login Item 03" + new_password = "new password" + field_label = "no-such-password-field" + section_label = "Example Section" + vault = "Test Data 2" + + with pytest.raises(OPFieldNotFoundException): + # This excercises a different code path from looking up a field + # with no section specified + signed_in_op.item_edit_set_password(item_name, + new_password, + field_label=field_label, + section_label=section_label, + insecure_operation=True, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_password_invalid_field_040(signed_in_op: OP): + """ + Test: looking up an invalid field with no section + - Attempt to call item_edit_set_password() + - Don't pass a section name + - Pass an invalid field name + Verify: + - OPFieldNotFoundException is raised + """ + + item_name = "Example Login Item 03" + new_password = "new password" + field_label = "no-such-password-field" + vault = "Test Data 2" + + with pytest.raises(OPFieldNotFoundException): + # This specifies a different code path from looking up a field + # associated with a specific section + signed_in_op.item_edit_set_password(item_name, + new_password, + field_label=field_label, + insecure_operation=True, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_text_field_omit_section_050(signed_in_op: OP): + """ + Test: Exiting an item where the field exists and is assigned to a section, + but omitting the section label + - Attempt to call item_edit_set_text_field() + - Pass a valid section label + - Pass None for the section label + + Verify: + - OPFieldNotFoundException is raised + """ + + item_name = "Example Login Item 12" + field_label = "Text Field 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + with pytest.raises(OPFieldNotFoundException): + signed_in_op.item_edit_set_text_field(item_name, + new_field_value, + field_label, + section_label=None, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_mismatched_section_text_field_060(signed_in_op: OP): + """ + Test: Exiting an item where the field exists and is assigned to a section, + but omitting the section label + - Attempt to call item_edit_set_text_field() + - Pass a valid section label + - Pass None for the section label + Verify: + - OPFieldNotFoundException is raised + """ + + item_name = "Example Login Item 16" + field_label = "Text Field 01" + section_label = "Section 02" + new_field_value = "new text field value" + vault = "Test Data 2" + + with pytest.raises(OPFieldNotFoundException): + signed_in_op.item_edit_set_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_text_field_ambiguous_match_070(signed_in_op: OP): + """ + Scenario: + - adding a text field pairing when: + - No section label is specified + - Two matching text fields exist + - Each text field belongs to a different section + + This should fail since ambiguous field match is an error when adding a field + + Test: OP.item_edit_add_text_field(), + - Retrieve an item via OP.item_get() + - Look up fields based on requested field label + - Call item_edit_add_text_field(), saving returned object + + Verify: + - The original item has at least one field matching the requested field label + - Each matching field belongs to a section + - OPFieldExistsException is raised during the item edit operation + """ + item_name = "Example Login Item 19" + field_label = "Ambiguous Field Match" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should have one or more matching fields + try: + fields = item_get_1.fields_by_label(field_label) + for field in fields: + # all fields should belong to a section + assert field.section_id is not None + except OPFieldNotFoundException: + assert False, f"Item SHOULD have the field: {field_label}" + + with pytest.raises(OPFieldExistsException): + signed_in_op.item_edit_add_text_field(item_name, + new_field_value, + field_label, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_text_field_exact_match_080(signed_in_op: OP): + """ + Scenario: + - adding a section/text field pairing when: + - A matching section exists + - A matching field exists + - The text field belongs to the section + + This should fail since ambiguous field match is an error when adding a field + + Test: OP.item_edit_add_text_field(), + - Retrieve an item via OP.item_get() + - Look up fields based on requested field & section label + - Call item_edit_add_text_field(), saving returned object + + Verify: + - The original item has at least matching section + - The section ias associated with one matching field + - OPFieldExistsException is raised during the item edit operation + """ + item_name = "Example Login Item 20" + field_label = "Field 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + # item should have a matching section and a matching field + section = item_get_1.first_section_by_label(section_label) + assert len(section.fields_by_label(field_label)) == 1 + + with pytest.raises(OPFieldExistsException): + signed_in_op.item_edit_add_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_add_password_no_insecure_acknowledge_090(signed_in_op: OP): + """ + Test: OP.item_edit_set_password() raises OPInsecureOperationException appropriately + - Attempt to call item_edit_set_password() without passing insecure_operation = True + Verify: + - OPInsecureOperationException is raised + """ + + item_name = "Example Login Item 18" + field_label = "Password Field 01" + section_label = "Section 01" + new_field_value = "new password field value" + vault = "Test Data 2" + + # item_edit_set_password() is inherently insecure, so + # requires insecure_operation=True + # This is expected to fail + with pytest.raises(OPInsecureOperationException): + signed_in_op.item_edit_set_password(item_name, + new_field_value, + field_label=field_label, + section_label=section_label, + vault=vault) diff --git a/tests/test_item_edit/test_item_edit_set_field_value.py b/tests/test_item_edit/test_item_edit_set_field_value.py new file mode 100644 index 00000000..dc1c98d6 --- /dev/null +++ b/tests/test_item_edit/test_item_edit_set_field_value.py @@ -0,0 +1,346 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from pyonepassword.api.object_types import ( + OPConcealedField, + OPStringField, + OPURLField +) +from pyonepassword.py_op_exceptions import OPPasswordFieldDowngradeException + +if TYPE_CHECKING: + from pyonepassword import OP + from pyonepassword.api.object_types import OPAbstractItem + +# ensure HOME env variable is set, and there's a valid op config present +pytestmark = pytest.mark.usefixtures("valid_op_cli_config_homedir") + + +def _get_field_value(item: OPAbstractItem, field_label: str, section_label: str = None): + """ + Given a field label and optionally a section label, return the field's value + """ + section = None + if section_label: + section = item.first_section_by_label(section_label) + + if section: + field = section.first_field_by_label(field_label) + else: + field = item.first_field_by_label(field_label) + + field_value = field.value + return field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_text_field_010(signed_in_op: OP): + """ + Test: OP.item_edit_set_text_field() + - Retrieve an item via OP.item_get() + - Call item_edit_set_text_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item field's value is not equal to the desired new value + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 12" + field_label = "Text Field 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + item_1_field_value = _get_field_value( + item_get_1, field_label, section_label=section_label) + + assert item_1_field_value != new_field_value + + edited_item = signed_in_op.item_edit_set_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_text_field_012(signed_in_op: OP): + """ + Test: password downgrade prevention + - Call item_edit_set_text_field() on a field that is a concealed/password field + Verify: + - Field on unedited item is an instance of OPConcealedField + - OPPasswordFieldDowngradeException is raised + """ + + item_name = "Example Login Item 14" + field_label = "Password to Text 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item = signed_in_op.item_get(item_name, vault=vault) + + field = item.first_field_by_label(field_label) + assert isinstance(field, OPConcealedField) + + with pytest.raises(OPPasswordFieldDowngradeException): + signed_in_op.item_edit_set_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_text_field_015(signed_in_op: OP): + """ + Test: OP.item_edit_set_url_field() + - Retrieve an item via OP.item_get() + - Call item_edit_set_text_field(), saving returned object + - Set a field that is a concealed/password field + - pass password_downgrade=True + - save returned object + - Retreive the same item a second time + Verify: + - OPPasswordFieldDowngradeException is NOT raised when item is edited + - Field on unedited item is an instance of OPConcealedField + - The original item field's value is not equal to the desired new value + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item's field is an instance of OPStringField + - The edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 14" + field_label = "Password to Text 01" + section_label = "Section 01" + new_field_value = "new text field value" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + section = item_get_1.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + # it's important that we're starting with a concealed field + # because that's what triggers a downgrade exception + assert isinstance(field, OPConcealedField) + + field_value = field.value + assert field_value != new_field_value + + # OPPasswordFieldDowngradeException is NOT raised + # because password_downgrade=True + edited_item = signed_in_op.item_edit_set_text_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault, + password_downgrade=True) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + + section = item_get_2.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + # verify + assert isinstance(field, OPStringField) + + item_2_field_value = field.value + + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_url_field_020(signed_in_op: OP): + """ + Test: OP.item_edit_set_url_field() + - Retrieve an item via OP.item_get() + - Call item_edit_set_url_field(), saving returned object + - Retreive the same item a second time + + Verify: + - The original item field's value is not equal to the desired new value + - The returned edited item field's value is the same as newly retrieved item field's value + - The newly retrieved item field's value is the same as the desired new value + + """ + + item_name = "Example Login Item 13" + field_label = "URL Field 01" + section_label = "Section 01" + new_field_value = "https://new-url.com/login.html" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item_get_1 = signed_in_op.item_get(item_name, vault=vault) + + item_1_field_value = _get_field_value( + item_get_1, field_label, section_label=section_label) + + assert item_1_field_value != new_field_value + + edited_item = signed_in_op.item_edit_set_url_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item_get_2 = signed_in_op.item_get(item_name, vault=vault) + edited_item_field_value = _get_field_value( + edited_item, field_label, section_label=section_label) + item_2_field_value = _get_field_value( + item_get_2, field_label, section_label=section_label) + + # ensure the field value in the item returned from the edit operation + # matches the field value for the same item in a subsequent "item_get" operation + assert edited_item_field_value == item_2_field_value + + # ensure the field value for the newly retrieved item matches the intended new field value + assert item_2_field_value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_url_field_030(signed_in_op: OP): + """ + Test: OP.item_edit_set_url_field() + - Retrieve an item via OP.item_get() + - Look up the field to be changed based on section and field name + - Call item_edit_set_url_field(), saving returned object + - Retreive the same item a second time + Verify: + - The original item field is an instance of OPURLField + - The original item field's value is not equal to the desired new value + - The newly retrieved item field is an instance of OPURLField + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 13" + field_label = "URL Field 01" + section_label = "Section 01" + new_field_value = "https://new-url.com/login.html" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item = signed_in_op.item_get(item_name, vault=vault) + section = item.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + + # ensure the field is a URL field + assert isinstance(field, OPURLField) + + # ensure the original field value is not the value we're trying to set + assert field.value != new_field_value + + signed_in_op.item_edit_set_url_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item = signed_in_op.item_get(item_name, vault=vault) + section = item.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + + # ensure the field is still a URL field + assert isinstance(field, OPURLField) + + # ensure the field value for the newly retrieved item matches the intended new field value + assert field.value == new_field_value + + +@pytest.mark.usefixtures("setup_stateful_item_edit") +def test_item_edit_set_url_field_040(signed_in_op: OP): + """ + Test: OP.item_edit_set_url_field() + - Retrieve an item via OP.item_get() + - Look up the field to be changed based on section and field name + - Call item_edit_set_url_field(), saving returned object + - Retreive the same item a second time + Verify: + - The original item field is an instance of OPStringField + - The original item field's value is not equal to the desired new value + - The newly retrieved item field has been chaned to an instance of OPURLField + - The newly retrieved item field's value is the same as the desired new value + """ + + item_name = "Example Login Item 15" + field_label = "Text field to be updated to URL 01" + section_label = "Section 01" + new_field_value = "https://new-url.com/login.html" + vault = "Test Data 2" + + # stateful response directory + # state 1: responses-item-edit/response-directory-1.json + item = signed_in_op.item_get(item_name, vault=vault) + section = item.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + + # ensure the field is a string field, and more importantly NOT + # a URL field + assert isinstance(field, OPStringField) + + # ensure the original field value is not the value we're trying to set + assert field.value != new_field_value + + signed_in_op.item_edit_set_url_field(item_name, + new_field_value, + field_label, + section_label=section_label, + vault=vault) + + # state changed with item_edit above + # state 2: responses-item-edit/response-directory-2.json + item = signed_in_op.item_get(item_name, vault=vault) + section = item.first_section_by_label(section_label) + field = section.first_field_by_label(field_label) + + # ensure the field has been changed to a URL field + assert isinstance(field, OPURLField) + + # ensure the field value for the newly retrieved item matches the intended new field value + assert field.value == new_field_value diff --git a/tests/test_item_errors.py b/tests/test_item_errors.py index bb709a17..ec689898 100644 --- a/tests/test_item_errors.py +++ b/tests/test_item_errors.py @@ -9,6 +9,7 @@ OPInvalidItemException, OPItemFieldCollisionException, OPSectionCollisionException, + OPSectionNotFoundException, OPUnknownItemTypeException ) from pyonepassword.api.object_types import OPLoginItem @@ -24,18 +25,36 @@ def test_unknown_item_type_01(invalid_data): + """ + Attempt to create an op item with invalid category "UNKNOWN" + + Verify OPUnknownItemtypeException is raised + """ invalid_item_json = invalid_data.data_for_name("invalid-item") with pytest.raises(OPUnknownItemTypeException): _ = OPItemFactory.op_item(invalid_item_json) def test_malformed_item_json_01(invalid_data): + """ + Attempt to create an op item with malformed/corrupted JSON + + Verify OPInvalidItemException is raised + """ malformed_json = invalid_data.data_for_name("malformed-item-json") with pytest.raises(OPInvalidItemException): _ = OPItemFactory.op_item(malformed_json) def test_item_field_not_found_01(valid_data: ValidData): + """ + Create: + - a valid OPLoginItem object + + Attempt to look up a non-existent field via field_by_id() + + Verify OPFieldNotFoundException is raised + """ item_dict = valid_data.data_for_name("example-login-1") result = OPLoginItem(item_dict) @@ -43,7 +62,47 @@ def test_item_field_not_found_01(valid_data: ValidData): result.field_by_id("Non-existent-field") +def test_item_field_not_found_02(valid_data: ValidData): + """ + Create: + - a valid OPLoginItem object + + Attempt to look up a non-existent field via fields_by_label() + + Verify OPFieldNotFoundException is raised + """ + item_dict = valid_data.data_for_name("example-login-1") + result = OPLoginItem(item_dict) + + with pytest.raises(OPFieldNotFoundException): + result.fields_by_label("Non-existent-field") + + +def test_item_field_not_found_03(valid_data: ValidData): + """ + Create: + - a valid OPLoginItem object + + Attempt to look up a non-existent field via first_field_by_label() + + Verify OPFieldNotFoundException is raised + """ + item_dict = valid_data.data_for_name("example-login-1") + result = OPLoginItem(item_dict) + + with pytest.raises(OPFieldNotFoundException): + result.first_field_by_label("Non-existent-field") + + def test_item_field_collision_01(invalid_data): + """ + Test item creation with colliding sections + + Create: + - op item object from an item dictionary with colliding Field IDs + Verify: + - OPFieldCollisionException is raised + """ field_collision_json = invalid_data.data_for_name("field-collision") with pytest.raises(OPItemFieldCollisionException): OPItemFactory.op_item(field_collision_json) @@ -62,3 +121,60 @@ def test_item_section_collision_01(invalid_data: InvalidData): "login-item-with-section-collision") with pytest.raises(OPSectionCollisionException): OPItemFactory.op_item(invalid_item_dict) + + +def test_item_section_not_found_01(valid_data: ValidData): + """ + Test looking up a section on a login item by an invalid section ID + + Create: + - A login item object with fields and sections + - Look up an invalid section ID via section_by_id() + Verify: + - OPSectionNotFoundException is raised + """ + section_id = "no_such_section" + + valid_item_dict = valid_data.data_for_name("example-login-with-fields") + result_login_item = OPLoginItem(valid_item_dict) + + with pytest.raises(OPSectionNotFoundException): + result_login_item.section_by_id(section_id) + + +def test_item_section_not_found_02(valid_data: ValidData): + """ + Test looking up a section on a login item by an invalid section ID + + Create: + - A login item object with fields and sections + - Look up an invalid section ID via section_by_id() + Verify: + - OPSectionNotFoundException is raised + """ + section_label = "No Such Section" + + valid_item_dict = valid_data.data_for_name("example-login-with-fields") + result_login_item = OPLoginItem(valid_item_dict) + + with pytest.raises(OPSectionNotFoundException): + result_login_item.sections_by_label(section_label) + + +def test_item_section_not_found_03(valid_data: ValidData): + """ + Test looking up a section on a login item by an invalid section ID + + Create: + - A login item object with fields and sections + - Look up an invalid section ID via section_by_id() + Verify: + - OPSectionNotFoundException is raised + """ + section_label = "No Such Section" + + valid_item_dict = valid_data.data_for_name("example-login-with-fields") + result_login_item = OPLoginItem(valid_item_dict) + + with pytest.raises(OPSectionNotFoundException): + result_login_item.first_section_by_label(section_label) diff --git a/tests/test_item_section.py b/tests/test_item_section.py index aa20fb6f..86128e94 100644 --- a/tests/test_item_section.py +++ b/tests/test_item_section.py @@ -4,7 +4,7 @@ import pytest -from pyonepassword.api.exceptions import OPSectionNotFoundException +from pyonepassword.api.exceptions import OPFieldNotFoundException from pyonepassword.api.object_types import OPLoginItem from pyonepassword.op_items.fields_sections.item_field_base import OPItemField from pyonepassword.op_items.fields_sections.item_section import OPSection @@ -98,25 +98,6 @@ def test_item_section_02(valid_data: ValidData, expected_login_item_data: Expect def test_item_section_03(valid_data: ValidData, expected_login_item_data: ExpectedLoginItemData): - """ - Test looking up a section on a login item by an invalid section ID - - Create: - - A login item object with fields and sections - - Look up an invalid section ID via section_by_id() - Verify: - - OPSectionNotFoundException is raised - """ - section_id = "no_such_section" - - valid_item_dict = valid_data.data_for_name("example-login-with-fields") - result_login_item = OPLoginItem(valid_item_dict) - - with pytest.raises(OPSectionNotFoundException): - result_login_item.section_by_id(section_id) - - -def test_item_section_04(valid_data: ValidData, expected_login_item_data: ExpectedLoginItemData): """ Test case-insensitive search for sections by label @@ -147,3 +128,29 @@ def test_item_section_04(valid_data: ValidData, expected_login_item_data: Expect assert isinstance(result, OPSection) assert result.label == expected_section.label + + +def test_section_field_not_found_01(valid_data: ValidData): + section_id = "vh4wk7qyw46urc7wuwczzhpm7u" + field_label = "No Such Field" + + valid_item_dict = valid_data.data_for_name("example-login-with-fields") + + result_login_item = OPLoginItem(valid_item_dict) + result_section = result_login_item.section_by_id(section_id) + + with pytest.raises(OPFieldNotFoundException): + result_section.fields_by_label(field_label) + + +def test_section_field_not_found_02(valid_data: ValidData): + section_id = "vh4wk7qyw46urc7wuwczzhpm7u" + field_label = "No Such Field" + + valid_item_dict = valid_data.data_for_name("example-login-with-fields") + + result_login_item = OPLoginItem(valid_item_dict) + result_section = result_login_item.section_by_id(section_id) + + with pytest.raises(OPFieldNotFoundException): + result_section.first_field_by_label(field_label) diff --git a/tests/test_password_recipe.py b/tests/test_password_recipe.py new file mode 100644 index 00000000..42fed3e5 --- /dev/null +++ b/tests/test_password_recipe.py @@ -0,0 +1,226 @@ +import pytest + +from pyonepassword.api.object_types import OPPasswordRecipe +from pyonepassword.op_items.password_recipe import ( + OPInvalidPasswordRecipeException +) + + +def test_password_recipe_010(): + """ + Create a password recipe with: + - custom length + - letters, digits, & symbols explicitly True + Verify: + the resulting recipe matches the expected recipe + """ + expected_recipe = "25,letters,digits,symbols" + length = 25 + letters = True + digits = True + symbols = True + recipe = OPPasswordRecipe( + length=length, letters=letters, digits=digits, symbols=symbols) + assert expected_recipe == str(recipe) + + +def test_password_recipe_020(): + """ + Create a password recipe with: + - custom length + - letters, digits explicitly True + - symbols explicitly False + Verify: + the resulting recipe matches the expected recipe + """ + expected_recipe = "30,letters,digits" + length = 30 + letters = True + digits = True + symbols = False + recipe = OPPasswordRecipe( + length=length, letters=letters, digits=digits, symbols=symbols) + assert expected_recipe == str(recipe) + + +def test_password_recipe_030(): + """ + Create a password recipe with: + - custom length + - letters explicitlyh False + - digits, symbols explicitly True + Verify: + the resulting recipe matches the expected recipe + """ + expected_recipe = "50,digits,symbols" + length = 50 + letters = False + digits = True + symbols = True + recipe = OPPasswordRecipe( + length=length, letters=letters, digits=digits, symbols=symbols) + assert expected_recipe == str(recipe) + + +def test_password_recipe_040(): + """ + Create a password recipe with all default values + Verify: + the resulting recipe matches the expected recipe + """ + expected_recipe = "20,letters,digits,symbols" + + recipe = OPPasswordRecipe() + assert expected_recipe == str(recipe) + + +def test_password_recipe_050(): + """ + Create a password recipe with: + - custom length + - default values for letters, digits, & symbols + Verify: + the resulting recipe matches the expected recipe + """ + expected_recipe = "36,letters,digits,symbols" + length = 36 + recipe = OPPasswordRecipe(length=length) + assert expected_recipe == str(recipe) + + +def test_password_recipe_exception_060(): + """ + Create a password recipe with: + - letters, digits, & symbols explicitly False + Verify: + OPInvalidPasswordRecipeException is raised + """ + letters = False + digits = False + symbols = False + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe(letters=letters, digits=digits, symbols=symbols) + + +def test_password_recipe_exception_070(): + """ + Create a password recipe with: + - Length value less than the minimum of 1 + Verify: + OPInvalidPasswordRecipeException is raised + """ + length = 0 + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe(length=length) + + +def test_password_recipe_exception_080(): + """ + Create a password recipe with: + - Length value greater than the maximum 64 + Verify: + OPInvalidPasswordRecipeException is raised + """ + length = 65 + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe(length=length) + + +def test_password_recipe_exception_090(): + """ + Create a password recipe with: + - Negative length value + Verify: + OPInvalidPasswordRecipeException is raised + """ + length = -127 + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe(length=length) + + +def test_password_recipe_from_string_100(): + """ + Create a password recipe using from_string(), with: + - Custom length greater than the maximum 64 + - letters, digits, & symbols + Verify: + the resulting recipe matches the expected recipe + """ + + input_string = "64,letters,digits,symbols" + expected_recipe = "64,letters,digits,symbols" + + recipe = OPPasswordRecipe.from_string(input_string) + + assert expected_recipe == str(recipe) + + +def test_password_recipe_from_string_110(): + """ + Create a password recipe using from_string(), with: + - custom length + - letters & digits + Verify: + the resulting recipe matches the expected recipe + """ + + input_string = "20,letters,digits" + expected_recipe = "20,letters,digits" + + recipe = OPPasswordRecipe.from_string(input_string) + + assert expected_recipe == str(recipe) + + +def test_password_recipe_from_string_120(): + """ + Create a password recipe using from_string(), with: + - Custom length larger the maximum + - letters, digits, & symbols + Verify: + the resulting recipe matches the expected recipe + """ + + input_string = "65,letters,digits" + + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe.from_string(input_string) + + +def test_password_recipe_from_string_130(): + """ + Create a password recipe using from_string(), with: + - Omitted length, only letters & digits specified + Verify: + OPInvalidPasswordRecipeException is raised + """ + input_string = "letters,digits" + + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe.from_string(input_string) + + +def test_password_recipe_from_string_140(): + """ + Create a password recipe using from_string(), with: + - an illegal string consisting of emojis + Verify: + OPInvalidPasswordRecipeException is raised + """ + input_string = "🍆🍆🍆" + + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe.from_string(input_string) + + +def test_password_recipe_from_string_150(): + """ + Create a password recipe using from_string(), with: + - an illegal string consisting of length, letters, digits, and an emoji + Verify: + OPInvalidPasswordRecipeException is raised + """ + input_string = "25,letters,digits,🙃" + + with pytest.raises(OPInvalidPasswordRecipeException): + OPPasswordRecipe.from_string(input_string) diff --git a/tests/test_support/_datetime.py b/tests/test_support/_datetime.py index fe18392e..516aa7ec 100644 --- a/tests/test_support/_datetime.py +++ b/tests/test_support/_datetime.py @@ -1,3 +1,4 @@ +import re from datetime import datetime """ @@ -13,11 +14,16 @@ def fromisoformat_z(date_string: str) -> datetime: And there's no way to do it without an external package like dateutil https://bugs.python.org/issue35829 """ - if not date_string.endswith('Z'): + if date_string.endswith('Z'): + _str = date_string.rstrip('Z') + _str += "+00:00" + elif re.match(r".*[+-]\d{2}:\d{2}$", date_string): + # We shouldn't ever get this, but we also shouldn't blow up on it, + # so work with it if it happens + _str = date_string + else: # Mirror the ValueError that datetime.fromisoformat() raises raise ValueError( - f"Invalid Z-terminated isoformat string: '{date_string}'") - _str = date_string.rstrip('Z') - _str += "+00:00" + f"Invalid TZ terminated isoformat string: '{date_string}'") datetime_obj = datetime.fromisoformat(_str) return datetime_obj diff --git a/tests/test_svc_acct_support/test_svc_acct_primary_api.py b/tests/test_svc_acct_support/test_svc_acct_primary_api.py index 48ef3dee..0ec1a1af 100644 --- a/tests/test_svc_acct_support/test_svc_acct_primary_api.py +++ b/tests/test_svc_acct_support/test_svc_acct_primary_api.py @@ -153,14 +153,18 @@ def test_svc_account_primary_api_docstrings(): failures = [] for meth_name, method_obj in api_method_dict.items(): - matches = re.search(svc_account_string_re, method_obj.__doc__) - if not matches: - # we didn't find service account support in the docstring + if not method_obj.__doc__: + # no docstring at all failures.append(f"OP.{meth_name}()") else: - # we found mention of service account support but it was incomplete or not formatted properly - if len(matches[0].splitlines()) != 2: + matches = re.search(svc_account_string_re, method_obj.__doc__) + if not matches: + # we didn't find service account support in the docstring failures.append(f"OP.{meth_name}()") + else: + # we found mention of service account support but it was incomplete or not formatted properly + if len(matches[0].splitlines()) != 2: + failures.append(f"OP.{meth_name}()") # len(failures) should == 0 # if not generate failure message from list of failures diff --git a/tox.ini b/tox.ini index 5035042b..e7e9e8de 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{38,39,310,311}-{pytest,mypy} +envlist = py{39,310,311,312}-{pytest,mypy} discover = {env:CUSTOM_PYTHON} @@ -14,7 +14,7 @@ commands = {posargs} -[testenv:py{38,39,310,311}-mypy] +[testenv:py{39,310,311,312}-mypy] # It's important to run mypy across all supported python versions # so we don't introduce type hints incompatible with older python versions # e.g., TypeAlias not available for pythton < 3.10