From 35bc4bc1122e545e8d82563fcb49263ecfdd9980 Mon Sep 17 00:00:00 2001 From: Theo Ephraim Date: Fri, 16 Aug 2024 00:35:25 -0700 Subject: [PATCH] use field ids, better error mesages, update 1pass plugin docs --- .changeset/big-swans-own.md | 7 + example-repo/.dmno/config.mts | 127 ++++++++-------- .../plugins/1password/blob-item-example.png | Bin 0 -> 101035 bytes .../content/docs/docs/plugins/1password.mdx | 140 +++++++++++------- packages/plugins/1password/src/plugin.ts | 53 +++++-- 5 files changed, 202 insertions(+), 125 deletions(-) create mode 100644 .changeset/big-swans-own.md create mode 100644 packages/docs-site/src/assets/docs-images/plugins/1password/blob-item-example.png diff --git a/.changeset/big-swans-own.md b/.changeset/big-swans-own.md new file mode 100644 index 00000000..a163aad2 --- /dev/null +++ b/.changeset/big-swans-own.md @@ -0,0 +1,7 @@ +--- +"@dmno/encrypted-vault-plugin": patch +"@dmno/1password-plugin": patch +"dmno": patch +--- + +1password plugin improvements, related refactoring diff --git a/example-repo/.dmno/config.mts b/example-repo/.dmno/config.mts index 313b0ef3..a3c3c0bd 100644 --- a/example-repo/.dmno/config.mts +++ b/example-repo/.dmno/config.mts @@ -48,11 +48,6 @@ export default defineDmnoService({ OP_TOKEN: { extends: OnePasswordTypes.serviceAccountToken, }, - - TEST_PROD_AUTH: { - extends: 'boolean', - }, - // OP_TOKEN_PROD: { // extends: OnePasswordTypes.serviceAccountToken, // }, @@ -64,7 +59,7 @@ export default defineDmnoService({ value: OnePassSecretsDev.itemById("ut2dftalm3ugmxc6klavms6tfq", "bphvvrqjegfmd5yoz4buw2aequ", "username"), }, OP_ITEM_BY_LINK: { - value: OnePassSecretsDev.itemByLink("https://start.1password.com/open/i?a=I3GUA2KU6BD3FBHA47QNBIVEV4&v=ut2dftalm3ugmxc6klavms6tfq&i=bphvvrqjegfmd5yoz4buw2aequ&h=dmnoinc.1password.com", "sectiontest/section-child"), + value: OnePassSecretsDev.itemByLink("https://start.1password.com/open/i?a=I3GUA2KU6BD3FBHA47QNBIVEV4&v=ut2dftalm3ugmxc6klavms6tfq&i=bphvvrqjegfmd5yoz4buw2aequ&h=dmnoinc.1password.com", ""), }, OP_ITEM_BY_REFERENCE: { value: OnePassSecretsDev.itemByReference("op://dev test/example/username"), @@ -89,78 +84,78 @@ export default defineDmnoService({ value: 'rootonly', }, - // VAULT_ITEM_1: { - // value: ProdVault.item(), - // }, - // VAULT_ITEM_WITH_SWITCH: { - // value: switchByNodeEnv({ - // _default: NonProdVault.item(), - // staging: switchBy('CONTEXT', { - // 'branch-preview': ProdVault.item(), - // 'pr-preview': ProdVault.item(), - // }), - // production: ProdVault.item() - // }), - // }, + VAULT_ITEM_1: { + value: ProdVault.item(), + }, + VAULT_ITEM_WITH_SWITCH: { + value: switchByNodeEnv({ + _default: NonProdVault.item(), + staging: switchBy('CONTEXT', { + 'branch-preview': ProdVault.item(), + 'pr-preview': ProdVault.item(), + }), + production: ProdVault.item() + }), + }, PICK_TEST: { value: (ctx) => `pick-test--${DMNO_CONFIG.ROOT_ONLY}`, }, - // CONTACT_EMAIL: { - // extends: DmnoBaseTypes.email({ - // normalize: true, - // }), - // // required: true, - // value: 'Test@test.com' - // }, + CONTACT_EMAIL: { + extends: DmnoBaseTypes.email({ + normalize: true, + }), + // required: true, + value: 'Test@test.com' + }, - // SOME_IPV4: { - // extends: DmnoBaseTypes.ipAddress, - // required: true, - // value: '100.200.1.1' - // }, + SOME_IPV4: { + extends: DmnoBaseTypes.ipAddress, + required: true, + value: '100.200.1.1' + }, - // SOME_IPV6: { - // extends: DmnoBaseTypes.ipAddress({ - // version: 6, - // normalize: true, - // }), - // required: true, - // value: '2001:0DB8:85a3:0000:0000:8a2e:0370:7334' - // }, + SOME_IPV6: { + extends: DmnoBaseTypes.ipAddress({ + version: 6, + normalize: true, + }), + required: true, + value: '2001:0DB8:85a3:0000:0000:8a2e:0370:7334' + }, - // SOME_PORT: { - // extends: DmnoBaseTypes.port, - // required: true, - // value: '8080' - // }, + SOME_PORT: { + extends: DmnoBaseTypes.port, + required: true, + value: '8080' + }, - // SOME_SEMVER: { - // extends: DmnoBaseTypes.semver({ - // normalize: true, - // }), - // required: true, - // value: '1.2.3-ALPHA.1' - // }, + SOME_SEMVER: { + extends: DmnoBaseTypes.semver({ + normalize: true, + }), + required: true, + value: '1.2.3-ALPHA.1' + }, - // SOME_DATE: { - // extends: DmnoBaseTypes.isoDate, - // required: true, - // value: new Date().toISOString() - // }, + SOME_DATE: { + extends: DmnoBaseTypes.isoDate, + required: true, + value: new Date().toISOString() + }, - // SOME_UUID: { - // extends: DmnoBaseTypes.uuid, - // required: true, - // value: '550e8400-e29b-41d4-a716-446655440000' - // }, + SOME_UUID: { + extends: DmnoBaseTypes.uuid, + required: true, + value: '550e8400-e29b-41d4-a716-446655440000' + }, - // SOME_MD5: { - // extends: DmnoBaseTypes.md5, - // required: true, - // value: 'd41d8cd98f00b204e9800998ecf8427e' - // }, + SOME_MD5: { + extends: DmnoBaseTypes.md5, + required: true, + value: 'd41d8cd98f00b204e9800998ecf8427e' + }, } }); diff --git a/packages/docs-site/src/assets/docs-images/plugins/1password/blob-item-example.png b/packages/docs-site/src/assets/docs-images/plugins/1password/blob-item-example.png new file mode 100644 index 0000000000000000000000000000000000000000..3d1b2a5ae0f000a38a7cad8caf14dd70a9b71a82 GIT binary patch literal 101035 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 literal 0 HcmV?d00001 diff --git a/packages/docs-site/src/content/docs/docs/plugins/1password.mdx b/packages/docs-site/src/content/docs/docs/plugins/1password.mdx index 81799d8c..cd7818f5 100644 --- a/packages/docs-site/src/content/docs/docs/plugins/1password.mdx +++ b/packages/docs-site/src/content/docs/docs/plugins/1password.mdx @@ -6,103 +6,129 @@ description: DMNO's 1Password plugin allows you to securely access your stored s import { Steps, Icon } from '@astrojs/starlight/components'; import TabbedCode from '@/components/TabbedCode.astro'; -DMNO's 1Password plugin allows you to securely access your stored secrets in 1Password. This plugin uses the 1Password CLI and can communicate by means of a [Service Account](https://developer.1password.com/docs/service-accounts) or during local development by [integrating with the 1Password desktop app](https://developer.1password.com/docs/cli/get-started/#step-2-turn-on-the-1password-desktop-app-integration). It is compatible with any account type. Note that rate limits vary by account type, you can read more about that in the [1Password Developer documentation](https://developer.1password.com/docs/service-accounts/rate-limits/). +DMNO's [1Password](https://1password.com/) plugin allows you to securely access your secrets stored in 1Password. This plugin uses their [JavaScript SDK](https://github.com/1Password/onepassword-sdk-js/) to authenticate via a [service account](https://developer.1password.com/docs/service-accounts). Additionally, for local development, you can opt-in to use your system-installed [1Password CLI](https://developer.1password.com/docs/cli/get-started/) and its [integration with the 1Password desktop app](https://developer.1password.com/docs/cli/get-started/#step-2-turn-on-the-1password-desktop-app-integration), which uses your personal account gated behind biometric unlocking of the desktop app. This plugin is compatible with any 1Password account type (personal, family, teams, business), but note that [rate limits](https://developer.1password.com/docs/service-accounts/rate-limits/) vary by account type. -## Installation +## Installation & setup -Install the package in your service(s) that will use config from 1password. +Install the package in your service(s) that will use config from 1Password. ----- -After installation, you'll need to initialize the plugin in your dmno config and wire it up to the config path that will hold your 1password service account token. It's ok if you have not created this service account yet - we'll do that in the next section. +After installation, you'll need to initialize the plugin in your dmno config and wire it up to the config path that will hold your 1Password service account token. It's ok if you have not created this service account yet - we'll do that in the next section. -```typescript title='.dmno/config.mts' -import { OnePasswordDmnoPlugin, OnePasswordTypes } from '@dmno/1password-plugin'; +```diff lang="ts" title='.dmno/config.mts' ++import { OnePasswordDmnoPlugin, OnePasswordTypes } from '@dmno/1password-plugin'; -const OnePassBackend = new OnePasswordDmnoPlugin('1pass/prod', { - token: configPath('OP_TOKEN'), -}); ++const OnePassBackend = new OnePasswordDmnoPlugin('1pass', { ++ token: configPath('OP_TOKEN'), ++}); export default defineDmnoService({ schema: { - OP_TOKEN: { - extends: OnePasswordTypes.serviceAccountToken, - // NOTE - the type itself is already marked as sensitive 🔐 - }, ++ OP_TOKEN: { ++ extends: OnePasswordTypes.serviceAccountToken, ++ // NOTE - the type itself is already marked as sensitive 🔐 ++ }, }, }); ``` -:::tip -You must give each plugin instance a unique id so we can refer to it in other services and the CLI. In this case we used `1pass/prod`, as you can imagine using multiple 1password vaults and having another plugin instance of `1pass/non-prod`. +:::tip[Plugin instance IDs] +You must give each plugin instance a unique id so we can refer to it in other services and the [`dmno` CLI](/docs/reference/cli/plugin/). + +In this case we used `1pass`, but you can imagine splitting vaults and access, and having multiple plugin instances - for example `1pass/prod` for highly sensitive production secrets and `1pass/dev` for everything else. ::: ### Injecting the plugin in monorepo services -In a monorepo, if you are managing config for multiple services in a single vault, you should initialize the plugin instance once in your root service as seen above, and then _inject_ it in the child services. Note we must use that same id we set during initialization. +In a monorepo, you are likely managing secrets for multiple services. If you will be using the same service account(s) to access those secrets, you can initialize a plugin instance once in your root service as seen above, and then _inject_ it in the child services. Note we must use that same id we set during initialization. ```typescript title='apps/some-service/.dmno/config.mts' import { OnePasswordDmnoPlugin } from '@dmno/1password-plugin'; -// inject the already initialized plugin instead of re-initializing it -const OnePassBackend = OnePasswordDmnoPlugin.injectInstance('1pass/prod'); +// 💉 inject the already initialized plugin instead of re-initializing it +const OnePassBackend = OnePasswordDmnoPlugin.injectInstance('1pass'); ``` -:::tip -For more on 1Password security, see their best practices for [CLI](https://developer.1password.com/docs/cli/best-practices/) and [business accounts](https://support.1password.com/business-security-practices/#access-management-and-the-principle-of-least-privilege). -::: - - ------------ ## Setup vault & service account +If you already use 1password and your secrets live in a vault that holds other important passwords and info, you should create a new vault and move your secrets to it, because **the access system of 1password is based on vaults, not individual items**. + -1. **Create a vault** in your 1Password account. This is where you'll store your secrets. You can create multiple vaults for different environments or services. [link](https://support.1password.com/create-share-vaults/#create-a-vault) +1. **Create a vault** in your 1Password account which will be used to hold your secrets. You can create multiple vaults to segment access to different environments, services, etc. You can use any 1password app, the web app, or the CLI. [link](https://support.1password.com/create-share-vaults/#create-a-vault) + +2. **Create a new service account** and grant access to necessary vault(s). This is a special account used for machine-to-machine communication. This is done in the 1Password web interface. Be sure to copy the new service account token or save it in another vault. [link](https://developer.1password.com/docs/service-accounts/get-started/) + :::note[Vault access set during creation only] + Vault access rules cannot be edited after creation, so if your vault setup changes, you will need to create new service account(s) and update the tokens. + ::: -2. **Create a service account** in your 1Password account. This is a separate account that has access to the vault(s) you created. You can create multiple service accounts for different environments or services. [link](https://developer.1password.com/docs/service-accounts/get-started/) +3. **Grant vault access to users/teams (optional)**. Your developers may need access to at least some of your vaults, especially if using the `op` cli based auth mentioned below. [link](https://support.1password.com/create-share-vaults-teams/#share-a-vault) -3. **Grant vault access to the service account**. This is done in the 1Password web interface. You can add multiple service accounts to a single vault. [link](https://developer.1password.com/docs/service-accounts/manage-service-accounts/#manage-access) +4. **Ensure vault service account access is enabled (optional)**. Each vault has a toggle to disable service account access _in general_. It is on by default, so you will likely not need to do anything. [link](https://developer.1password.com/docs/service-accounts/manage-service-accounts/#manage-access) -4. **Grant vault access to users/teams (optional)**. During local development, if you'd rather not useon using the op cli's integration with the Desktop app -This service account token will now serve as your "secret-zero" - which grants access to the rest of your sensitive config stored in 1password. It must be set locally and in deployed environments, and as it is sensitive, we must pass in the value as an _override_ rather than storing it within the config. Locally this usually means storing it in your `.env.local` and on a deployed environment you'll usually set it within some kind of UI, wherever you would normally pass in secrets. +This service account token will now serve as your "secret-zero" - which grants access to the rest of your sensitive config stored in 1Password. It must be set locally (unless relying on cli-based auth) and in deployed environments. It is sensitive so we must pass in the value as an _override_ rather than storing it within the config. Locally this usually means storing it in your [`.env.local` file](/docs/guides/env-files/) and on a deployed environment you'll usually set it within some kind of UI, wherever you would normally pass in environment variables. ```diff title=".dmno/.env.local" +OP_TOKEN=ops_abc123... ``` -Note that the config path of `OP_TOKEN` is arbitrary and you can see how it was wired up from the config to the plugin input above. If you are using multiple vaults and service accounts, you may have something more like `OP_PROD_TOKEN` and `OP_NON_PROD_TOKEN`. +Note that the config path of `OP_TOKEN` is arbitrary and you can see how it was wired up from your config schema to the plugin input in the example above. If you are using multiple vaults and service accounts, you may have something more like `OP_TOKEN_PROD` and `OP_TOKEN_DEV`. -:::tip -Consider how you want to organize your vaults and service accounts. You might have a single vault for all your secrets per environment, or you might have separate vaults for each service and environment. At a minimum, DMNO recommends having separate vaults for production and non-production environments. +:::tip[Vault organization best practices] +Consider how you want to organize your vaults and service accounts, keeping in mind [best practices](https://support.1password.com/business-security-practices/#access-management-and-the-principle-of-least-privilege). At a minimum, DMNO recommends having a vault for highly sensitive production secrets and another for everything else. ::: -### Desktop app integration +### Desktop app / CLI integration (optional) + +During local development, you may find it convenient to skip the service account tokens and instead rely on your system's `op` CLI and its [integration with the 1Password desktop app](https://developer.1password.com/docs/cli/get-started/#step-2-turn-on-the-1password-desktop-app-integration). This means you will be connecting to 1Password as if you were using your local 1Password desktop application, including using it's biometric unlocking features. + + +1. **Opt-in while initializing the plugin** + ```diff lang="ts" title='.dmno/config.mts' + const OnePassBackend = new OnePasswordDmnoPlugin('1pass/dev', { + token: configPath('OP_TOKEN'), + + fallbackToCliBasedAuth: true, + }); + ``` + + _Of course you can also point to a `configPath` in your schema and toggle the opt-in based on some other logic if you'd like._ + +2. **Ensure the `op` CLI is installed**. [docs](https://developer.1password.com/docs/cli/get-started/) + +3. **Enable the desktop app + CLI integration**. [docs](https://developer.1password.com/docs/cli/get-started/#step-2-turn-on-the-1password-desktop-app-integration) -During local development, you may find it convenient to use the onepoas +4. **Run `op signin` to log in on the CLI**. Ensure you are logged in to the correct account. You can run `op whoami` to see which account is currently connected to the CLI. + + +With this option enabled, if the resolved service account token is empty, we will call out to the `op` cli installed on your machine (it must be in your `$PATH`) and use the auth it provides. With the desktop app integration enabled, it will call out and may trigger biometric verification to unlock. It is slick and very convenient! +:::caution[Connecting as yourself] +Keep in mind that this method is connecting as _YOU_ who may have more access than a tightly scoped service account. Consider only enabling this method for a plugin instance that will be handling non-production secrets. +::: ------ -## Add your items +## Add items to your schema -DMNO supports a few different ways to reference items in 1Password. +With the plugin initialized and access wired up, now we must update our config schema to know which items will be coming from 1Password and where to look. DMNO supports a few different ways to reference items in 1Password: -### Using a env blob (recommended) +### Using a `.env` blob -Managing lots of individual 1password items and connecting them to your config can be a bit tedious, so we recommend storing multiple items together in a `.env` style text blob. Using this method, we'll have a single 1password item that can have one text entry per service containing the `.env` blob. This would be similar to applying a `.env.local` file as overrides, except they are secured and shared via 1password. This also makes it incredibly easy to migrate from using local `.env` files. +Managing lots of individual 1Password items and connecting them to your config can be a bit tedious, so when getting started, we recommend storing multiple items together in a `.env` style text blob. Using this method, we'll have a single 1Password item that can have one text entry per service containing the `.env` blob. This would be similar to applying a `.env.local` file as overrides, except they are secured and shared via 1Password. This also makes it incredibly easy to migrate from using local `.env` files. -To use this method, we need to tell the plugin which 1password item will store our `.env` blob(s). As this value is static and not sensitive, we can use a static value as our plugin input. +To use this method, we need to tell the plugin which 1Password item will store our `.env` blob(s). As this link is not sensitive, we can use a static value as our plugin input. -```diff lang="ts" title=".dmno/config.mts" -import { OnePasswordDmnoPlugin, OnePasswordTypes } from '@dmno/1password-plugin'; +Then use the `.item()` value resolver for any config values that will be stored in the linked 1Password item. +```diff lang="ts" title=".dmno/config.mts" const OnePassBackend = new OnePasswordDmnoPlugin('1pass/prod', { token: configPath('OP_TOKEN'), + envItemLink: 'https://start.1password.com/open/i?a=I3GUA2KU6BD3FBHA47QNBIVEV4&v=ut2dftalm3ugmxc6klavms6tfq&i=n4wmgfq77mydg5lebtroa3ykvm&h=dmnoinc.1password.com', @@ -121,11 +147,22 @@ export default defineDmnoService({ }); ``` +:::tip[Where to find an item private link] +You can find the private link by clicking the 3 dots on the item in the 1Password interface and selecting `Copy Private Link`. +::: + +Values are looked up within the linked 1Password item using a simple convention. We expect to find a _text field_ within the item with a label set to the current [service name](/docs/guides/schema/#service-names). The contents of that item are parsed as a [`.env` file](https://dotenvx.com/docs/env-file), and we look up items using the config item key. If no match is found, we will also look in an additional field with the label `_default`. + +![1Password blob item example](../../../../assets/docs-images/plugins/1password/blob-item-example.png) + +For example, in the item above, an item with the key `ONE_MORE` would fallback to the value in the `_default` field in any service that wasn't named `root`. + + {/* TODO: add screenshot of 1pass item showing the entry? */} -### Using specific 1password items +### Using specific 1Password items -If you already have lots of indivdual items in 1password, or you just don't want to use the blob method, you can wire up invididual config items to specific 1password items. We provide several methods to do so. Note that while a 1password reference (e.g., `op://vaultname/itemname/path`) points all the way to a specific value, the other methods only get us to an item which usually contains multiple entries (account id, secret key, etc). In these cases you must also pass in an additional path to the specific entry. These paths use the entry labels. +If you already have lots of indivdual items in 1Password, or you just don't want to use the blob method, you can wire up invididual config items to specific 1Password items. We provide several methods to do so. Note that while a 1Password reference (e.g., `op://vaultname/itemname/path`) is easier to use in some ways, they are based on field labels and are not stable, so the other methods are preferred. ```ts export default defineDmnoService({ @@ -134,14 +171,14 @@ export default defineDmnoService({ ITEM_WITH_LINK: { value: OnePassBackend.itemByLink( 'https://start.1password.com/open/i?a=I3GUA2KU6BD3FBHA47QNBIVEV4&v=ut2dftalm3ugmxc6klavms6tfq&i=n4wmgfq77mydg5lebtroa3ykvm&h=dmnoinc.1password.com', - 'somepath', + 'somefieldid', ), }, - // using vault + item UUIDs + // using UUIDs ITEM_WITH_IDS: { - value: OnePassBackend.itemById('vaultUuid', 'itemUuid', 'somepath'), + value: OnePassBackend.itemById('vaultUuid', 'itemUuid', 'somefieldid'), }, - // using item reference + // using item reference url ITEM_WITH_REFERENCE: { value: OnePassBackend.itemByReference('op://vaultname/itemname/path'), }, @@ -150,11 +187,14 @@ export default defineDmnoService({ ``` :::tip[Where to find an item private link] -You can find the private link by clicking the 3 dots on the item in the 1Password interface and selecting `Copy Private Link`. +You can find the private link by clicking the 3 dots **on the item** in the 1Password interface and selecting `Copy Private Link`. ::: -:::tip[Where to find an item reference] -The secret reference for invidivual items can be found by clicking on the down arrow icon on the item and selecting `Copy Secret Reference`. +:::tip[Where to find field IDs] +Field IDs are not easy to get from the 1Password UI. Luckily when the supplied field ID is not found, our error message includes a list of all the possible IDs in the item. Simply start with an empty string or a bogus id like `"?"` and use the DMNO error message to find the right field ID. +::: -If you don't see the menu option, you may need to enable it in the 1Password Developer settings and you may need to install the 1Password CLI as well. +:::tip[Where to find an item reference] +The secret reference for invidivual fields within an item can be found by clicking on the down arrow icon **on the field** and selecting `Copy Secret Reference`. ::: + diff --git a/packages/plugins/1password/src/plugin.ts b/packages/plugins/1password/src/plugin.ts index 96c65ba8..9ebca282 100644 --- a/packages/plugins/1password/src/plugin.ts +++ b/packages/plugins/1password/src/plugin.ts @@ -15,6 +15,7 @@ import { Client, createClient } from '@1password/sdk'; import { name as thisPackageName, version as thisPackageVersion } from '../package.json'; import { OnePasswordTypes } from './data-types'; +type FieldId = string; type ItemId = string; type VaultId = string; type VaultName = string; @@ -100,13 +101,16 @@ export class OnePasswordDmnoPlugin extends DmnoPlugin { token: { description: 'this service account token will be used via the CLI to communicate with 1password', extends: OnePasswordTypes.serviceAccountToken, + // TODO: add validation, token must be set unless `fallbackToCliBasedAuth` is true // required: true, }, envItemLink: { description: 'link to secure note item containing dotenv style values', extends: OnePasswordTypes.itemLink, }, - + fallbackToCliBasedAuth: { + description: "if token is empty, use system's `op` CLI to communicate with 1password", + }, } satisfies DmnoPluginInputSchema; // ^^ note this explicit `satisfies` is needed to give us better typing on our inputSchema @@ -138,6 +142,7 @@ export class OnePasswordDmnoPlugin extends DmnoPlugin { // using sdk if (this.opClient) { return await ctx.getOrSetCacheItem(`1pass-sdk:V|${vaultId}/I|${itemId}`, async () => { + // TODO: better error handling to tell you what went wrong? no access, non existant, etc const opItem = await this.opClient!.items.get(vaultId, itemId); return JSON.parse(JSON.stringify(opItem)); // convert to plain object }); @@ -157,6 +162,7 @@ export class OnePasswordDmnoPlugin extends DmnoPlugin { // using sdk if (this.opClient) { return await ctx.getOrSetCacheItem(`1pass-sdk:R|${referenceUrl}`, async () => { + // TODO: better error handling to tell you what went wrong? no access, non existant, etc return await this.opClient!.secrets.resolve(referenceUrl); }); } @@ -243,7 +249,7 @@ export class OnePasswordDmnoPlugin extends DmnoPlugin { * * To get an item's link, right click on the item and select "Copy Private Link" (or select the item and click the ellipses / more options menu) * */ - itemByLink(privateLink: string, path?: string) { + itemByLink(privateLink: string, fieldIdOrPath?: FieldId | { path: string }) { const linkValidationResult = OnePasswordTypes.itemLink().validate(privateLink); if (linkValidationResult !== true) { @@ -255,19 +261,22 @@ export class OnePasswordDmnoPlugin extends DmnoPlugin { const vaultId = url.searchParams.get('v')!; const itemId = url.searchParams.get('i')!; - return this.itemById(vaultId, itemId, path); + return this.itemById(vaultId, itemId, fieldIdOrPath); } // can read items by id - need a vault id, item id // and then need to grab the specific data from a big json blob // cli command `op item get bphvvrqjegfmd5yoz4buw2aequ --vault=ut2dftalm3ugmxc6klavms6tfq --format json` - itemById(vaultId: VaultId, itemId: ItemId, path?: string) { + itemById(vaultId: VaultId, itemId: ItemId, fieldIdOrPath?: FieldId | { path: string }) { + const fieldId = _.isString(fieldIdOrPath) ? fieldIdOrPath : undefined; + const path = _.isObject(fieldIdOrPath) ? fieldIdOrPath.path : undefined; return this.createResolver({ label: (ctx) => { return _.compact([ `Vault: ${vaultId}`, `Item: ${itemId}`, + fieldId && `Field: ${fieldId}`, path && `Path: ${path}`, ]).join(', '); }, @@ -277,9 +286,35 @@ export class OnePasswordDmnoPlugin extends DmnoPlugin { const itemObj = await this.getOpItemById(ctx, vaultId, itemId); - // TODO: path is necessary... maybe we could return the first item or something if none is specified? + const sectionsById = _.keyBy(itemObj.sections, (s) => s.id); + + // field selection by id + if (fieldId !== undefined) { + const field = _.find(itemObj.fields, (f) => f.id === fieldId); + if (field) { + // do we want to throw an error if we found the value but its empty? + return field.value; + } + // console.log(itemObj); + const possibleFieldIds = _.compact(_.map(itemObj.fields, (f) => { + if (f.value === undefined || f.value === '' || f.purpose === 'NOTES') return undefined; + const section = sectionsById[f.sectionId || f.section?.id]; + return { id: f.id, label: f.label || f.title, sectionLabel: section?.label || section?.title }; + })); + throw new ResolutionError(`Unable to find field ID "${fieldId}" in item`, { + tip: [ + 'Perhaps you meant one of', + ...possibleFieldIds.map((f) => [ + '- ', + f.sectionLabel ? `${f.sectionLabel} > ` : '', + f.label, + ` - ID = ${f.id}` + ].join('')), + ] + }); + } + // field selection by path if (path) { - const sectionsById = _.keyBy(itemObj.sections, (s) => s.id); const valueAtPath = _.find(itemObj.fields, (i) => { // using the cli, each item has the reference included if (i.reference) { @@ -297,10 +332,10 @@ export class OnePasswordDmnoPlugin extends DmnoPlugin { } return valueAtPath.value; } + // should we fallback to first item or? - // TODO: better error handling to tell you what went wrong? no access, non existant, etc - return itemObj; + }, }); } @@ -337,7 +372,7 @@ export interface OnePasswordDmnoPlugin { /** private link to item containing dotenv style values (optional) */ envItemLink?: string; /** rely on auth from system installed `op` cli instead of a service account */ - useSystemCli?: boolean, + fallbackToCliBasedAuth?: boolean, } }