Giter VIP home page Giter VIP logo

connect-sdk-js's Introduction

1Password Connect SDK JS

Access your 1Password items in your JavaScript/TypeScript applications through your self-hosted 1Password Connect server.

Get started

The 1Password Connect SDK JS provides your JavaScript and TypeScript applications access to the 1Password Connect API hosted on your infrastructure and leverages the power of 1Password Secrets Automation.

This library can be used by Node.js applications, tools, and other automations to access and manage items in 1Password vaults.

๐Ÿ’พ Installation

You can install the SDK using npm or Yarn.

npm install @1password/connect
yarn add @1password/connect

โœจ Get Started

Refer to QUICKSTART.md for code examples on how to start using this library.

๐Ÿ› ๏ธ Development

From the root of the repo you can run the following make commands. You can also run make help to list out all available commands and their descriptions.

make build
make install
make test

๐Ÿ’™ Community & Support

๐Ÿ” Security

1Password requests you practice responsible disclosure if you discover a vulnerability. Please submit discoveries via BugCrowd.

For information about security practices, please visit our Security homepage.

connect-sdk-js's People

Contributors

benwestrate avatar dckcode avatar dependabot[bot] avatar dustin-ruetz avatar edif2008 avatar ephremdeme avatar florisvdg avatar gevalo1 avatar github-actions[bot] avatar hculea avatar jillianwilson avatar jpcoenen avatar leofkj avatar mcmarkj avatar mmarkell avatar petetnt avatar simhnna avatar simonbarendse avatar thatguygriff avatar verkaufer avatar volodymyrzotov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

connect-sdk-js's Issues

Unable to connect using service account token

Your environment

SDK Version:
1.4.1

Connect Server Version:

OS:
Win 10

Node Version:
18.19

What happened?

Hello There,
I am trying to use the service token for onepasswordconnect Api. Can you please provide me an example as to how ai can use it?

Use cases

No serviceurl ir token but connect to sdk isi g service account token

What did you expect to happen?

Should be able to connect

Steps to reproduce

Use service account token only to connect

Type declarations are not correct

For instance, I am trying to retrieve a FullItem:

const items = await op.listItems(vaultId);
  const fullItems = (await Promise.all(items.map((item) => {
    if (item.id) {
      return op.getItem(vaultId, item.id);
    }
  })))

