Skip to content
Source
Sign inSign up

definition.ts

41 lines1.8 KB

1import { SecretProviderKind } from "@t3tools/contracts";
2import { defineSecretProvider } from "@t3tools/secret-provider-core/shared/definition";
3import * as Schema from "effect/Schema";
4​
5const ACCOUNT_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
6​
7/**
8 * Any value `op --account` accepts: shorthand, sign-in address, account ID, or user ID.
9 * It is passed to the CLI as an argument, so it can never start with `-`.
10 */
11export const OnePasswordAccount = Schema.String.check(
12 Schema.isMaxLength(253),
13 Schema.makeFilter((value: string) =>
14 ACCOUNT_PATTERN.test(value)
15 ? true
16 : "1Password account must be a shorthand, sign-in address, or ID with no spaces.",
17 ),
18).pipe(Schema.brand("OnePasswordAccount"));
19export type OnePasswordAccount = typeof OnePasswordAccount.Type;
20​
21export const OnePasswordSecretProviderConfig = Schema.Struct({
22 account: OnePasswordAccount,
23});
24export type OnePasswordSecretProviderConfig = typeof OnePasswordSecretProviderConfig.Type;
25​
26// 1Password secret reference syntax: names outside this charset must be written as item ids.
27// It also keeps `{{`, `}}`, and line breaks out of the `op inject` template the server builds.
28const NAME = String.raw`[A-Za-z0-9._-](?:[A-Za-z0-9 ._-]*[A-Za-z0-9._-])?`;
29const REFERENCE = new RegExp(
30 String.raw`^op://${NAME}(?:/${NAME}){2,3}(?:\?[a-z-]+=[A-Za-z0-9_-]+)?$`,
31);
32const MAX_REFERENCE_LENGTH = 1024;
33​
34export const definition = defineSecretProvider({
35 kind: SecretProviderKind.make("one_password"),
36 label: "1Password",
37 configSchema: OnePasswordSecretProviderConfig,
38 isReference: (reference) => reference.length <= MAX_REFERENCE_LENGTH && REFERENCE.test(reference),
39 referencePlaceholder: "op://vault/item/field",
40 invalidReferenceMessage: "Use a 1Password reference like op://vault/item/field.",
41});