the resultant items do not have a .value property on them, even though the .value property is present on the object (which you can see via console.log.

Enhance `deleteItem` functionality

Sumary

We want users to have an easy flow when using this SDK. For items, we want them to be able to provide either the ID or the title of an item as a parameter. In this issue, we will address this for deleting items.

Tasks to be done

  • Rename delete function in src/lib/resources.ts to deleteById
  • Create the new delete function in src/lib/resources.ts that expects either the Item name or its ID. The important part of this functionality is to check if the provided string is a valid ID or not (i.e. it matches the following regex: "^[a-z0-9]{26}$")
  • Adjust deleteItem by changing the parameter name to suggest that either the name or ID is accepted (e.g. itemQuery).
  • Create a new function deleteItemById in src/lib/op-connect.ts
    /**
     * Delete a specific item with a matching ID value.
     *
     * @param {string} vaultId
     * @param {string} itemId
     * @returns {Promise<void>}
     */
    public async deleteItemById(vaultId: string, itemId: string): Promise<void> {
        return await this.items.deleteById(vaultId, itemId);
    }
  • Add and adjust tests for the new functions in __test__/op-connect.test.ts

Add `listItemsByTag` and `listItemsByTagContains`

Summary

The REST api supports searching with tag filters, just like name filters. It would be really useful if we could do that in the JS SDK too.

Use cases

We're writing automations to perform key rotations and update 1password, but we need the flexibility to set the schedule for rotations on the item in 1Password. For example, you might use a tag named rotate:quarterly or something like that. This would make it easy to search for items that need to be rotated during the quarterly rotation.

Proposed Solution

Copy/paste the listItemsByName and listItemsByNameContains functions, and change name to tag.

Is there a workaround to accomplish this today?

Only way to perform this style of search I've found is to interact with the REST api directly. Instead, at the moment, I'm getting all items and then filtering the array by inspecting the tags on every item.

new items generation recipe is broken

When the API call is made, JSON.stringify does not know how to stringify JavaScript Set objects. Thus the recipe is invalid and the server logs an error and returns a 400.

'characterSets'?: Set<GeneratorRecipe.CharacterSetsEnum>;

Logged error was:

op-connect-api     | {"log_message":"(E) Server: (invalid JSON sent by client), json: cannot unmarshal object into Go struct field GeneratorRecipe.fields.recipe.characterSets of type []string","timestamp":"2021-09-04T23:43:26.83597448Z","level":1,"scope":{"request_id":"b8f71f5c-01e9-4d36-a997-56d33f99d2df","jti":"do5lfdfnl7bf5td7n45twobihu"}}

As you can see the characterSets is empty, even though the original request has all three options of letters, digits and symbols.

Add functionality to download a file

Summary

Starting with Connect 1.3.0, the users can get files that are stored in an Item. Connect Node SDK should enable the users to do that.

In this issue, we will enable the user to download a file stored in 1Password.

Tasks to be done

  • Implement downloadFile function in the Items class in src/lib/resources.ts. The API endpoint that this function needs to call is v1/vaults/vaultId/items/itemId/files/fileId/content. You'll have to figure out the object type the promise expects.
    /**
     * Download an Item's File in the provided path.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @param {string} fileId
     * @param {string} targetDirectory
     * @param {boolean} overwrite
     * @returns {Promise<string>}
     * @private
     */
    private async getFileContent(
             vaultId: string,
             itemQuery: string,
             fileId: string,
             targetDirectory: string,
             overwrite: boolean,
         ): Promise<string> {
         // functionality
    }
    Note: Feel free to place this functionality in a separate class (e.g. Files) if you feel it's more suitable. This is just a suggested approach.
  • Implement downloadFile function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Download an Item's File in the provided path.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @param {string} fileId
     * @returns {Promise<string>}
     */
    public async downloadFile(vaultId: string, itemQuery: string, fileId: string. targetDirectory: string, overwrite: boolean): Promise<string> {
          return await this.items.getFileContent(vaultId, itemQuery, fileId, targetDirectory, overwrite);
    }
  • Add a test for the new function in __test__/op-connect.test.ts. This may be a tricky one.
    test("downloadFile", async () => {
        // actual test here
    }

Add functionality to get a File's content

Summary

Starting with Connect 1.3.0, the users can get files that are stored in an Item. Connect Node SDK should enable the users to do that.

In this issue, we will get a file's content.

Tasks to be done

  • Implement getFileContent function in the Items class in src/lib/resources.ts. The API endpoint that this function needs to call is v1/vaults/vaultId/items/itemId/files/fileId/content. You'll have to figure out the object type the promise expects.
    /**
     * Get an Item File's content.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @param {string} fileId
     * @returns {Promise<>}
     * @private
     */
    private async getFileContent(
             vaultId: string,
             itemQuery: string,
             fileId: string,
         ): Promise<> {
         // functionality
    }
    Note: Feel free to place this functionality in a separate class (e.g. Files) if you feel it's more suitable. This is just a suggested approach.
  • Implement getFileContent function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Get an Item File's content.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @param {string} fileId
     * @returns {Promise<>}
     */
    public async getFileContent(vaultId: string, itemQuery: string, fileId: string): Promise<> {
          return await this.items.getFileContent(vaultId, itemQuery, fileId);
    }
  • Add a test for the new function in __test__/op-connect.test.ts:
    test("get file content", async () => {
        // actual test here
    }

Adjust Autofill URL object

Summary

Starting with Connect 1.5.0+, the item URL object (or autofill URL) got a new property: label.
JS SDK should reflect this new addition as well.

Tasks to be done

  • Add in the src/model/itemURLs.ts (where the item URL object is defiled) the following property:
    {
        "name": "label",
        "baseName": "label",
        "type": "string"
    },
    Place this property before primary.
  • Adjust the __test__/responses/item-details.json item JSON response to reflect the new item autofill URL object. Specifically, change the urls part of the JSON like this:
    "urls": [
      {
        "label": "website-1",
        "primary": true,
        "url": "https://agilebits.com"
      },
      {
        "label": "website-2",
        "url": "https://1password.ca"
      }
    ],
    Make sure the tests work with the latest changes to the item URL object.

Add functionality to delete Item by title

Summary

We want to enhance the way users can delete items when using the Connect Node SDK. In this issue, we want to enable users to delete an item that has the given title.

Tasks to be done

  • Implement deleteByTitle function in the Items class in src/lib/resources.ts:
    /**
     * Deletes an item with a case-sensitive, exact match on title.
     *
     * @param {string} vaultId
     * @param {string} title
     * @returns {Promise<void>}
     * @private
     */
    private async deleteItemByTitle(
             vaultId: string,
             title: string,
         ): Promise<Response> {
         // functionality
    }
  • Implement deleteItemByTitle function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Delete a specific item with a matching Title value.
     *
     * The Item Title is case-sensitive and must be an exact-match.
     *
     * @param {string} vaultId
     * @param {string} itemTitle
     * @returns {Promise<void>}
     */
    public async deleteItemByTitle(vaultId: string, itemTitle: string): Promise<void> {
          return await this.items.deleteByTitle(vaultId, itemTitle);
    }
  • Add a test for the new function in __test__/op-connect.test.ts below delete item test case:
    test("delete item by titte", async () => {
        // actual test here
    }

Enhance `getVault` functionality

Sumary

We want users to have an easy flow when using this SDK. For vaults, we want them to be able to provide either the ID or the title as a parameter.

Tasks to be done

  • Rename getVault to getVaultById in src/lib/resources.ts
  • Create the new getVault function in src/lib/resources.ts that expects either the Vault name or its ID. The important part of this functionality is to check if the provided string is a valid ID or not (i.e. it matches the following regex: "^[a-z0-9]{26}$"). You can use as an inspiration the get function for the Item class.
  • Adjust getVault by changing the parameter name to suggest that either the name or ID is accepted (e.g. vaultQuery).
  • Create a new function getValutById in src/lib/op-connect.ts
    /**
     * Get details about a specific vault with a matching ID value.
     *
     * @param {string} vaultId
     * @returns {Promise<Vault>}
     */
    public async getVaultById(vaultId: string): Promise<Vault> {
        return await this.vaults.getVaultById(vaultId);
    }
  • Add and adjust tests for the new functions in __test__/op-connect.test.ts

Add functionality to get multiple vaults by a title

Summary

Currently this is what the users can do when it comes to vaults:

  • listVaults - get the list of all vaults that the Connect token has access to.
  • getVault(vaultId) - get a Vault by its ID.

We want to enhance the way users can get vaults when using the Connect Node SDK. In this issue, we want to enable users to get a list of vaults that have the given title.

Tasks to be done

  • Implement getVaultsByTitle function in the Vaults class in src/lib/resources.ts:
    /**
     * Search for all Vaults with an exact match on title.
     *
     * @param {string} title
     * @returns {Promise<Vault[]>}
     * @private
     */
    private async listVaultsByTitle(
             title: string,
         ): Promise<Response> {
         // functionality
    }
  • Implement listVaultsByTitle function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Returns a list of Vaults with a matching Title value.
     *
     * The Vault Title is case-sensitive and must be an exact-match.
     *
     * @param {string} vaultTitle
     * @returns {Promise<Vault[]>}
     */
    public async listVaultsByTitle(vaultTitle: string): Promise<Vault[]> {
          return await this.vaults.getVaultsByTitle(vaultTitle);
    }
  • Add a test for the new function in __test__/op-connect.test.ts below get vault test case:
    test("list vaults by titte", async () => {
        // actual test here
    }

Add functionality to get multiple items by a title

Summary

We want to enhance the way users can get items when using the Connect Node SDK. In this issue, we want to enable users to get a list of items that have the given title.

Tasks to be done

  • Implement listItemsByTitle function in the Items class in src/lib/resources.ts. Important note: The API response returns an Item summary, not the full item, therefore once you get the list of item summaries, for each item you have to call getItemById.
    /**
     * Search for all Items with an exact match on title.
     *
     * @param {string} title
     * @returns {Promise<FullItem[]>}
     * @private
     */
    private async listItemssByTitle(
             vaultId: string,
             title: string,
         ): Promise<Response> {
         // functionality
    }
    Tip: You can move this snippet from get to listItemsByTitle and then call listItemsByTitle in get. In this way, you avoid duplicate code in the two function.
  • Implement listItemsByTitle function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Returns a list of Items with a matching Title value.
     *
     * @param {string} vaultId
     * @param {string} itemTitle
     * @returns {Promise<FullItem[]>}
     */
    public async listItemsByTitle(vaultId: string, itemTitle: string): Promise<FullItem[]> {
          return await this.items.listItemsByTitle(vaultId, itemTitle);
    }
  • Add a test for the new function in __test__/op-connect.test.ts below get item test case:
    test("list items by titte", async () => {
        // actual test here
    }

Remove "crypto" import

Summary

Webpack 5 stopped automatically polyfilling Node.js (src). Because we use the node.js crypto library in one area of the item builder, users trying to integrate the SDK with the webpack bundler will see this error:

webpack < 5 used to include polyfills for node.js core modules by default" error

Use cases

n/a

Proposed Solution

Remove the crypto import from our SDK. We're only using it to generate sectionIDs, and there's a note that section IDs aren't cryptographically random anyways.

We should replace the crypto call with a quick-and-dirty "generate alphanumeric string" function.

Is there a workaround to accomplish this today?

Users can target node in their webpack config or enable nodejs fallbacks.

Both workarounds lead to larger bundle sizes for users.

References & Prior Work

Error: connect ECONNREFUSED ::1:8080 when connecting to the OnePassword Connect server

Your environment

SDK Version: 1.4.1

Connect Server Version: 1.7.2

OS: MacOS 11.7.9 (Big Sur - Intel) with Rancher Desktop and Docker

Node Version: v18.18.2

What happened?

Using the serverURL of http://localhost:8080 attempts to resolve via IPv6 and fails to resolve the host causing the connection to the op-connect-api container to fail when running in local development. Using Rancher Desktop & Docker.

What did you expect to happen?

No error connecting to the op-connect-api Docker Container and a list of vault/secrets to be returned.

Steps to reproduce

  1. Create a Secrets Automation save the .json and token.

  2. Setup OnePassword Connect server per https://developer.1password.com/docs/connect/get-started/#step-2-deploy-1password-connect-server with Rancher Desktop and Docker.

    • Verify connection returns values with:
         curl \
           -H "Accept: application/json" \
           -H "Authorization: Bearer $OP_API_TOKEN" \
           http://localhost:8080/v1/vaults
    
  3. Create a basic test.ts file with:

    import { OnePasswordConnect, Vault } from '@1password/connect';
    
    export async function getSecrets(): Promise<Vault[]> {
      try {
        const op = OnePasswordConnect({
          serverURL: 'http://localhost:8080',
          token: 'my-token',
          keepAlive: true,
        });
    
        return await op.listVaults();
      } catch (err) {
        return Promise.reject(err);
      }
    }
    
    async function main() {
      console.log('vaults:', await getSecrets());
    }
    
    main();
  4. run the file with ts-node ./test.ts, which results in:

        cause: Error: connect ECONNREFUSED ::1:8080
        at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16) {
          errno: -61,
          code: 'ECONNREFUSED',
          syscall: 'connect',
          address: '::1',
          port: 8080
        }
    
  5. Changing serverURL to http://127.0.0.1:8080 and rerunning the script then works as expected; returning a list of vaults.

Cannot set the Password field when creating new Items

Your environment

SDK Version: 1.4.0

Connect Server Version: 1.7.2

OS: Ubuntu 22.04.3 LTS (Jammy Jellyfish) (WSL2)

Node Version: 18.18.2

Context: Building a Backstage plugin for interacting with 1Password via Scaffolding actions.

What happened?

There is no way to set the username or password fields when creating a new Item. Attempting to include a field to set the password results in a similar field with the same name (but not the actual password field) being made, or it being completely ignored. In both cases the password remains blank. This is with the ItemBuilder and by manually creating an object with the necessary details (see below).

This appears to be the case for all "special" fields in across all Items, but I'm specifically using the "Login" item for my use-case.

What did you expect to happen?

I expect to be able to set the password (and any other fields) at creation time, as well as being able to effectively update these.

Steps to reproduce

  1. Create an item using the ItemBuilder as described in the documentation.
  2. Try to use ItemBuilder.addField() to add fields for Password, Username, etc.
  3. There is no option to set the password, username, or notesPlain - adding fields with similar labels/configurations are treated as separate fields with similar labels.
  4. Use ItemBuilder to build Item without any fields. Instead, manually create each FullItemAllOfFields and add it the built FullItem object (including a password field, as seen below).
  5. Use op.createItem() with the newly built Item with manual fields.
  6. New item is created in 1Password, but the password field that was manually put in is completely ignored. New item has everything except the password field, which is blank in 1Password.

Notes & Logs

Example Input

This is what is sent to the op.createItem() function.

{
  "fields": [
    {
      "section": {
        "id": "Section_SomeRandomSectionID",
        "label": "test section"
      },
      "type": "String",
      "label": "some label",
      "value": "static value!",
      "recipe": {}
    },
    {
      "id": "password",
      "type": "Concealed",
      "purpose": "Password",
      "label": "password",
      "generate": true,
      "recipe": { "length": 20, "characterSets": ["Letters", "Digits"] }
    }
  ],
  "tags": [],
  "title": "Test Item",
  "category": "LOGIN",
  "sections": [
    { "id": "Section_SomeRandomSectionID", "label": "test section" }
  ],
  "urls": [{ "href": "https://example.com/, Opens in a new window" }]
}

Output

This is the FullItem response from the op.createItem().

{
  "id": "SomeUniqueAndRandomItemId",
  "title": "Test Item",
  "vault": { "id": "REDACTED" },
  "category": "LOGIN",
  "urls": [{ "href": "https://example.com/" }],
  "createdAt": "2023-11-13T16:33:08.305Z",
  "updatedAt": "2023-11-13T16:33:08.305Z",
  "sections": [
    {
      "id": "Section_SomeRandomSectionID",
      "label": "test section"
    }
  ],
  "fields": [
    {
      "id": "username",
      "type": "STRING",
      "purpose": "USERNAME",
      "label": "username"
    },
    {
      "id": "password",
      "type": "CONCEALED",
      "purpose": "PASSWORD",
      "label": "password"
    },
    {
      "id": "notesPlain",
      "type": "STRING",
      "purpose": "NOTES",
      "label": "notesPlain"
    },
    {
      "id": "SomeUniqueAndRandomFieldId",
      "section": { "id": "Section_SomeRandomSectionID" },
      "type": "STRING",
      "label": "some label",
      "value": "static value!"
    }
  ]
}

Thanks, and appreciate any other guidance on this as well! ๐Ÿ˜ธ

NCC: UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'type' of null

Your environment

SDK Version: 1.0.0 or 1.0.1 - happening on both

OS: Ubuntu / MacOs

Node Version: v12.9.1

What happened?

NCC is failing to compile the project complaining of a TypeError of type null.

What did you expect to happen?

The project should compile normally.

Steps to reproduce

  1. Compile the project with ncc ncc build

Notes & Logs

(node:64130) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'type' of null
    at handleWrappers (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/loaders/relocate-loader.js.cache.js:12:121388)
    at e.exports (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/loaders/relocate-loader.js.cache.js:12:97983)
    at Object.e.exports (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/loaders/relocate-loader.js.cache.js:12:79903)
    at LOADER_EXECUTION (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/index.js.cache.js:1:879014)
    at runSyncOrAsync (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/index.js.cache.js:1:879025)
    at iterateNormalLoaders (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/index.js.cache.js:1:880623)
    at iterateNormalLoaders (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/index.js.cache.js:1:880491)
    at /Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/index.js.cache.js:1:880720
    at runSyncOrAsync (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/index.js.cache.js:1:879178)
    at iterateNormalLoaders (/Users/markmcwhirter/Documents/personal/1password-actions/node_modules/@vercel/ncc/dist/ncc/index.js.cache.js:1:880623)
(node:64130) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

I've created a separate Typscript project importing only 1Password's SDK and it's occurring there. This is happening on multiple machines, so I've ruled out an issue with my development environment.
image

FullItemAllOfFields TypeEnum.Totp points to incorrect field type

Your environment

SDK Version: 1.0.4

Connect Server Version: 1.5.0

OS: macOS 15.7

Node Version: 12.22.7

What happened?

Trying to create an item with an OTP field causes an error. The Connect server rejects the request with a validation error.

What did you expect to happen?

The item with an OTP field is created successfully.

Steps to reproduce

  1. Create an item with the following config:
const item = new ItemBuilder()
    .setCategory(CategoryEnum.Login)
    .addField({
        type: TypeEnum.Totp,
        label: "My OTP Field",
        value: "otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example",
    })
    .build();

/** setup client, send item to server **/
const op = OnePasswordConnect({
	serverURL: "http://localhost:8080",
	token: "my-token",
	keepAlive: true,
});
const createdItem = await op.createItem(my_vault_id_here, item);

You should receive a server error because the TypeEnum.Totp points to TOTP which is not a valid field type.

Notes & Logs

This is related to 1Password/connect#26

Enhance `getItem` functionality

Sumary

We want users to have an easy flow when using this SDK. For items, we want them to be able to provide either the ID or the title of an item as a parameter.

Tasks to be done

  • Adjust get function in src/lib/resources.ts so that now it checks whether the input is a valid Item ID or not (i.e. it matches the following regex: "^[a-z0-9]{26}$")
  • Adjust getItem by changing the parameter name to suggest that either the name or ID is accepted (e.g. itemQuery).
  • Create a new function getItemById in src/lib/op-connect.ts
    /**
     * Get details about a specific vault with a matching ID value.
     *
     * @param {string} vaultId
     * @param {string} itemId
     * @returns {Promise<FullItem>}
     */
    public async getItemById(vaultId: string, itemId: string): Promise<FullItem> {
        return await this.items.getById(vaultId, itemId);
    }
  • Add and adjust tests for the new functions in __test__/op-connect.test.ts

Add excludedChars support to the Field value generator

Summary

The Connect API >=1.4.0 spec shows a client can specify characters to exclude when using a field generator recipe.

The JS SDK should support this feature because users expect SDKs to have parity with our API spec.

Use cases

The excludeCharacters property lets customers have more control over their generated secrets. If we let them define allowed characters, why not disallowed characters?

Proposed Solution

Edit the model file to support the optional excludeCharacters field as a string type, per the spec.

Is there a workaround to accomplish this today?

No.

References & Prior Work

Add functionality to get an item's files

Summary

Starting with Connect 1.3.0, the users can get files that are stored in an Item. Connect Node SDK should enable the users to do that. In this issue, we will get the list of files that are in an Item.

Since the File object doesn't exist in this SDK yet, we will also create the File object in this issue, according to the API spec.

Tasks to be done

  • Create a new file named itemFile.ts and implement the ItemFile class. As an inspiration, you can take a look at how ItemURLs is implemented.
  • Implement listFiles function in the Items class in src/lib/resources.ts. The API endpoint that this function needs to call is v1/vaults/vaultId/items/itemId/files.
    /**
     * Lists all files an Item contains.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @returns {Promise<ItemFile[]>}
     * @private
     */
    private async listFiles(
             vaultId: string,
             itemQuery: string,
         ): Promise<ItemFile[]> {
         // functionality
    }
    Note: Feel free to place this functionality in a separate class (e.g. Files) if you feel it's more suitable. This is just a suggested approach.
  • Implement listFiles function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Get a list of files an Item contains.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @returns {Promise<ItemFile[]>}
     */
    public async listFiles(vaultId: string, itemQuery: string): Promise<ItemFile[]> {
          return await this.items.listFiles(vaultId, itemQuery);
    }
  • Add a test for the new function in __test__/op-connect.test.ts:
    test("list files", async () => {
        // actual test here
    }

options.response.data is not guaranteed to exist when client request fails

Your environment

SDK Version: 1.0.0.

Connect Server Version: 1.1.0

OS:MacOS

Node Version: 16.0.0

What happened?

If the client request fails for some reason, this catch handler will be run:

https://github.com/1Password/connect-sdk-js/blob/main/src/lib/client.ts#L69

However, in my case the handler actually throws because data is not available:

/foo/node_modules/@1password/connect/dist/lib/client.js:87
        (error) => Promise.reject(error.response.data));
                                                 ^

TypeError: Cannot read property 'data' of undefined

What did you expect to happen?

Error should try to define what went wrong in specific way, by at least exposing the http error code and the relevant message

Steps to reproduce

Create foo.mjs

import { OnePasswordConnect } from '@1password/connect';

const op = OnePasswordConnect({
	serverURL: 'http://x',
	token: 'x',
	keepAlive: true,
});

async function foo() {
	console.log(await op.listVaults())
}

console.log(foo())

Run with

node foo.mjs

listVaults returns vaults with undefined properties

Your environment

SDK Version: 1.3.0

Connect Server Version:

OS: macOS

Node Version: 16.14.2

What happened?

I used the 698 bytes length access token created from the integration tab, on my 1password server for OnePasswordConnect function.
Then, when I use listVaults, I get 10337 vaults, which all have only undefined properties.
I realized that no matter what my token is, I get the same results

What did you expect to happen?

Receive the actual vaults/ get an unauthorized exception (if the token is false)

Steps to reproduce

const op = OnePasswordConnect({
serverURL: "https://.1password.com",
token: ,
keepAlive: true,
});

const vaults = await op.listVaults()

op.createNewItem failing

Your environment

SDK Version: 1.0.2

Connect Server Version: 1.3.1

OS:11.4

Node Version:15.14

What happened?

When I attempt to create a new item I get a 400 response.

{ status: 400, message: 'Invalid Vault UUID' }

The vault UUID I set via .setVault is correct. After turning on debugging I noticed that the the requested urls have [object object] as apart of the path.

  opconnect:requests Sending request - POST v1/vaults/[object Object]/items/ +5ms
  opconnect:requests formatted url: http://localhost:8080/v1/vaults/[object%20Object]/items/ +0ms

What did you expect to happen?

I expected for opconnect to create a new item in the vault I specified.

Steps to reproduce

  1. set up a connect server
  2. use the example in the read me to create a new item with the item builder.
  3. run your code and observe the 400 error being returned

Notes & Logs

This is the code that I am running for reference

import { OnePasswordConnect, ItemBuilder } from "@1password/connect";

const VAULT_UUID = "...";

const op = OnePasswordConnect({
    serverURL: "http://localhost:8080",
    token: "...",
    keepAlive: true,
});


try {

    const newItem = new ItemBuilder()
        .setVault(VAULT_UUID)
        .setCategory("LOGIN")
        .addField({
            label: "Example",
            value: "MySecret",
            sectionName: "Demo Section",
        })
        .build();

    const createdItem = await op.createItem(newItem);

    console.log(createdItem)

} catch (err) {
    console.log(err);
}

Add functionality to get a vault by its title

Summary

Currently this is what the users can do when it comes to vaults:

  • listVaults - get the list of all vaults that the Connect token has access to.
  • getVault(vaultId) - get a Vault by its ID.

We want to enhance the way users can get vaults when using the Connect Node SDK. In this issue, we want to enable users to get a vault by its title.

Tasks to be done

  • Implement getVaultByTitle function in the Vaults class in src/lib/resources.ts:
    /**
     * Search for a Vault with an exact match on title.
     * If no Vaults with the title are found, it returns an error.
     * If multiple Vaults with the same title are found, it returns an error.
     *
     * @param {string} title
     * @returns {Promise<Vault>}
     * @private
     */
    private async getVaultByTitle(
             title: string,
         ): Promise<Response> {
         // functionality
    }
    Note: You can make use of the listVaultsByTitle functionality and add if the list has exactly one Vault.
  • Implement getVaultByTitle function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Get details about a specific vault with a matching Title value.
     *
     * @param {string} vaultTitle
     * @returns {Promise<Vault>}
     */
    public async getVaultByTitle(vaultTitle: string): Promise<Vault> {
        return await this.vaults.getVaultByTitle(vaultTitle);
    }
  • Add a test for the new function in __test__/op-connect.test.ts below get vault test case:
    test("get vault by titte", async () => {
        // actual test here
    }

Add test coverage reports

Summary

Users should have confidence that the SDK is well-tested before choosing to integrate it with their applications. We can assure users that the code is stable and well-tested by providing test coverage metrics.

Use cases

Users considering the JS SDK want to be sure they can safely integrate the library into their applications. By providing code coverage reports, they can be sure that the library works as described and won't do anything surprising.

Most open-source SDKs provide code coverage reports to their users, and we should follow that practice.

Proposed Solution

We need to:

  • Identify a code coverage tool that is compatible with our test runner (Jest)
  • Integrate the code coverage into our pipelines
  • Save code coverage reports
  • Display the code coverage report prominently on the repo README

Is there a workaround to accomplish this today?

n/a

References & Prior Work

Add functionality to get File by ID

Summary

Starting with Connect 1.3.0, the users can get files that are stored in an Item. Connect Node SDK should enable the users to do that.

In this issue, we will get a file based on its ID.

Tasks to be done

  • Implement getFile function in the Items class in src/lib/resources.ts. The API endpoint that this function needs to call is v1/vaults/vaultId/items/itemId/files/fileId.
    /**
     * Get an Item's specific File with a matching ID value.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @param {string} fileId
     * @returns {Promise<ItemFile>}
     * @private
     */
    private async getFile(
             vaultId: string,
             itemQuery: string,
             fileId: string,
         ): Promise<ItemFile> {
         // functionality
    }
    Note: Feel free to place this functionality in a separate class (e.g. Files) if you feel it's more suitable. This is just a suggested approach.
  • Implement getFile function in OPConnect class in src/lib/op-connect.ts:
    /**
     * Get an Item's specific File with a matching ID value.
     *
     * @param {string} vaultId
     * @param {string} itemQuery
     * @param {string} fileId
     * @returns {Promise<ItemFile>}
     */
    public async getFile(vaultId: string, itemQuery: string, fileId: string): Promise<ItemFile> {
          return await this.items.getFile(vaultId, itemQuery);
    }
  • Add a test for the new function in __test__/op-connect.test.ts:
    test("get file", async () => {
        // actual test here
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.