@opengeni/vaults-onepassword 3.1.3-canary.38890816741001 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +54 -18
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts +6 -1
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/provider.ts +75 -17
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* apps/worker (the SDK carries a ~14 MB WASM core); see
|
|
6
6
|
* test/import-guard.test.ts.
|
|
7
7
|
*/
|
|
8
|
-
export { createOnePasswordVaultProvider, ONEPASSWORD_GET_ALL_BATCH, ONEPASSWORD_MANAGED_GROUP_PERMISSIONS, ONEPASSWORD_VALUE_CACHE_MS, type OnePasswordVaultProvider, type OnePasswordVaultProviderOptions, } from "./provider.js";
|
|
8
|
+
export { createOnePasswordVaultProvider, OnePasswordVaultCreatedError, ONEPASSWORD_GET_ALL_BATCH, ONEPASSWORD_MANAGED_GROUP_PERMISSIONS, ONEPASSWORD_VALUE_CACHE_MS, type OnePasswordVaultProvider, type OnePasswordVaultProviderOptions, } from "./provider.js";
|
|
9
9
|
export { createAttemptProviderBudget, ONEPASSWORD_PLAN_LIMITS, ONEPASSWORD_REQUEST_COST, OnePasswordQuota, onePasswordQuotaFor, PROVIDER_READS_PER_ATTEMPT, resetOnePasswordQuotasForTests, type OnePasswordOperation, type OnePasswordPlanTier, } from "./budget.js";
|
|
10
10
|
export { classifyOnePasswordMessage, mapOnePasswordError, ONEPASSWORD_MESSAGE_RULES, onePasswordRetryAfterMs, } from "./errors.js";
|
|
11
11
|
export { describeOnePasswordToken, isOnePasswordFakeToken, ONEPASSWORD_FAKE_TOKENS, type OnePasswordFakeToken, type OnePasswordTokenDescription, } from "./token.js";
|
package/dist/index.js
CHANGED
|
@@ -642,6 +642,16 @@ async function onePasswordTokenFingerprint(token) {
|
|
|
642
642
|
var ONEPASSWORD_VALUE_CACHE_MS = 6e4;
|
|
643
643
|
var ONEPASSWORD_GET_ALL_BATCH = 50;
|
|
644
644
|
var ONEPASSWORD_MANAGED_GROUP_PERMISSIONS = 32 | 16 | 1024 | 128 | 64 | 256 | 512;
|
|
645
|
+
var OnePasswordVaultCreatedError = class extends VaultProviderError {
|
|
646
|
+
constructor(createdVault, failure) {
|
|
647
|
+
super(
|
|
648
|
+
failure.code,
|
|
649
|
+
"The vault was created, but its group access could not be confirmed. Do not create it again.",
|
|
650
|
+
failure.retryAfterMs
|
|
651
|
+
);
|
|
652
|
+
this.createdVault = createdVault;
|
|
653
|
+
}
|
|
654
|
+
};
|
|
645
655
|
var ONEPASSWORD_ID = /^[a-z0-9]{1,64}$/i;
|
|
646
656
|
function assertOnePasswordIds(...ids) {
|
|
647
657
|
for (const id of ids) {
|
|
@@ -685,6 +695,7 @@ function createOnePasswordVaultProvider(options) {
|
|
|
685
695
|
...sdk.AuthExpiredError ? { AuthExpiredError: sdk.AuthExpiredError } : {}
|
|
686
696
|
};
|
|
687
697
|
for (let attempt = 0; ; attempt += 1) {
|
|
698
|
+
let sent = false;
|
|
688
699
|
try {
|
|
689
700
|
const client = await clients.get(
|
|
690
701
|
key.client,
|
|
@@ -694,6 +705,7 @@ function createOnePasswordVaultProvider(options) {
|
|
|
694
705
|
integrationVersion: options.integrationVersion ?? "1"
|
|
695
706
|
})
|
|
696
707
|
);
|
|
708
|
+
sent = op === "write" || operation === "vaultsCreate" || operation === "vaultsDelete" || operation === "grantGroupPermissions";
|
|
697
709
|
return await fn(client);
|
|
698
710
|
} catch (error) {
|
|
699
711
|
const mapped = mapOnePasswordError(error, classes);
|
|
@@ -704,6 +716,12 @@ function createOnePasswordVaultProvider(options) {
|
|
|
704
716
|
clients.drop(key.client);
|
|
705
717
|
}
|
|
706
718
|
if (attempt === 0 && isOnePasswordSessionError(mapped)) continue;
|
|
719
|
+
if (sent && mapped.code === "provider_unavailable") {
|
|
720
|
+
throw new VaultProviderError(
|
|
721
|
+
"provider_outcome_unknown",
|
|
722
|
+
"1Password did not confirm the change; it may have been applied"
|
|
723
|
+
);
|
|
724
|
+
}
|
|
707
725
|
throw mapped;
|
|
708
726
|
}
|
|
709
727
|
}
|
|
@@ -716,20 +734,29 @@ function createOnePasswordVaultProvider(options) {
|
|
|
716
734
|
}
|
|
717
735
|
return cache;
|
|
718
736
|
}
|
|
719
|
-
function getItem(ctx, vaultId, itemId) {
|
|
737
|
+
async function getItem(ctx, vaultId, itemId) {
|
|
738
|
+
const { client: clientKey } = await keys(ctx);
|
|
720
739
|
const cache = itemCache(ctx);
|
|
721
|
-
const cacheKey = `${vaultId}/${itemId}`;
|
|
740
|
+
const cacheKey = `${clientKey}|${vaultId}/${itemId}`;
|
|
741
|
+
const epoch = ctx.cacheEpoch ?? null;
|
|
722
742
|
const cached = cache.get(cacheKey);
|
|
723
|
-
if (cached && now() - cached.at < valueCacheMs)
|
|
743
|
+
if (cached && !ctx.forceRefresh && cached.epoch === epoch && now() - cached.at < valueCacheMs) {
|
|
744
|
+
return await cached.item;
|
|
745
|
+
}
|
|
724
746
|
const item = call(ctx, "read", "itemsGet", (client) => client.items.get(vaultId, itemId));
|
|
725
|
-
cache.set(cacheKey, { at: now(), item });
|
|
747
|
+
cache.set(cacheKey, { at: now(), epoch, item });
|
|
726
748
|
item.catch(() => {
|
|
727
749
|
if (cache.get(cacheKey)?.item === item) cache.delete(cacheKey);
|
|
728
750
|
});
|
|
729
|
-
return item;
|
|
751
|
+
return await item;
|
|
730
752
|
}
|
|
731
753
|
function forgetItem(ctx, vaultId, itemId) {
|
|
732
|
-
attemptItemCaches.get(ctx.budget)
|
|
754
|
+
const cache = attemptItemCaches.get(ctx.budget);
|
|
755
|
+
if (!cache) return;
|
|
756
|
+
const suffix = `|${vaultId}/${itemId}`;
|
|
757
|
+
for (const cacheKey of [...cache.keys()]) {
|
|
758
|
+
if (cacheKey.endsWith(suffix)) cache.delete(cacheKey);
|
|
759
|
+
}
|
|
733
760
|
}
|
|
734
761
|
async function materialFor(ctx, item, externalFieldId) {
|
|
735
762
|
const field = mapItemFields(item).find(
|
|
@@ -893,23 +920,31 @@ function createOnePasswordVaultProvider(options) {
|
|
|
893
920
|
allowAdminsAccess: input.allowAdminsAccess
|
|
894
921
|
})
|
|
895
922
|
);
|
|
896
|
-
|
|
897
|
-
const groupId = input.groupId;
|
|
898
|
-
await call(
|
|
899
|
-
ctx,
|
|
900
|
-
"admin",
|
|
901
|
-
"grantGroupPermissions",
|
|
902
|
-
(client) => client.vaults.grantGroupPermissions(vault.id, [
|
|
903
|
-
{ groupId, permissions: ONEPASSWORD_MANAGED_GROUP_PERMISSIONS }
|
|
904
|
-
])
|
|
905
|
-
);
|
|
906
|
-
}
|
|
907
|
-
return {
|
|
923
|
+
const created = {
|
|
908
924
|
externalVaultId: vault.id,
|
|
909
925
|
name: vault.title,
|
|
910
926
|
contentVersion: vault.contentVersion === void 0 ? null : String(vault.contentVersion),
|
|
911
927
|
itemCount: typeof vault.activeItemCount === "number" ? vault.activeItemCount : 0
|
|
912
928
|
};
|
|
929
|
+
if (input.groupId) {
|
|
930
|
+
const groupId = input.groupId;
|
|
931
|
+
try {
|
|
932
|
+
await call(
|
|
933
|
+
ctx,
|
|
934
|
+
"admin",
|
|
935
|
+
"grantGroupPermissions",
|
|
936
|
+
(client) => client.vaults.grantGroupPermissions(vault.id, [
|
|
937
|
+
{ groupId, permissions: ONEPASSWORD_MANAGED_GROUP_PERMISSIONS }
|
|
938
|
+
])
|
|
939
|
+
);
|
|
940
|
+
} catch (error) {
|
|
941
|
+
throw new OnePasswordVaultCreatedError(
|
|
942
|
+
created,
|
|
943
|
+
error instanceof VaultProviderError ? error : mapOnePasswordError(error)
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return created;
|
|
913
948
|
},
|
|
914
949
|
async deleteVault(ctx, externalVaultId) {
|
|
915
950
|
assertOnePasswordIds(externalVaultId);
|
|
@@ -1089,6 +1124,7 @@ export {
|
|
|
1089
1124
|
ONEPASSWORD_VALUE_CACHE_MS,
|
|
1090
1125
|
OnePasswordClientCache,
|
|
1091
1126
|
OnePasswordQuota,
|
|
1127
|
+
OnePasswordVaultCreatedError,
|
|
1092
1128
|
PROVIDER_READS_PER_ATTEMPT,
|
|
1093
1129
|
categoryForItemType,
|
|
1094
1130
|
classifyOnePasswordMessage,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contract.ts","../src/budget.ts","../src/errors.ts","../src/mapping.ts","../src/sdk.ts","../src/token.ts","../src/provider.ts","../src/connection.ts"],"sourcesContent":["/**\n * The shared vault contracts this adapter implements (F1: `@opengeni/vaults`\n * §10B.1.4 and `@opengeni/contracts`), re-exported for the package's modules.\n */\nexport {\n VaultProviderError,\n type ProviderCallBudget,\n type ProviderFieldMeta,\n type ProviderFieldValue,\n type ProviderItemMeta,\n type ProviderVault,\n type ProviderWriteItem,\n type VaultProvider,\n type VaultProviderCapabilities,\n type VaultProviderContext,\n type VaultProviderErrorCode,\n} from \"@opengeni/vaults\";\nexport {\n parseTotpInput,\n totpCode,\n type SecretMaterial,\n type TotpParams,\n type VaultFieldKind,\n type VaultItemType,\n} from \"@opengeni/contracts\";\n","import { type ProviderCallBudget, VaultProviderError } from \"./contract\";\n\nexport type OnePasswordPlanTier = \"family\" | \"teams\" | \"business\";\nexport type ProviderCallOp = Parameters<ProviderCallBudget[\"take\"]>[0];\n\n/**\n * HTTP requests each SDK operation makes against 1Password, measured live with\n * @1password/sdk 0.5.0 (evidence/w5/README.md). The daily account quota counts\n * requests, not SDK calls, so the connection quota is charged these weights.\n */\nexport const ONEPASSWORD_REQUEST_COST = {\n signIn: 4,\n vaultsList: 1,\n itemsList: 1,\n itemsGetAll: 1,\n itemsGet: 1,\n filesRead: 1,\n itemsCreate: 2,\n itemsPut: 4,\n itemsArchive: 3,\n itemsDelete: 3,\n vaultsCreate: 9,\n grantGroupPermissions: 2,\n vaultsDelete: 2,\n} as const;\nexport type OnePasswordOperation = keyof typeof ONEPASSWORD_REQUEST_COST;\n\n/**\n * Service-account limits by plan (developer.1password.com/docs/service-accounts/rate-limits):\n * the daily request cap is shared by every service account in the 1Password\n * account; the hourly read/write caps apply per token.\n */\nexport const ONEPASSWORD_PLAN_LIMITS: Record<\n OnePasswordPlanTier,\n { dailyRequests: number; hourlyReads: number; hourlyWrites: number }\n> = {\n family: { dailyRequests: 1_000, hourlyReads: 1_000, hourlyWrites: 100 },\n teams: { dailyRequests: 5_000, hourlyReads: 1_000, hourlyWrites: 100 },\n business: { dailyRequests: 50_000, hourlyReads: 10_000, hourlyWrites: 1_000 },\n};\n\n/** Fraction of the daily account quota Opengeni may burst through at once. */\nconst DAILY_BURST_FRACTION = 0.25;\nconst HOUR_MS = 3_600_000;\nconst DAY_MS = 24 * HOUR_MS;\n\ntype Clock = () => number;\n\nclass TokenBucket {\n private tokens: number;\n private updatedAt: number;\n constructor(\n readonly capacity: number,\n private readonly refillPerMs: number,\n private readonly now: Clock,\n ) {\n this.tokens = capacity;\n this.updatedAt = now();\n }\n private refill() {\n const at = this.now();\n this.tokens = Math.min(this.capacity, this.tokens + (at - this.updatedAt) * this.refillPerMs);\n this.updatedAt = at;\n }\n /** Milliseconds until `cost` tokens are available (0 when available now). */\n waitMs(cost: number): number {\n this.refill();\n if (this.tokens >= cost) return 0;\n return Math.ceil((cost - this.tokens) / this.refillPerMs);\n }\n take(cost: number) {\n this.refill();\n this.tokens -= cost;\n }\n get available() {\n this.refill();\n return this.tokens;\n }\n}\n\n/**\n * Per-connection quota guard. One instance per (connection, plan) lives for the\n * process; it fails fast instead of spending the customer's shared daily quota,\n * and stays closed until `blockedUntil` after a real 429 from 1Password.\n */\nexport class OnePasswordQuota {\n private readonly daily: TokenBucket;\n private readonly reads: TokenBucket;\n private readonly writes: TokenBucket;\n private blockedUntilMs = 0;\n constructor(\n readonly planTier: OnePasswordPlanTier,\n private readonly now: Clock = Date.now,\n ) {\n const limits = ONEPASSWORD_PLAN_LIMITS[planTier];\n this.daily = new TokenBucket(\n Math.max(1, Math.floor(limits.dailyRequests * DAILY_BURST_FRACTION)),\n limits.dailyRequests / DAY_MS,\n now,\n );\n this.reads = new TokenBucket(limits.hourlyReads, limits.hourlyReads / HOUR_MS, now);\n this.writes = new TokenBucket(limits.hourlyWrites, limits.hourlyWrites / HOUR_MS, now);\n }\n\n get blockedUntil(): Date | null {\n return this.blockedUntilMs > this.now() ? new Date(this.blockedUntilMs) : null;\n }\n\n /** Record a real 429 so every later call in this process fails fast. */\n block(retryAfterMs: number) {\n this.blockedUntilMs = Math.max(this.blockedUntilMs, this.now() + retryAfterMs);\n }\n\n take(op: ProviderCallOp, cost = 1) {\n const now = this.now();\n if (this.blockedUntilMs > now) {\n throw new VaultProviderError(\n \"provider_rate_limited\",\n \"1Password is rate limiting this connection; try again later\",\n this.blockedUntilMs - now,\n );\n }\n const lane = op === \"write\" ? this.writes : this.reads;\n const waitMs = Math.max(this.daily.waitMs(cost), lane.waitMs(cost));\n if (waitMs > 0) {\n throw new VaultProviderError(\n \"provider_rate_limited\",\n `Opengeni paused 1Password calls to stay inside the ${this.planTier} plan quota`,\n waitMs,\n );\n }\n this.daily.take(cost);\n lane.take(cost);\n }\n\n /** Remaining daily burst, for diagnostics and tests. */\n get remainingDaily(): number {\n return Math.floor(this.daily.available);\n }\n}\n\nconst quotas = new Map<string, OnePasswordQuota>();\n\n/** Process-wide quota for one connection (or token fingerprint). */\nexport function onePasswordQuotaFor(\n key: string,\n planTier: OnePasswordPlanTier,\n now?: Clock,\n): OnePasswordQuota {\n const existing = quotas.get(key);\n if (existing && existing.planTier === planTier) return existing;\n const quota = new OnePasswordQuota(planTier, now);\n const blockedUntil = existing?.blockedUntil;\n if (blockedUntil) quota.block(blockedUntil.getTime() - Date.now());\n quotas.set(key, quota);\n return quota;\n}\n\nexport function resetOnePasswordQuotasForTests() {\n quotas.clear();\n}\n\n/** design §10.9 / VAULT_LIMITS.providerReadsPerAttempt */\nexport const PROVIDER_READS_PER_ATTEMPT = 50;\n\n/**\n * Attempt-scoped budget: at most `reads` provider reads (list + read) per agent\n * attempt. Writes and admin calls are explicit user/agent actions and are only\n * bounded by the connection quota.\n */\nexport function createAttemptProviderBudget(\n options: { reads?: number } = {},\n): ProviderCallBudget & { readonly used: number } {\n const limit = options.reads ?? PROVIDER_READS_PER_ATTEMPT;\n let used = 0;\n return {\n get used() {\n return used;\n },\n take(op) {\n if (op === \"write\" || op === \"admin\") return;\n if (used >= limit) {\n throw new VaultProviderError(\n \"provider_rate_limited\",\n `This task already made ${limit} password-manager reads; reuse values already fetched or continue in a new turn`,\n );\n }\n used += 1;\n },\n };\n}\n\n/** Budget that never refuses (human-initiated install/link/sync routes). */\nexport const unlimitedProviderBudget: ProviderCallBudget = { take() {} };\n","import { VaultProviderError, type VaultProviderErrorCode } from \"./contract\";\n\n/**\n * The 1Password SDK types only three errors (RateLimitExceededError,\n * AuthExpiredError, DesktopSessionExpiredError); everything else arrives as a\n * plain `Error(message)` whose text comes from the WASM core. This module is the\n * single place that turns those messages into provider error codes. The\n * substrings below were read from @1password/sdk-core 0.5.0 (core_bg.wasm) and\n * are pinned by the unit table in test/errors.test.ts.\n */\ntype MessageRule = { code: VaultProviderErrorCode; needles: readonly string[] };\n\nexport const ONEPASSWORD_MESSAGE_RULES: readonly MessageRule[] = [\n {\n code: \"provider_rate_limited\",\n needles: [\"rate limit exceeded\", \"too many requests\"],\n },\n {\n code: \"provider_auth_invalid\",\n needles: [\n \"service account token had invalid format\",\n \"service account token base64 decoding failed\",\n \"service account deserialization failed\",\n \"invalid service account token\",\n \"service account token is invalid\",\n \"bad service account token\",\n \"prefix 'ops_' was expected\",\n \"throttle token is invalid\",\n \"account couldn't be found\",\n \"invalid sign-in address\",\n \"failed to authenticate\",\n ],\n },\n {\n code: \"provider_auth_expired\",\n needles: [\"you are not authenticated\", \"session expired\"],\n },\n {\n code: \"provider_conflict\",\n needles: [\n \"incorrect item version\",\n \"itemstatusincorrectitemversion\",\n \"a conflict occurred on the server\",\n \"data conflict occurred on the server\",\n ],\n },\n {\n code: \"provider_permission_denied\",\n needles: [\n \"you don't have the right permissions\",\n // Live (2026-10-12): item update in a read-only vault.\n \"you do not have the right permissions\",\n \"not sufficient permissions\",\n \"itemstatuspermissionerror\",\n \"permission denied\",\n ],\n },\n {\n code: \"provider_not_found\",\n needles: [\n \"resource not found\",\n \"itemnotfound\",\n \"vaultnotfound\",\n \"document not found in item\",\n \"file uuid not found\",\n \"file not found\",\n \"group not found\",\n ],\n },\n];\n\nexport type OnePasswordErrorClasses = {\n RateLimitExceededError?: abstract new (...args: never[]) => Error;\n AuthExpiredError?: abstract new (...args: never[]) => Error;\n};\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message ?? \"\";\n if (typeof error === \"string\") return error;\n return \"\";\n}\n\nfunction isNamed(error: unknown, name: string, cls?: abstract new (...args: never[]) => Error) {\n if (cls && error instanceof cls) return true;\n return error instanceof Error && error.constructor?.name === name;\n}\n\nconst MINUTE = 60_000;\n\n/**\n * 1Password reports two rate-limit scopes: the hourly per-token limit (\"this\n * service account\") and the daily per-account limit (\"this 1Password\n * account\"). When the message carries an explicit \"retry in N <unit>\", that\n * wins; otherwise fall back to a scope-shaped default.\n */\nexport function onePasswordRetryAfterMs(message: string): number {\n const lower = message.toLowerCase();\n const match = /retry (?:in|after) (\\d+(?:\\.\\d+)?)\\s*(second|sec|s|minute|min|m|hour|hr|h)/.exec(\n lower,\n );\n if (match) {\n const amount = Number(match[1]);\n const unit = match[2] ?? \"m\";\n const factor = unit.startsWith(\"h\") ? 60 * MINUTE : unit.startsWith(\"m\") ? MINUTE : 1_000;\n return Math.max(1_000, Math.round(amount * factor));\n }\n if (lower.includes(\"1password account\") || lower.includes(\"daily\")) return 6 * 60 * MINUTE;\n if (lower.includes(\"service account\") || lower.includes(\"hourly\")) return 60 * MINUTE;\n return 15 * MINUTE;\n}\n\n/** Map a thrown SDK error to a provider error. Never includes token material. */\nexport function mapOnePasswordError(\n error: unknown,\n classes: OnePasswordErrorClasses = {},\n): VaultProviderError {\n if (error instanceof VaultProviderError) return error;\n const message = errorMessage(error);\n if (isNamed(error, \"RateLimitExceededError\", classes.RateLimitExceededError)) {\n return new VaultProviderError(\n \"provider_rate_limited\",\n `1Password rate limit reached: ${message}`,\n onePasswordRetryAfterMs(message),\n );\n }\n if (isNamed(error, \"AuthExpiredError\", classes.AuthExpiredError)) {\n return new VaultProviderError(\n \"provider_auth_expired\",\n `1Password service account token expired: ${message}`,\n );\n }\n const code = classifyOnePasswordMessage(message);\n if (code === \"provider_rate_limited\") {\n return new VaultProviderError(\n code,\n `1Password rate limit reached: ${message}`,\n onePasswordRetryAfterMs(message),\n );\n }\n return new VaultProviderError(code, `1Password: ${message || \"unknown error\"}`);\n}\n\nexport function classifyOnePasswordMessage(message: string): VaultProviderErrorCode {\n const lower = message.toLowerCase();\n for (const rule of ONEPASSWORD_MESSAGE_RULES) {\n if (rule.needles.some((needle) => lower.includes(needle))) return rule.code;\n }\n return \"provider_unavailable\";\n}\n\n/** True for errors after which a fresh SDK client (new sign-in) may succeed. */\nexport function isOnePasswordSessionError(error: VaultProviderError): boolean {\n return error.code === \"provider_auth_expired\" && !/token expired/i.test(error.message);\n}\n","import {\n type ProviderFieldMeta,\n type ProviderItemMeta,\n type ProviderWriteItem,\n type VaultFieldKind,\n type VaultItemType,\n VaultProviderError,\n} from \"./contract\";\nimport type { SdkItem, SdkItemCreateParams, SdkItemField, SdkWebsite } from \"./sdk\";\n\n/** External field ids that do not name an SDK `fields[]` entry. */\nexport const NOTES_FIELD_ID = \"@notes\";\nexport const DOCUMENT_FIELD_ID = \"@document\";\nexport const FILE_FIELD_PREFIX = \"@file:\";\n/** Section used for custom fields that Opengeni adds to 1Password items. */\nexport const OPENGENI_SECTION_ID = \"opengeni\";\n\nconst API_KEY_CATEGORIES = new Set([\n \"ApiCredentials\",\n \"Password\",\n \"Server\",\n \"Database\",\n \"SshKey\",\n \"SoftwareLicense\",\n \"Router\",\n \"Email\",\n \"CryptoWallet\",\n]);\n\nexport function itemTypeForCategory(category: string): VaultItemType {\n if (category === \"Login\") return \"login\";\n if (category === \"SecureNote\") return \"note\";\n if (category === \"Document\") return \"file\";\n if (API_KEY_CATEGORIES.has(category)) return \"api_key\";\n // CreditCard, Identity, BankAccount, ...: generic fields, shown as notes.\n return \"note\";\n}\n\nexport function categoryForItemType(type: VaultItemType): string {\n switch (type) {\n case \"login\":\n return \"Login\";\n case \"api_key\":\n return \"ApiCredentials\";\n case \"note\":\n return \"SecureNote\";\n case \"file\":\n case \"passkey\":\n throw new VaultProviderError(\n \"provider_unavailable\",\n type === \"passkey\"\n ? \"1Password service accounts cannot store passkeys; keep passkeys in an Opengeni vault\"\n : \"Creating file items in 1Password from Opengeni is not supported yet\",\n );\n }\n}\n\nexport function fieldKindForSdkType(fieldType: string): VaultFieldKind | null {\n switch (fieldType) {\n case \"Concealed\":\n case \"CreditCardNumber\":\n case \"SshKey\":\n return \"concealed\";\n case \"Totp\":\n return \"totp\";\n case \"Unsupported\":\n // Passkeys and other fields the SDK cannot edit; `put` preserves them.\n return null;\n default:\n return \"text\";\n }\n}\n\nfunction sdkTypeForKind(kind: VaultFieldKind): string {\n if (kind === \"text\") return \"Text\";\n if (kind === \"totp\") return \"Totp\";\n if (kind === \"concealed\") return \"Concealed\";\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"Writing file fields to 1Password from Opengeni is not supported yet\",\n );\n}\n\n// Mirrors contracts isValidSecretName (Q-10): no / { } # \\ or control chars,\n// trimmed, 1..120 chars, not \"id:…\"; field names additionally may not be \"otp\".\n// eslint-disable-next-line no-control-regex\nconst FORBIDDEN_NAME_CHARS = /[/{}#\\\\\\u0000-\\u001f\\u007f]/g;\n\nexport function nameKey(name: string): string {\n return name.normalize(\"NFC\").trim().toLowerCase();\n}\n\nexport function safeSecretName(raw: string, fallback: string): string {\n let name = raw.replace(FORBIDDEN_NAME_CHARS, \"-\").trim().slice(0, 120).trim();\n if (!name) name = fallback.replace(FORBIDDEN_NAME_CHARS, \"-\").trim().slice(0, 120) || \"item\";\n if (/^id:/i.test(name)) name = `id-${name.slice(3)}`;\n return name;\n}\n\nfunction safeFieldName(raw: string, fallback: string): string {\n const name = safeSecretName(raw, fallback);\n return nameKey(name) === \"otp\" ? \"otp-code\" : name;\n}\n\n/** Appends \" (2)\", \" (3)\" … so names are unique case-insensitively. */\nexport function uniqueName(name: string, taken: Set<string>): string {\n let candidate = name;\n for (let n = 2; taken.has(nameKey(candidate)); n += 1) {\n const suffix = ` (${n})`;\n candidate = `${name.slice(0, 120 - suffix.length)}${suffix}`;\n }\n taken.add(nameKey(candidate));\n return candidate;\n}\n\nexport type MappedField =\n | (ProviderFieldMeta & { source: \"field\"; field: SdkItemField })\n | (ProviderFieldMeta & { source: \"notes\" })\n | (ProviderFieldMeta & {\n source: \"file\";\n file: { name: string; id: string; size: number };\n });\n\nfunction fieldExternalId(field: SdkItemField, duplicateIds: Set<string>): string {\n return duplicateIds.has(field.id) && field.sectionId\n ? `${field.sectionId}.${field.id}`\n : field.id;\n}\n\n/** Deterministic projection of an item's fields; values are never copied out. */\nexport function mapItemFields(item: SdkItem): MappedField[] {\n const seen = new Set<string>();\n const duplicateIds = new Set<string>();\n for (const field of item.fields) {\n if (seen.has(field.id)) duplicateIds.add(field.id);\n seen.add(field.id);\n }\n const taken = new Set<string>();\n const mapped: MappedField[] = [];\n for (const field of item.fields) {\n const kind = fieldKindForSdkType(field.fieldType);\n if (!kind) continue;\n mapped.push({\n source: \"field\",\n field,\n externalFieldId: fieldExternalId(field, duplicateIds),\n name: uniqueName(safeFieldName(field.title, field.id), taken),\n kind,\n });\n }\n if (item.category === \"SecureNote\" || item.notes) {\n mapped.push({\n source: \"notes\",\n externalFieldId: NOTES_FIELD_ID,\n name: uniqueName(item.category === \"SecureNote\" ? \"note\" : \"notes\", taken),\n kind: \"concealed\",\n });\n }\n if (item.document) {\n mapped.push({\n source: \"file\",\n file: item.document,\n externalFieldId: DOCUMENT_FIELD_ID,\n name: uniqueName(\"file\", taken),\n kind: \"file\",\n });\n }\n for (const file of item.files ?? []) {\n mapped.push({\n source: \"file\",\n file: file.attributes,\n externalFieldId: `${FILE_FIELD_PREFIX}${file.attributes.id}`,\n name: uniqueName(safeFieldName(file.attributes.name, file.attributes.id), taken),\n kind: \"file\",\n });\n }\n return mapped;\n}\n\nfunction isoDate(value: Date | string | undefined | null): string | null {\n if (!value) return null;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? null : date.toISOString();\n}\n\nexport function toProviderItemMeta(item: SdkItem): ProviderItemMeta {\n return {\n externalItemId: item.id,\n name: safeSecretName(item.title, item.id),\n type: itemTypeForCategory(item.category),\n websites: (item.websites ?? []).map((website) => website.url).filter(Boolean),\n fields: mapItemFields(item).map(({ externalFieldId, name, kind }) => ({\n externalFieldId,\n name,\n kind,\n })),\n version: String(item.version),\n updatedAt: isoDate(item.updatedAt),\n };\n}\n\nfunction toWebsites(urls: readonly string[], previous: readonly SdkWebsite[] = []): SdkWebsite[] {\n return urls.map(\n (url) =>\n previous.find((website) => website.url === url) ?? {\n url,\n label: \"website\",\n autofillBehavior: \"AnywhereOnWebsite\",\n },\n );\n}\n\ntype WriteField = ProviderWriteItem[\"fields\"][number];\n\n/** Built-in 1Password field that a named Opengeni field maps onto, if any. */\nfunction builtInFieldFor(\n category: string,\n field: WriteField,\n): { id: string; fieldType: string } | null {\n const key = nameKey(field.name);\n if (category === \"Login\" && key === \"username\") return { id: \"username\", fieldType: \"Text\" };\n if (category === \"Login\" && key === \"password\") return { id: \"password\", fieldType: \"Concealed\" };\n if (category === \"ApiCredentials\" && (key === \"value\" || key === \"credential\"))\n return { id: \"credential\", fieldType: \"Concealed\" };\n if (category === \"ApiCredentials\" && key === \"username\")\n return { id: \"username\", fieldType: \"Text\" };\n return null;\n}\n\nfunction isNotesField(category: string, field: WriteField): boolean {\n if (field.externalFieldId === NOTES_FIELD_ID) return true;\n const key = nameKey(field.name);\n return category === \"SecureNote\" ? key === \"note\" || key === \"notes\" : key === \"notes\";\n}\n\nfunction customFieldId(name: string, item: { fields: SdkItemField[] }): string {\n const slug =\n nameKey(name)\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\") || \"field\";\n const ids = new Set(item.fields.map((field) => field.id));\n let id = `opengeni_${slug}`.slice(0, 64);\n for (let n = 2; ids.has(id); n += 1) id = `opengeni_${slug}`.slice(0, 60) + `_${n}`;\n return id;\n}\n\nfunction requireValue(field: WriteField): string {\n if (field.value === undefined) {\n throw new VaultProviderError(\n \"provider_conflict\",\n `Field \"${field.name}\" has no value to write`,\n );\n }\n return field.value;\n}\n\nfunction addField(\n target: SdkItem | (SdkItemCreateParams & { fields: SdkItemField[] }),\n category: string,\n field: WriteField,\n) {\n const value = requireValue(field);\n const builtIn = builtInFieldFor(category, field);\n if (builtIn && !target.fields.some((existing) => existing.id === builtIn.id)) {\n target.fields.push({ id: builtIn.id, title: field.name, fieldType: builtIn.fieldType, value });\n return;\n }\n const sections = (target.sections ??= []);\n if (!sections.some((section) => section.id === OPENGENI_SECTION_ID)) {\n sections.push({ id: OPENGENI_SECTION_ID, title: \"\" });\n }\n target.fields.push({\n id: customFieldId(field.name, target),\n title: field.name,\n sectionId: OPENGENI_SECTION_ID,\n fieldType: sdkTypeForKind(field.kind),\n value,\n });\n}\n\nexport function buildCreateParams(\n externalVaultId: string,\n write: ProviderWriteItem,\n): SdkItemCreateParams {\n const category = categoryForItemType(write.type);\n const params: SdkItemCreateParams & {\n fields: SdkItemField[];\n sections: Array<{ id: string; title: string }>;\n } = {\n category,\n vaultId: externalVaultId,\n title: write.name,\n fields: [],\n sections: [],\n websites: toWebsites(write.websites),\n };\n for (const field of write.fields) {\n if (field.remove) continue;\n if (isNotesField(category, field)) {\n params.notes = requireValue(field);\n continue;\n }\n addField(params, category, field);\n }\n return params;\n}\n\n/** Applies a field patch to a freshly read item (get → patch → put). */\nexport function applyWrite(item: SdkItem, write: ProviderWriteItem): SdkItem {\n const next: SdkItem = {\n ...item,\n title: write.name,\n fields: item.fields.map((field) => ({ ...field })),\n sections: [...(item.sections ?? [])],\n websites: toWebsites(write.websites, item.websites),\n };\n for (const field of write.fields) {\n const mapped = mapItemFields(next);\n const target =\n (field.externalFieldId\n ? mapped.find((candidate) => candidate.externalFieldId === field.externalFieldId)\n : undefined) ?? mapped.find((candidate) => nameKey(candidate.name) === nameKey(field.name));\n if (target?.source === \"file\" || (!target && field.kind === \"file\")) {\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"Writing file fields to 1Password from Opengeni is not supported yet\",\n );\n }\n if (field.remove) {\n if (!target) continue;\n if (target.source === \"notes\") next.notes = \"\";\n else next.fields = next.fields.filter((candidate) => candidate !== target.field);\n continue;\n }\n if (target?.source === \"notes\" || (!target && isNotesField(next.category, field))) {\n next.notes = requireValue(field);\n continue;\n }\n if (target?.source === \"field\") {\n target.field.value = requireValue(field);\n if (field.kind !== target.kind && field.kind !== \"file\") {\n target.field.fieldType = sdkTypeForKind(field.kind);\n }\n continue;\n }\n addField(next, next.category, field);\n }\n return next;\n}\n","/**\n * The narrow slice of `@1password/sdk` this adapter uses, typed structurally so\n * tests can inject an in-memory double and so the SDK (a ~14 MB WASM core) is\n * only ever loaded through `loadOnePasswordSdk()`'s dynamic import.\n */\nimport { VaultProviderError } from \"@opengeni/vaults\";\n\nexport type SdkFieldType =\n | \"Text\"\n | \"Concealed\"\n | \"CreditCardType\"\n | \"CreditCardNumber\"\n | \"Phone\"\n | \"Url\"\n | \"Totp\"\n | \"Email\"\n | \"Reference\"\n | \"SshKey\"\n | \"Menu\"\n | \"MonthYear\"\n | \"Address\"\n | \"Date\"\n | \"Unsupported\";\n\nexport interface SdkItemField {\n id: string;\n title: string;\n sectionId?: string;\n fieldType: SdkFieldType | (string & {});\n value: string;\n details?: { type: string; content?: { code?: string; errorMessage?: string } | unknown };\n}\nexport interface SdkWebsite {\n url: string;\n label: string;\n autofillBehavior: string;\n}\nexport interface SdkFileAttributes {\n name: string;\n id: string;\n size: number;\n}\nexport interface SdkItem {\n id: string;\n title: string;\n category: string;\n vaultId: string;\n fields: SdkItemField[];\n sections: Array<{ id: string; title: string }>;\n notes: string;\n tags: string[];\n websites: SdkWebsite[];\n version: number;\n files: Array<{ attributes: SdkFileAttributes; sectionId: string; fieldId: string }>;\n document?: SdkFileAttributes;\n createdAt: Date;\n updatedAt: Date;\n}\nexport interface SdkItemOverview {\n id: string;\n title: string;\n category: string;\n vaultId: string;\n websites: SdkWebsite[];\n updatedAt: Date;\n state: string;\n}\nexport interface SdkItemCreateParams {\n category: string;\n vaultId: string;\n title: string;\n fields?: SdkItemField[];\n sections?: Array<{ id: string; title: string }>;\n notes?: string;\n tags?: string[];\n websites?: SdkWebsite[];\n}\nexport interface SdkVaultOverview {\n id: string;\n title: string;\n description: string;\n vaultType: string;\n activeItemCount: number;\n contentVersion: number;\n}\nexport type SdkItemListFilter = {\n type: \"ByState\";\n content: { active: boolean; archived: boolean };\n};\nexport interface SdkGetAllResponse {\n individualResponses: Array<{ content?: SdkItem; error?: { type: string; message?: string } }>;\n}\n\nexport interface OnePasswordSdkClient {\n vaults: {\n list(params?: { decryptDetails?: boolean }): Promise<SdkVaultOverview[]>;\n create(params: {\n title: string;\n description?: string;\n allowAdminsAccess?: boolean;\n }): Promise<SdkVaultOverview>;\n delete(vaultId: string): Promise<void>;\n grantGroupPermissions(\n vaultId: string,\n groups: Array<{ groupId: string; permissions: number }>,\n ): Promise<void>;\n };\n items: {\n list(vaultId: string, ...filters: SdkItemListFilter[]): Promise<SdkItemOverview[]>;\n get(vaultId: string, itemId: string): Promise<SdkItem>;\n getAll(vaultId: string, itemIds: string[]): Promise<SdkGetAllResponse>;\n create(params: SdkItemCreateParams): Promise<SdkItem>;\n put(item: SdkItem): Promise<SdkItem>;\n archive(vaultId: string, itemId: string): Promise<void>;\n delete(vaultId: string, itemId: string): Promise<void>;\n files: {\n read(vaultId: string, itemId: string, attributes: SdkFileAttributes): Promise<Uint8Array>;\n };\n };\n}\n\nexport interface OnePasswordSdk {\n createClient(config: {\n auth: string;\n integrationName: string;\n integrationVersion: string;\n }): Promise<OnePasswordSdkClient>;\n RateLimitExceededError?: abstract new (...args: never[]) => Error;\n AuthExpiredError?: abstract new (...args: never[]) => Error;\n}\n\nexport const ONEPASSWORD_SDK_VERSION = \"0.5.0\";\nexport const ONEPASSWORD_INTEGRATION_NAME = \"OpenGeni\";\n\nlet sdkPromise: Promise<OnePasswordSdk> | null = null;\n\n/**\n * Lazily loads the pinned SDK (WASM) once per process. A server that cannot\n * load it (for example a broken image without the WASM core) reports\n * `provider_unavailable` with a plain reason, so connecting and syncing say\n * what is wrong instead of failing with a generic error, and the next call\n * tries again.\n */\nexport function loadOnePasswordSdk(\n importSdk: () => Promise<{\n createClient: unknown;\n RateLimitExceededError?: unknown;\n AuthExpiredError?: unknown;\n }> = () => import(\"@1password/sdk\"),\n): Promise<OnePasswordSdk> {\n const loading = (sdkPromise ??= importSdk().then(\n (module): OnePasswordSdk => ({\n createClient: module.createClient as OnePasswordSdk[\"createClient\"],\n ...(module.RateLimitExceededError\n ? {\n RateLimitExceededError:\n module.RateLimitExceededError as OnePasswordSdk[\"RateLimitExceededError\"] & {},\n }\n : {}),\n ...(module.AuthExpiredError\n ? { AuthExpiredError: module.AuthExpiredError as OnePasswordSdk[\"AuthExpiredError\"] & {} }\n : {}),\n }),\n (cause: unknown) => {\n sdkPromise = null;\n console.error(\"[vaults-onepassword] the 1Password SDK failed to load\", cause);\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"1Password support could not be loaded on this server. Ask whoever runs it to check the deployment.\",\n );\n },\n ));\n return loading;\n}\n\n/**\n * One signed-in client per token per process. Creating a client performs the\n * SRP sign-in (several requests), so reuse matters for the account quota.\n * The cache must hold the SDK `Client` object itself: the SDK releases the\n * WASM session when that object is garbage collected, so keeping only\n * `client.items` / `client.vaults` fails later calls with \"invalid client id\".\n */\nexport class OnePasswordClientCache {\n private readonly clients = new Map<string, Promise<OnePasswordSdkClient>>();\n\n get(key: string, create: () => Promise<OnePasswordSdkClient>): Promise<OnePasswordSdkClient> {\n let client = this.clients.get(key);\n if (!client) {\n client = create();\n this.clients.set(key, client);\n client.catch(() => {\n if (this.clients.get(key) === client) this.clients.delete(key);\n });\n }\n return client;\n }\n\n drop(key: string) {\n this.clients.delete(key);\n }\n\n /** True when a signed-in (or signing-in) client exists for `key`. */\n has(key: string): boolean {\n return this.clients.has(key);\n }\n\n clear() {\n this.clients.clear();\n }\n}\n\nexport const sharedOnePasswordClientCache = new OnePasswordClientCache();\n","import { VaultProviderError } from \"./contract\";\n\nexport const ONEPASSWORD_FAKE_TOKENS = [\"ops_fake_healthy\", \"ops_fake_sync_error\"] as const;\nexport type OnePasswordFakeToken = (typeof ONEPASSWORD_FAKE_TOKENS)[number];\n\nexport function isOnePasswordFakeToken(token: string): token is OnePasswordFakeToken {\n return (ONEPASSWORD_FAKE_TOKENS as readonly string[]).includes(token);\n}\n\nexport type OnePasswordTokenDescription = {\n /** Sign-in host, for example \"my.1password.com\". Never secret. */\n accountName: string | null;\n fake: boolean;\n};\n\nconst REQUIRED_KEYS = [\"signInAddress\", \"deviceUuid\", \"email\", \"srpX\", \"muk\", \"secretKey\"] as const;\n\n/**\n * Offline service-account token check: `ops_` + base64 JSON carrying the sign-in\n * address and key material. It costs no 1Password request. The error message never\n * echoes the token.\n */\nexport function describeOnePasswordToken(\n token: string,\n options: { allowFakeTokens?: boolean } = {},\n): OnePasswordTokenDescription {\n const trimmed = token.trim();\n if (options.allowFakeTokens && isOnePasswordFakeToken(trimmed)) {\n return { accountName: \"fake.1password.test\", fake: true };\n }\n const invalid = (detail: string) =>\n new VaultProviderError(\n \"provider_auth_invalid\",\n `This is not a 1Password service account token (${detail}). Create one in 1Password under Developer > Service accounts and paste the full token, which starts with \"ops_\".`,\n );\n if (!trimmed.startsWith(\"ops_\")) throw invalid(\"missing the ops_ prefix\");\n let decoded: unknown;\n try {\n const body = trimmed.slice(4).replace(/-/g, \"+\").replace(/_/g, \"/\");\n decoded = JSON.parse(Buffer.from(body, \"base64\").toString(\"utf8\"));\n } catch {\n throw invalid(\"it could not be decoded\");\n }\n if (!decoded || typeof decoded !== \"object\" || Array.isArray(decoded)) {\n throw invalid(\"it could not be decoded\");\n }\n const record = decoded as Record<string, unknown>;\n for (const key of REQUIRED_KEYS) {\n if (typeof record[key] !== \"string\" && typeof record[key] !== \"object\") {\n throw invalid(\"it is incomplete\");\n }\n }\n return { accountName: signInHost(record.signInAddress), fake: false };\n}\n\nfunction signInHost(value: unknown): string | null {\n if (typeof value !== \"string\" || !value) return null;\n try {\n return new URL(value.includes(\"://\") ? value : `https://${value}`).hostname || null;\n } catch {\n return null;\n }\n}\n\n/** Stable, non-reversible fingerprint used to key SDK clients per token. */\nexport async function onePasswordTokenFingerprint(token: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(token.trim()));\n return Buffer.from(digest).subarray(0, 12).toString(\"hex\");\n}\n","import {\n type ProviderCallBudget,\n type ProviderFieldValue,\n type ProviderItemMeta,\n type ProviderVault,\n type SecretMaterial,\n type VaultProvider,\n type VaultProviderCapabilities,\n type VaultProviderContext,\n VaultProviderError,\n parseTotpInput,\n} from \"./contract\";\nimport {\n ONEPASSWORD_REQUEST_COST,\n type OnePasswordOperation,\n type OnePasswordPlanTier,\n type ProviderCallOp,\n onePasswordQuotaFor,\n} from \"./budget\";\nimport { isOnePasswordSessionError, mapOnePasswordError } from \"./errors\";\nimport { applyWrite, buildCreateParams, mapItemFields, toProviderItemMeta } from \"./mapping\";\nimport {\n ONEPASSWORD_INTEGRATION_NAME,\n type OnePasswordClientCache,\n type OnePasswordSdk,\n type OnePasswordSdkClient,\n type SdkItem,\n loadOnePasswordSdk,\n sharedOnePasswordClientCache,\n} from \"./sdk\";\nimport { describeOnePasswordToken, onePasswordTokenFingerprint } from \"./token\";\n\n/** design §10.9 / VAULT_LIMITS.providerValueCacheMs */\nexport const ONEPASSWORD_VALUE_CACHE_MS = 60_000;\n/** Items per `items.getAll` request when mirroring metadata. */\nexport const ONEPASSWORD_GET_ALL_BATCH = 50;\n\n/**\n * Group permissions granted on a managed vault: the Teams \"edit\" bundle\n * (read, reveal, item history, create, update, archive, delete).\n */\nexport const ONEPASSWORD_MANAGED_GROUP_PERMISSIONS = 32 | 16 | 1024 | 128 | 64 | 256 | 512;\n\n/**\n * 1Password vault and item IDs are short lowercase alphanumerics (26 chars).\n * Anything else cannot exist, so refuse it as not found before spending a\n * request (and before the SDK reports it as a generic validation error).\n */\nconst ONEPASSWORD_ID = /^[a-z0-9]{1,64}$/i;\nfunction assertOnePasswordIds(...ids: Array<string | undefined>) {\n for (const id of ids) {\n if (id !== undefined && !ONEPASSWORD_ID.test(id)) {\n throw new VaultProviderError(\"provider_not_found\", \"No such 1Password vault or item\");\n }\n }\n}\n\nexport type OnePasswordVaultProviderOptions = {\n token: string;\n planTier?: OnePasswordPlanTier;\n /** Injected SDK (tests); defaults to the pinned dynamic import. */\n sdk?: OnePasswordSdk | (() => Promise<OnePasswordSdk>);\n clientCache?: OnePasswordClientCache;\n integrationVersion?: string;\n now?: () => number;\n valueCacheMs?: number;\n};\n\nexport type OnePasswordVaultProvider = VaultProvider & {\n readonly planTier: OnePasswordPlanTier;\n /** Deletes a vault this service account created (managed-vault cleanup, live tests). */\n deleteVault(ctx: VaultProviderContext, externalVaultId: string): Promise<void>;\n /** Permanently deletes an item (live-test cleanup only; product paths archive). */\n deleteItem(\n ctx: VaultProviderContext,\n externalVaultId: string,\n externalItemId: string,\n ): Promise<void>;\n};\n\ntype CachedItem = { at: number; item: Promise<SdkItem> };\n\n/**\n * Values never outlive the attempt that read them: the cache is keyed by the\n * attempt's budget object (one per attempt or request), so it is dropped with it.\n */\nconst attemptItemCaches = new WeakMap<ProviderCallBudget, Map<string, CachedItem>>();\n\nexport function createOnePasswordVaultProvider(\n options: OnePasswordVaultProviderOptions,\n): OnePasswordVaultProvider {\n const token = options.token.trim();\n const planTier = options.planTier ?? \"teams\";\n const now = options.now ?? Date.now;\n const clients = options.clientCache ?? sharedOnePasswordClientCache;\n const valueCacheMs = options.valueCacheMs ?? ONEPASSWORD_VALUE_CACHE_MS;\n const description = describeOnePasswordToken(token);\n let fingerprint: Promise<string> | null = null;\n let sdkPromise: Promise<OnePasswordSdk> | null = null;\n\n const loadSdk = () => {\n sdkPromise ??=\n typeof options.sdk === \"function\"\n ? options.sdk()\n : options.sdk\n ? Promise.resolve(options.sdk)\n : loadOnePasswordSdk();\n return sdkPromise;\n };\n\n async function keys(ctx: VaultProviderContext) {\n fingerprint ??= onePasswordTokenFingerprint(token);\n const tokenKey = await fingerprint;\n return {\n client: `${ctx.connectionId ?? \"token\"}:${tokenKey}`,\n quota: ctx.connectionId ?? `token:${tokenKey}`,\n };\n }\n\n async function call<T>(\n ctx: VaultProviderContext,\n op: ProviderCallOp,\n operation: OnePasswordOperation,\n fn: (client: OnePasswordSdkClient) => Promise<T>,\n ): Promise<T> {\n ctx.signal?.throwIfAborted();\n const key = await keys(ctx);\n const quota = onePasswordQuotaFor(key.quota, planTier, now);\n ctx.budget.take(op);\n // A cold client signs in first; charge that before spending anything.\n const cost =\n ONEPASSWORD_REQUEST_COST[operation] +\n (clients.has(key.client) ? 0 : ONEPASSWORD_REQUEST_COST.signIn);\n quota.take(op, cost);\n const sdk = await loadSdk();\n const classes = {\n ...(sdk.RateLimitExceededError ? { RateLimitExceededError: sdk.RateLimitExceededError } : {}),\n ...(sdk.AuthExpiredError ? { AuthExpiredError: sdk.AuthExpiredError } : {}),\n };\n for (let attempt = 0; ; attempt += 1) {\n try {\n const client = await clients.get(key.client, () =>\n sdk.createClient({\n auth: token,\n integrationName: ONEPASSWORD_INTEGRATION_NAME,\n integrationVersion: options.integrationVersion ?? \"1\",\n }),\n );\n return await fn(client);\n } catch (error) {\n const mapped = mapOnePasswordError(error, classes);\n if (mapped.code === \"provider_rate_limited\" && mapped.retryAfterMs) {\n quota.block(mapped.retryAfterMs);\n }\n if (mapped.code === \"provider_auth_expired\" || mapped.code === \"provider_auth_invalid\") {\n clients.drop(key.client);\n }\n if (attempt === 0 && isOnePasswordSessionError(mapped)) continue;\n throw mapped;\n }\n }\n }\n\n function itemCache(ctx: VaultProviderContext): Map<string, CachedItem> {\n let cache = attemptItemCaches.get(ctx.budget);\n if (!cache) {\n cache = new Map();\n attemptItemCaches.set(ctx.budget, cache);\n }\n return cache;\n }\n\n /** Live item read, cached per attempt for 60 s with single-flight. */\n function getItem(ctx: VaultProviderContext, vaultId: string, itemId: string): Promise<SdkItem> {\n const cache = itemCache(ctx);\n const cacheKey = `${vaultId}/${itemId}`;\n const cached = cache.get(cacheKey);\n if (cached && now() - cached.at < valueCacheMs) return cached.item;\n const item = call(ctx, \"read\", \"itemsGet\", (client) => client.items.get(vaultId, itemId));\n cache.set(cacheKey, { at: now(), item });\n item.catch(() => {\n if (cache.get(cacheKey)?.item === item) cache.delete(cacheKey);\n });\n return item;\n }\n\n function forgetItem(ctx: VaultProviderContext, vaultId: string, itemId: string) {\n attemptItemCaches.get(ctx.budget)?.delete(`${vaultId}/${itemId}`);\n }\n\n async function materialFor(\n ctx: VaultProviderContext,\n item: SdkItem,\n externalFieldId: string,\n ): Promise<SecretMaterial> {\n const field = mapItemFields(item).find(\n (candidate) => candidate.externalFieldId === externalFieldId,\n );\n if (!field) {\n throw new VaultProviderError(\n \"provider_not_found\",\n `1Password item \"${item.title}\" has no field ${externalFieldId}`,\n );\n }\n if (field.source === \"notes\") return { type: \"text\", value: item.notes };\n if (field.source === \"file\") {\n const bytes = await call(ctx, \"read\", \"filesRead\", (client) =>\n client.items.files.read(item.vaultId, item.id, field.file),\n );\n return { type: \"bytes\", value: bytes };\n }\n if (field.kind === \"totp\") {\n try {\n return { type: \"totp\", params: parseTotpInput(field.field.value) };\n } catch {\n const details = field.field.details?.content as { code?: string } | undefined;\n if (details?.code) return { type: \"text\", value: details.code };\n throw new VaultProviderError(\n \"provider_unavailable\",\n `The one-time password in 1Password item \"${item.title}\" is not a valid TOTP seed`,\n );\n }\n }\n return { type: \"text\", value: field.field.value };\n }\n\n const provider: OnePasswordVaultProvider = {\n id: \"onepassword\",\n planTier,\n\n capabilities(): VaultProviderCapabilities {\n return {\n write: true,\n createVault: true,\n totp: true,\n // File and Document fields are readable; writing them is not supported.\n files: false,\n groupGrants: planTier !== \"family\",\n passkeys: false,\n };\n },\n\n async validate(ctx) {\n await provider.listVaults(ctx);\n return { accountName: description.accountName };\n },\n\n async listVaults(ctx): Promise<ProviderVault[]> {\n const vaults = await call(ctx, \"list\", \"vaultsList\", (client) => client.vaults.list());\n return vaults.map((vault) => ({\n externalVaultId: vault.id,\n name: vault.title,\n contentVersion: vault.contentVersion === undefined ? null : String(vault.contentVersion),\n itemCount: typeof vault.activeItemCount === \"number\" ? vault.activeItemCount : null,\n }));\n },\n\n async listItems(ctx, externalVaultId): Promise<ProviderItemMeta[]> {\n assertOnePasswordIds(externalVaultId);\n const overviews = await call(ctx, \"list\", \"itemsList\", (client) =>\n client.items.list(externalVaultId, {\n type: \"ByState\",\n content: { active: true, archived: false },\n }),\n );\n const items: ProviderItemMeta[] = [];\n for (let start = 0; start < overviews.length; start += ONEPASSWORD_GET_ALL_BATCH) {\n const ids = overviews.slice(start, start + ONEPASSWORD_GET_ALL_BATCH).map((o) => o.id);\n const batch = await call(ctx, \"read\", \"itemsGetAll\", (client) =>\n client.items.getAll(externalVaultId, ids),\n );\n for (const response of batch.individualResponses) {\n // An item deleted between list and getAll simply drops out of the mirror.\n if (response.content) items.push(toProviderItemMeta(response.content));\n }\n }\n return items;\n },\n\n async readFields(ctx, externalVaultId, externalItemId, externalFieldIds) {\n assertOnePasswordIds(externalVaultId, externalItemId);\n const item = await getItem(ctx, externalVaultId, externalItemId);\n const values: ProviderFieldValue[] = [];\n for (const externalFieldId of externalFieldIds) {\n values.push({ externalFieldId, material: await materialFor(ctx, item, externalFieldId) });\n }\n return values;\n },\n\n async writeItem(ctx, externalVaultId, write) {\n assertOnePasswordIds(externalVaultId, write.externalItemId);\n if (!write.externalItemId) {\n const params = buildCreateParams(externalVaultId, write);\n const created = await call(ctx, \"write\", \"itemsCreate\", (client) =>\n client.items.create(params),\n );\n return toProviderItemMeta(created);\n }\n const itemId = write.externalItemId;\n forgetItem(ctx, externalVaultId, itemId);\n for (let attempt = 0; ; attempt += 1) {\n const current = await call(ctx, \"read\", \"itemsGet\", (client) =>\n client.items.get(externalVaultId, itemId),\n );\n if (\n write.expectedVersion !== undefined &&\n write.expectedVersion !== null &&\n String(current.version) !== write.expectedVersion\n ) {\n throw new VaultProviderError(\n \"provider_conflict\",\n `1Password item \"${current.title}\" changed (version ${current.version}, expected ${write.expectedVersion}); reload and retry`,\n );\n }\n const next = applyWrite(current, write);\n try {\n const saved = await call(ctx, \"write\", \"itemsPut\", (client) => client.items.put(next));\n return toProviderItemMeta(saved);\n } catch (error) {\n // Without an explicit expected version, a concurrent edit is re-read and\n // the same field patch re-applied once; never overwrite a stale view.\n const retry =\n error instanceof VaultProviderError &&\n error.code === \"provider_conflict\" &&\n attempt === 0 &&\n (write.expectedVersion === undefined || write.expectedVersion === null);\n if (!retry) throw error;\n } finally {\n forgetItem(ctx, externalVaultId, itemId);\n }\n }\n },\n\n async archiveItem(ctx, externalVaultId, externalItemId) {\n assertOnePasswordIds(externalVaultId, externalItemId);\n await call(ctx, \"write\", \"itemsArchive\", (client) =>\n client.items.archive(externalVaultId, externalItemId),\n );\n forgetItem(ctx, externalVaultId, externalItemId);\n },\n\n async createVault(ctx, input) {\n if (input.groupId && planTier === \"family\") {\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"1Password Families accounts have no groups; share the vault in 1Password instead\",\n );\n }\n const vault = await call(ctx, \"admin\", \"vaultsCreate\", (client) =>\n client.vaults.create({\n title: input.name,\n ...(input.description ? { description: input.description } : {}),\n allowAdminsAccess: input.allowAdminsAccess,\n }),\n );\n if (input.groupId) {\n const groupId = input.groupId;\n await call(ctx, \"admin\", \"grantGroupPermissions\", (client) =>\n client.vaults.grantGroupPermissions(vault.id, [\n { groupId, permissions: ONEPASSWORD_MANAGED_GROUP_PERMISSIONS },\n ]),\n );\n }\n return {\n externalVaultId: vault.id,\n name: vault.title,\n contentVersion: vault.contentVersion === undefined ? null : String(vault.contentVersion),\n itemCount: typeof vault.activeItemCount === \"number\" ? vault.activeItemCount : 0,\n };\n },\n\n async deleteVault(ctx, externalVaultId) {\n assertOnePasswordIds(externalVaultId);\n await call(ctx, \"admin\", \"vaultsDelete\", (client) => client.vaults.delete(externalVaultId));\n },\n\n async deleteItem(ctx, externalVaultId, externalItemId) {\n assertOnePasswordIds(externalVaultId, externalItemId);\n await call(ctx, \"write\", \"itemsDelete\", (client) =>\n client.items.delete(externalVaultId, externalItemId),\n );\n forgetItem(ctx, externalVaultId, externalItemId);\n },\n };\n return provider;\n}\n","import { createFakeVaultProvider } from \"@opengeni/vaults/testing/fake-provider\";\n\nimport type { OnePasswordPlanTier } from \"./budget\";\nimport { type VaultProvider, VaultProviderError } from \"./contract\";\nimport { createOnePasswordVaultProvider } from \"./provider\";\nimport { type OnePasswordClientCache } from \"./sdk\";\nimport { type OnePasswordFakeToken, describeOnePasswordToken } from \"./token\";\n\nexport type OnePasswordConnectionProviderOptions = {\n token: string;\n planTier?: OnePasswordPlanTier;\n /** `settings.onePasswordFakeTokens` (refused by the managed runtime posture). */\n allowFakeTokens?: boolean;\n clientCache?: OnePasswordClientCache;\n};\n\n/** Stable IDs so API and worker processes agree on the fake vaults. */\nexport const ONEPASSWORD_FAKE_VAULT_IDS = {\n engineering: \"fakeengineeringvault000001\",\n shared: \"fakesharedvault00000000001\",\n} as const;\n\nconst fakeProviders = new Map<OnePasswordFakeToken, VaultProvider>();\n\nfunction fakeLogin(id: string, name: string, website: string, totp = false) {\n return {\n externalItemId: id,\n name,\n type: \"login\" as const,\n websites: [website],\n fields: [\n {\n externalFieldId: \"username\",\n name: \"username\",\n kind: \"text\" as const,\n value: `${id}@example.test`,\n },\n {\n externalFieldId: \"password\",\n name: \"password\",\n kind: \"concealed\" as const,\n value: `fake-${id}-password`,\n },\n ...(totp\n ? [\n {\n externalFieldId: \"otp\",\n name: \"one-time password\",\n kind: \"totp\" as const,\n value: \"otpauth://totp/Fake:engineering?secret=JBSWY3DPEHPK3PXP&period=30&digits=6\",\n },\n ]\n : []),\n ],\n };\n}\n\nfunction fakeProviderFor(token: OnePasswordFakeToken): VaultProvider {\n const existing = fakeProviders.get(token);\n if (existing) return existing;\n let provider: VaultProvider;\n if (token === \"ops_fake_healthy\") {\n provider = createFakeVaultProvider({\n accountName: \"fake.1password.test\",\n capabilities: { files: false, groupGrants: false },\n vaults: [\n {\n externalVaultId: ONEPASSWORD_FAKE_VAULT_IDS.engineering,\n name: \"Engineering\",\n items: [\n fakeLogin(\"fakeitemgithub000000000001\", \"GitHub\", \"https://github.com\", true),\n fakeLogin(\"fakeitemgrafana00000000001\", \"Grafana\", \"https://grafana.example.test\"),\n fakeLogin(\"fakeitemstatuspage0000001\", \"Statuspage\", \"https://status.example.test\"),\n {\n externalItemId: \"fakeitemstripekey00000001\",\n name: \"Stripe API key\",\n type: \"api_key\",\n fields: [\n {\n externalFieldId: \"credential\",\n name: \"credential\",\n kind: \"concealed\",\n value: \"sk_test_fake\",\n },\n ],\n },\n {\n externalItemId: \"fakeitemsentrydsn00000001\",\n name: \"Sentry DSN\",\n type: \"api_key\",\n fields: [\n {\n externalFieldId: \"credential\",\n name: \"credential\",\n kind: \"concealed\",\n value: \"https://fake@sentry.example.test/1\",\n },\n ],\n },\n {\n externalItemId: \"fakeitemoncallnote0000001\",\n name: \"On-call runbook\",\n type: \"note\",\n fields: [\n {\n externalFieldId: \"@notes\",\n name: \"note\",\n kind: \"concealed\",\n value: \"Page the fake on-call.\",\n },\n ],\n },\n ],\n },\n ],\n });\n } else {\n const base = createFakeVaultProvider({\n accountName: \"fake.1password.test\",\n capabilities: { files: false, groupGrants: false },\n vaults: [\n {\n externalVaultId: ONEPASSWORD_FAKE_VAULT_IDS.shared,\n name: \"Shared\",\n items: [\n fakeLogin(\n \"fakeitemaws000000000000001\",\n \"AWS console\",\n \"https://console.aws.amazon.com\",\n ),\n fakeLogin(\"fakeitemjira00000000000001\", \"Jira\", \"https://jira.example.test\"),\n fakeLogin(\"fakeitemwifi00000000000001\", \"Office Wi-Fi\", \"https://wifi.example.test\"),\n ],\n },\n ],\n });\n const syncError = () =>\n new VaultProviderError(\n \"provider_unavailable\",\n \"1Password could not be reached (simulated sync error for ops_fake_sync_error)\",\n );\n provider = {\n ...base,\n async listItems() {\n throw syncError();\n },\n async writeItem() {\n throw syncError();\n },\n };\n }\n fakeProviders.set(token, provider);\n return provider;\n}\n\n/**\n * The provider for one stored 1Password connection credential. Checks the\n * token offline first (no request); dev fake tokens resolve to a process-wide\n * in-memory fake only when `allowFakeTokens` is set.\n */\nexport function vaultProviderForOnePasswordConnection(\n options: OnePasswordConnectionProviderOptions,\n): VaultProvider & { readonly accountName: string | null; readonly fake: boolean } {\n const token = options.token.trim();\n const description = describeOnePasswordToken(token, {\n allowFakeTokens: options.allowFakeTokens ?? false,\n });\n const provider = description.fake\n ? fakeProviderFor(token as OnePasswordFakeToken)\n : createOnePasswordVaultProvider({\n token,\n planTier: options.planTier ?? \"teams\",\n ...(options.clientCache ? { clientCache: options.clientCache } : {}),\n });\n return { ...provider, accountName: description.accountName, fake: description.fake };\n}\n\nexport function resetOnePasswordFakeProvidersForTests() {\n fakeProviders.clear();\n}\n"],"mappings":"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","names":["VaultProviderError","sdkPromise"]}
|
|
1
|
+
{"version":3,"sources":["../src/contract.ts","../src/budget.ts","../src/errors.ts","../src/mapping.ts","../src/sdk.ts","../src/token.ts","../src/provider.ts","../src/connection.ts"],"sourcesContent":["/**\n * The shared vault contracts this adapter implements (F1: `@opengeni/vaults`\n * §10B.1.4 and `@opengeni/contracts`), re-exported for the package's modules.\n */\nexport {\n VaultProviderError,\n type ProviderCallBudget,\n type ProviderFieldMeta,\n type ProviderFieldValue,\n type ProviderItemMeta,\n type ProviderVault,\n type ProviderWriteItem,\n type VaultProvider,\n type VaultProviderCapabilities,\n type VaultProviderContext,\n type VaultProviderErrorCode,\n} from \"@opengeni/vaults\";\nexport {\n parseTotpInput,\n totpCode,\n type SecretMaterial,\n type TotpParams,\n type VaultFieldKind,\n type VaultItemType,\n} from \"@opengeni/contracts\";\n","import { type ProviderCallBudget, VaultProviderError } from \"./contract\";\n\nexport type OnePasswordPlanTier = \"family\" | \"teams\" | \"business\";\nexport type ProviderCallOp = Parameters<ProviderCallBudget[\"take\"]>[0];\n\n/**\n * HTTP requests each SDK operation makes against 1Password, measured live with\n * @1password/sdk 0.5.0 (evidence/w5/README.md). The daily account quota counts\n * requests, not SDK calls, so the connection quota is charged these weights.\n */\nexport const ONEPASSWORD_REQUEST_COST = {\n signIn: 4,\n vaultsList: 1,\n itemsList: 1,\n itemsGetAll: 1,\n itemsGet: 1,\n filesRead: 1,\n itemsCreate: 2,\n itemsPut: 4,\n itemsArchive: 3,\n itemsDelete: 3,\n vaultsCreate: 9,\n grantGroupPermissions: 2,\n vaultsDelete: 2,\n} as const;\nexport type OnePasswordOperation = keyof typeof ONEPASSWORD_REQUEST_COST;\n\n/**\n * Service-account limits by plan (developer.1password.com/docs/service-accounts/rate-limits):\n * the daily request cap is shared by every service account in the 1Password\n * account; the hourly read/write caps apply per token.\n */\nexport const ONEPASSWORD_PLAN_LIMITS: Record<\n OnePasswordPlanTier,\n { dailyRequests: number; hourlyReads: number; hourlyWrites: number }\n> = {\n family: { dailyRequests: 1_000, hourlyReads: 1_000, hourlyWrites: 100 },\n teams: { dailyRequests: 5_000, hourlyReads: 1_000, hourlyWrites: 100 },\n business: { dailyRequests: 50_000, hourlyReads: 10_000, hourlyWrites: 1_000 },\n};\n\n/** Fraction of the daily account quota Opengeni may burst through at once. */\nconst DAILY_BURST_FRACTION = 0.25;\nconst HOUR_MS = 3_600_000;\nconst DAY_MS = 24 * HOUR_MS;\n\ntype Clock = () => number;\n\nclass TokenBucket {\n private tokens: number;\n private updatedAt: number;\n constructor(\n readonly capacity: number,\n private readonly refillPerMs: number,\n private readonly now: Clock,\n ) {\n this.tokens = capacity;\n this.updatedAt = now();\n }\n private refill() {\n const at = this.now();\n this.tokens = Math.min(this.capacity, this.tokens + (at - this.updatedAt) * this.refillPerMs);\n this.updatedAt = at;\n }\n /** Milliseconds until `cost` tokens are available (0 when available now). */\n waitMs(cost: number): number {\n this.refill();\n if (this.tokens >= cost) return 0;\n return Math.ceil((cost - this.tokens) / this.refillPerMs);\n }\n take(cost: number) {\n this.refill();\n this.tokens -= cost;\n }\n get available() {\n this.refill();\n return this.tokens;\n }\n}\n\n/**\n * Per-connection quota guard. One instance per (connection, plan) lives for the\n * process; it fails fast instead of spending the customer's shared daily quota,\n * and stays closed until `blockedUntil` after a real 429 from 1Password.\n */\nexport class OnePasswordQuota {\n private readonly daily: TokenBucket;\n private readonly reads: TokenBucket;\n private readonly writes: TokenBucket;\n private blockedUntilMs = 0;\n constructor(\n readonly planTier: OnePasswordPlanTier,\n private readonly now: Clock = Date.now,\n ) {\n const limits = ONEPASSWORD_PLAN_LIMITS[planTier];\n this.daily = new TokenBucket(\n Math.max(1, Math.floor(limits.dailyRequests * DAILY_BURST_FRACTION)),\n limits.dailyRequests / DAY_MS,\n now,\n );\n this.reads = new TokenBucket(limits.hourlyReads, limits.hourlyReads / HOUR_MS, now);\n this.writes = new TokenBucket(limits.hourlyWrites, limits.hourlyWrites / HOUR_MS, now);\n }\n\n get blockedUntil(): Date | null {\n return this.blockedUntilMs > this.now() ? new Date(this.blockedUntilMs) : null;\n }\n\n /** Record a real 429 so every later call in this process fails fast. */\n block(retryAfterMs: number) {\n this.blockedUntilMs = Math.max(this.blockedUntilMs, this.now() + retryAfterMs);\n }\n\n take(op: ProviderCallOp, cost = 1) {\n const now = this.now();\n if (this.blockedUntilMs > now) {\n throw new VaultProviderError(\n \"provider_rate_limited\",\n \"1Password is rate limiting this connection; try again later\",\n this.blockedUntilMs - now,\n );\n }\n const lane = op === \"write\" ? this.writes : this.reads;\n const waitMs = Math.max(this.daily.waitMs(cost), lane.waitMs(cost));\n if (waitMs > 0) {\n throw new VaultProviderError(\n \"provider_rate_limited\",\n `Opengeni paused 1Password calls to stay inside the ${this.planTier} plan quota`,\n waitMs,\n );\n }\n this.daily.take(cost);\n lane.take(cost);\n }\n\n /** Remaining daily burst, for diagnostics and tests. */\n get remainingDaily(): number {\n return Math.floor(this.daily.available);\n }\n}\n\nconst quotas = new Map<string, OnePasswordQuota>();\n\n/** Process-wide quota for one connection (or token fingerprint). */\nexport function onePasswordQuotaFor(\n key: string,\n planTier: OnePasswordPlanTier,\n now?: Clock,\n): OnePasswordQuota {\n const existing = quotas.get(key);\n if (existing && existing.planTier === planTier) return existing;\n const quota = new OnePasswordQuota(planTier, now);\n const blockedUntil = existing?.blockedUntil;\n if (blockedUntil) quota.block(blockedUntil.getTime() - Date.now());\n quotas.set(key, quota);\n return quota;\n}\n\nexport function resetOnePasswordQuotasForTests() {\n quotas.clear();\n}\n\n/** design §10.9 / VAULT_LIMITS.providerReadsPerAttempt */\nexport const PROVIDER_READS_PER_ATTEMPT = 50;\n\n/**\n * Attempt-scoped budget: at most `reads` provider reads (list + read) per agent\n * attempt. Writes and admin calls are explicit user/agent actions and are only\n * bounded by the connection quota.\n */\nexport function createAttemptProviderBudget(\n options: { reads?: number } = {},\n): ProviderCallBudget & { readonly used: number } {\n const limit = options.reads ?? PROVIDER_READS_PER_ATTEMPT;\n let used = 0;\n return {\n get used() {\n return used;\n },\n take(op) {\n if (op === \"write\" || op === \"admin\") return;\n if (used >= limit) {\n throw new VaultProviderError(\n \"provider_rate_limited\",\n `This task already made ${limit} password-manager reads; reuse values already fetched or continue in a new turn`,\n );\n }\n used += 1;\n },\n };\n}\n\n/** Budget that never refuses (human-initiated install/link/sync routes). */\nexport const unlimitedProviderBudget: ProviderCallBudget = { take() {} };\n","import { VaultProviderError, type VaultProviderErrorCode } from \"./contract\";\n\n/**\n * The 1Password SDK types only three errors (RateLimitExceededError,\n * AuthExpiredError, DesktopSessionExpiredError); everything else arrives as a\n * plain `Error(message)` whose text comes from the WASM core. This module is the\n * single place that turns those messages into provider error codes. The\n * substrings below were read from @1password/sdk-core 0.5.0 (core_bg.wasm) and\n * are pinned by the unit table in test/errors.test.ts.\n */\ntype MessageRule = { code: VaultProviderErrorCode; needles: readonly string[] };\n\nexport const ONEPASSWORD_MESSAGE_RULES: readonly MessageRule[] = [\n {\n code: \"provider_rate_limited\",\n needles: [\"rate limit exceeded\", \"too many requests\"],\n },\n {\n code: \"provider_auth_invalid\",\n needles: [\n \"service account token had invalid format\",\n \"service account token base64 decoding failed\",\n \"service account deserialization failed\",\n \"invalid service account token\",\n \"service account token is invalid\",\n \"bad service account token\",\n \"prefix 'ops_' was expected\",\n \"throttle token is invalid\",\n \"account couldn't be found\",\n \"invalid sign-in address\",\n \"failed to authenticate\",\n ],\n },\n {\n code: \"provider_auth_expired\",\n needles: [\"you are not authenticated\", \"session expired\"],\n },\n {\n code: \"provider_conflict\",\n needles: [\n \"incorrect item version\",\n \"itemstatusincorrectitemversion\",\n \"a conflict occurred on the server\",\n \"data conflict occurred on the server\",\n ],\n },\n {\n code: \"provider_permission_denied\",\n needles: [\n \"you don't have the right permissions\",\n // Live (2026-10-12): item update in a read-only vault.\n \"you do not have the right permissions\",\n \"not sufficient permissions\",\n \"itemstatuspermissionerror\",\n \"permission denied\",\n ],\n },\n {\n code: \"provider_not_found\",\n needles: [\n \"resource not found\",\n \"itemnotfound\",\n \"vaultnotfound\",\n \"document not found in item\",\n \"file uuid not found\",\n \"file not found\",\n \"group not found\",\n ],\n },\n];\n\nexport type OnePasswordErrorClasses = {\n RateLimitExceededError?: abstract new (...args: never[]) => Error;\n AuthExpiredError?: abstract new (...args: never[]) => Error;\n};\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message ?? \"\";\n if (typeof error === \"string\") return error;\n return \"\";\n}\n\nfunction isNamed(error: unknown, name: string, cls?: abstract new (...args: never[]) => Error) {\n if (cls && error instanceof cls) return true;\n return error instanceof Error && error.constructor?.name === name;\n}\n\nconst MINUTE = 60_000;\n\n/**\n * 1Password reports two rate-limit scopes: the hourly per-token limit (\"this\n * service account\") and the daily per-account limit (\"this 1Password\n * account\"). When the message carries an explicit \"retry in N <unit>\", that\n * wins; otherwise fall back to a scope-shaped default.\n */\nexport function onePasswordRetryAfterMs(message: string): number {\n const lower = message.toLowerCase();\n const match = /retry (?:in|after) (\\d+(?:\\.\\d+)?)\\s*(second|sec|s|minute|min|m|hour|hr|h)/.exec(\n lower,\n );\n if (match) {\n const amount = Number(match[1]);\n const unit = match[2] ?? \"m\";\n const factor = unit.startsWith(\"h\") ? 60 * MINUTE : unit.startsWith(\"m\") ? MINUTE : 1_000;\n return Math.max(1_000, Math.round(amount * factor));\n }\n if (lower.includes(\"1password account\") || lower.includes(\"daily\")) return 6 * 60 * MINUTE;\n if (lower.includes(\"service account\") || lower.includes(\"hourly\")) return 60 * MINUTE;\n return 15 * MINUTE;\n}\n\n/** Map a thrown SDK error to a provider error. Never includes token material. */\nexport function mapOnePasswordError(\n error: unknown,\n classes: OnePasswordErrorClasses = {},\n): VaultProviderError {\n if (error instanceof VaultProviderError) return error;\n const message = errorMessage(error);\n if (isNamed(error, \"RateLimitExceededError\", classes.RateLimitExceededError)) {\n return new VaultProviderError(\n \"provider_rate_limited\",\n `1Password rate limit reached: ${message}`,\n onePasswordRetryAfterMs(message),\n );\n }\n if (isNamed(error, \"AuthExpiredError\", classes.AuthExpiredError)) {\n return new VaultProviderError(\n \"provider_auth_expired\",\n `1Password service account token expired: ${message}`,\n );\n }\n const code = classifyOnePasswordMessage(message);\n if (code === \"provider_rate_limited\") {\n return new VaultProviderError(\n code,\n `1Password rate limit reached: ${message}`,\n onePasswordRetryAfterMs(message),\n );\n }\n return new VaultProviderError(code, `1Password: ${message || \"unknown error\"}`);\n}\n\nexport function classifyOnePasswordMessage(message: string): VaultProviderErrorCode {\n const lower = message.toLowerCase();\n for (const rule of ONEPASSWORD_MESSAGE_RULES) {\n if (rule.needles.some((needle) => lower.includes(needle))) return rule.code;\n }\n return \"provider_unavailable\";\n}\n\n/** True for errors after which a fresh SDK client (new sign-in) may succeed. */\nexport function isOnePasswordSessionError(error: VaultProviderError): boolean {\n return error.code === \"provider_auth_expired\" && !/token expired/i.test(error.message);\n}\n","import {\n type ProviderFieldMeta,\n type ProviderItemMeta,\n type ProviderWriteItem,\n type VaultFieldKind,\n type VaultItemType,\n VaultProviderError,\n} from \"./contract\";\nimport type { SdkItem, SdkItemCreateParams, SdkItemField, SdkWebsite } from \"./sdk\";\n\n/** External field ids that do not name an SDK `fields[]` entry. */\nexport const NOTES_FIELD_ID = \"@notes\";\nexport const DOCUMENT_FIELD_ID = \"@document\";\nexport const FILE_FIELD_PREFIX = \"@file:\";\n/** Section used for custom fields that Opengeni adds to 1Password items. */\nexport const OPENGENI_SECTION_ID = \"opengeni\";\n\nconst API_KEY_CATEGORIES = new Set([\n \"ApiCredentials\",\n \"Password\",\n \"Server\",\n \"Database\",\n \"SshKey\",\n \"SoftwareLicense\",\n \"Router\",\n \"Email\",\n \"CryptoWallet\",\n]);\n\nexport function itemTypeForCategory(category: string): VaultItemType {\n if (category === \"Login\") return \"login\";\n if (category === \"SecureNote\") return \"note\";\n if (category === \"Document\") return \"file\";\n if (API_KEY_CATEGORIES.has(category)) return \"api_key\";\n // CreditCard, Identity, BankAccount, ...: generic fields, shown as notes.\n return \"note\";\n}\n\nexport function categoryForItemType(type: VaultItemType): string {\n switch (type) {\n case \"login\":\n return \"Login\";\n case \"api_key\":\n return \"ApiCredentials\";\n case \"note\":\n return \"SecureNote\";\n case \"file\":\n case \"passkey\":\n throw new VaultProviderError(\n \"provider_unavailable\",\n type === \"passkey\"\n ? \"1Password service accounts cannot store passkeys; keep passkeys in an Opengeni vault\"\n : \"Creating file items in 1Password from Opengeni is not supported yet\",\n );\n }\n}\n\nexport function fieldKindForSdkType(fieldType: string): VaultFieldKind | null {\n switch (fieldType) {\n case \"Concealed\":\n case \"CreditCardNumber\":\n case \"SshKey\":\n return \"concealed\";\n case \"Totp\":\n return \"totp\";\n case \"Unsupported\":\n // Passkeys and other fields the SDK cannot edit; `put` preserves them.\n return null;\n default:\n return \"text\";\n }\n}\n\nfunction sdkTypeForKind(kind: VaultFieldKind): string {\n if (kind === \"text\") return \"Text\";\n if (kind === \"totp\") return \"Totp\";\n if (kind === \"concealed\") return \"Concealed\";\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"Writing file fields to 1Password from Opengeni is not supported yet\",\n );\n}\n\n// Mirrors contracts isValidSecretName (Q-10): no / { } # \\ or control chars,\n// trimmed, 1..120 chars, not \"id:…\"; field names additionally may not be \"otp\".\n// eslint-disable-next-line no-control-regex\nconst FORBIDDEN_NAME_CHARS = /[/{}#\\\\\\u0000-\\u001f\\u007f]/g;\n\nexport function nameKey(name: string): string {\n return name.normalize(\"NFC\").trim().toLowerCase();\n}\n\nexport function safeSecretName(raw: string, fallback: string): string {\n let name = raw.replace(FORBIDDEN_NAME_CHARS, \"-\").trim().slice(0, 120).trim();\n if (!name) name = fallback.replace(FORBIDDEN_NAME_CHARS, \"-\").trim().slice(0, 120) || \"item\";\n if (/^id:/i.test(name)) name = `id-${name.slice(3)}`;\n return name;\n}\n\nfunction safeFieldName(raw: string, fallback: string): string {\n const name = safeSecretName(raw, fallback);\n return nameKey(name) === \"otp\" ? \"otp-code\" : name;\n}\n\n/** Appends \" (2)\", \" (3)\" … so names are unique case-insensitively. */\nexport function uniqueName(name: string, taken: Set<string>): string {\n let candidate = name;\n for (let n = 2; taken.has(nameKey(candidate)); n += 1) {\n const suffix = ` (${n})`;\n candidate = `${name.slice(0, 120 - suffix.length)}${suffix}`;\n }\n taken.add(nameKey(candidate));\n return candidate;\n}\n\nexport type MappedField =\n | (ProviderFieldMeta & { source: \"field\"; field: SdkItemField })\n | (ProviderFieldMeta & { source: \"notes\" })\n | (ProviderFieldMeta & {\n source: \"file\";\n file: { name: string; id: string; size: number };\n });\n\nfunction fieldExternalId(field: SdkItemField, duplicateIds: Set<string>): string {\n return duplicateIds.has(field.id) && field.sectionId\n ? `${field.sectionId}.${field.id}`\n : field.id;\n}\n\n/** Deterministic projection of an item's fields; values are never copied out. */\nexport function mapItemFields(item: SdkItem): MappedField[] {\n const seen = new Set<string>();\n const duplicateIds = new Set<string>();\n for (const field of item.fields) {\n if (seen.has(field.id)) duplicateIds.add(field.id);\n seen.add(field.id);\n }\n const taken = new Set<string>();\n const mapped: MappedField[] = [];\n for (const field of item.fields) {\n const kind = fieldKindForSdkType(field.fieldType);\n if (!kind) continue;\n mapped.push({\n source: \"field\",\n field,\n externalFieldId: fieldExternalId(field, duplicateIds),\n name: uniqueName(safeFieldName(field.title, field.id), taken),\n kind,\n });\n }\n if (item.category === \"SecureNote\" || item.notes) {\n mapped.push({\n source: \"notes\",\n externalFieldId: NOTES_FIELD_ID,\n name: uniqueName(item.category === \"SecureNote\" ? \"note\" : \"notes\", taken),\n kind: \"concealed\",\n });\n }\n if (item.document) {\n mapped.push({\n source: \"file\",\n file: item.document,\n externalFieldId: DOCUMENT_FIELD_ID,\n name: uniqueName(\"file\", taken),\n kind: \"file\",\n });\n }\n for (const file of item.files ?? []) {\n mapped.push({\n source: \"file\",\n file: file.attributes,\n externalFieldId: `${FILE_FIELD_PREFIX}${file.attributes.id}`,\n name: uniqueName(safeFieldName(file.attributes.name, file.attributes.id), taken),\n kind: \"file\",\n });\n }\n return mapped;\n}\n\nfunction isoDate(value: Date | string | undefined | null): string | null {\n if (!value) return null;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? null : date.toISOString();\n}\n\nexport function toProviderItemMeta(item: SdkItem): ProviderItemMeta {\n return {\n externalItemId: item.id,\n name: safeSecretName(item.title, item.id),\n type: itemTypeForCategory(item.category),\n websites: (item.websites ?? []).map((website) => website.url).filter(Boolean),\n fields: mapItemFields(item).map(({ externalFieldId, name, kind }) => ({\n externalFieldId,\n name,\n kind,\n })),\n version: String(item.version),\n updatedAt: isoDate(item.updatedAt),\n };\n}\n\nfunction toWebsites(urls: readonly string[], previous: readonly SdkWebsite[] = []): SdkWebsite[] {\n return urls.map(\n (url) =>\n previous.find((website) => website.url === url) ?? {\n url,\n label: \"website\",\n autofillBehavior: \"AnywhereOnWebsite\",\n },\n );\n}\n\ntype WriteField = ProviderWriteItem[\"fields\"][number];\n\n/** Built-in 1Password field that a named Opengeni field maps onto, if any. */\nfunction builtInFieldFor(\n category: string,\n field: WriteField,\n): { id: string; fieldType: string } | null {\n const key = nameKey(field.name);\n if (category === \"Login\" && key === \"username\") return { id: \"username\", fieldType: \"Text\" };\n if (category === \"Login\" && key === \"password\") return { id: \"password\", fieldType: \"Concealed\" };\n if (category === \"ApiCredentials\" && (key === \"value\" || key === \"credential\"))\n return { id: \"credential\", fieldType: \"Concealed\" };\n if (category === \"ApiCredentials\" && key === \"username\")\n return { id: \"username\", fieldType: \"Text\" };\n return null;\n}\n\nfunction isNotesField(category: string, field: WriteField): boolean {\n if (field.externalFieldId === NOTES_FIELD_ID) return true;\n const key = nameKey(field.name);\n return category === \"SecureNote\" ? key === \"note\" || key === \"notes\" : key === \"notes\";\n}\n\nfunction customFieldId(name: string, item: { fields: SdkItemField[] }): string {\n const slug =\n nameKey(name)\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\") || \"field\";\n const ids = new Set(item.fields.map((field) => field.id));\n let id = `opengeni_${slug}`.slice(0, 64);\n for (let n = 2; ids.has(id); n += 1) id = `opengeni_${slug}`.slice(0, 60) + `_${n}`;\n return id;\n}\n\nfunction requireValue(field: WriteField): string {\n if (field.value === undefined) {\n throw new VaultProviderError(\n \"provider_conflict\",\n `Field \"${field.name}\" has no value to write`,\n );\n }\n return field.value;\n}\n\nfunction addField(\n target: SdkItem | (SdkItemCreateParams & { fields: SdkItemField[] }),\n category: string,\n field: WriteField,\n) {\n const value = requireValue(field);\n const builtIn = builtInFieldFor(category, field);\n if (builtIn && !target.fields.some((existing) => existing.id === builtIn.id)) {\n target.fields.push({ id: builtIn.id, title: field.name, fieldType: builtIn.fieldType, value });\n return;\n }\n const sections = (target.sections ??= []);\n if (!sections.some((section) => section.id === OPENGENI_SECTION_ID)) {\n sections.push({ id: OPENGENI_SECTION_ID, title: \"\" });\n }\n target.fields.push({\n id: customFieldId(field.name, target),\n title: field.name,\n sectionId: OPENGENI_SECTION_ID,\n fieldType: sdkTypeForKind(field.kind),\n value,\n });\n}\n\nexport function buildCreateParams(\n externalVaultId: string,\n write: ProviderWriteItem,\n): SdkItemCreateParams {\n const category = categoryForItemType(write.type);\n const params: SdkItemCreateParams & {\n fields: SdkItemField[];\n sections: Array<{ id: string; title: string }>;\n } = {\n category,\n vaultId: externalVaultId,\n title: write.name,\n fields: [],\n sections: [],\n websites: toWebsites(write.websites),\n };\n for (const field of write.fields) {\n if (field.remove) continue;\n if (isNotesField(category, field)) {\n params.notes = requireValue(field);\n continue;\n }\n addField(params, category, field);\n }\n return params;\n}\n\n/** Applies a field patch to a freshly read item (get → patch → put). */\nexport function applyWrite(item: SdkItem, write: ProviderWriteItem): SdkItem {\n const next: SdkItem = {\n ...item,\n title: write.name,\n fields: item.fields.map((field) => ({ ...field })),\n sections: [...(item.sections ?? [])],\n websites: toWebsites(write.websites, item.websites),\n };\n for (const field of write.fields) {\n const mapped = mapItemFields(next);\n const target =\n (field.externalFieldId\n ? mapped.find((candidate) => candidate.externalFieldId === field.externalFieldId)\n : undefined) ?? mapped.find((candidate) => nameKey(candidate.name) === nameKey(field.name));\n if (target?.source === \"file\" || (!target && field.kind === \"file\")) {\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"Writing file fields to 1Password from Opengeni is not supported yet\",\n );\n }\n if (field.remove) {\n if (!target) continue;\n if (target.source === \"notes\") next.notes = \"\";\n else next.fields = next.fields.filter((candidate) => candidate !== target.field);\n continue;\n }\n if (target?.source === \"notes\" || (!target && isNotesField(next.category, field))) {\n next.notes = requireValue(field);\n continue;\n }\n if (target?.source === \"field\") {\n target.field.value = requireValue(field);\n if (field.kind !== target.kind && field.kind !== \"file\") {\n target.field.fieldType = sdkTypeForKind(field.kind);\n }\n continue;\n }\n addField(next, next.category, field);\n }\n return next;\n}\n","/**\n * The narrow slice of `@1password/sdk` this adapter uses, typed structurally so\n * tests can inject an in-memory double and so the SDK (a ~14 MB WASM core) is\n * only ever loaded through `loadOnePasswordSdk()`'s dynamic import.\n */\nimport { VaultProviderError } from \"@opengeni/vaults\";\n\nexport type SdkFieldType =\n | \"Text\"\n | \"Concealed\"\n | \"CreditCardType\"\n | \"CreditCardNumber\"\n | \"Phone\"\n | \"Url\"\n | \"Totp\"\n | \"Email\"\n | \"Reference\"\n | \"SshKey\"\n | \"Menu\"\n | \"MonthYear\"\n | \"Address\"\n | \"Date\"\n | \"Unsupported\";\n\nexport interface SdkItemField {\n id: string;\n title: string;\n sectionId?: string;\n fieldType: SdkFieldType | (string & {});\n value: string;\n details?: { type: string; content?: { code?: string; errorMessage?: string } | unknown };\n}\nexport interface SdkWebsite {\n url: string;\n label: string;\n autofillBehavior: string;\n}\nexport interface SdkFileAttributes {\n name: string;\n id: string;\n size: number;\n}\nexport interface SdkItem {\n id: string;\n title: string;\n category: string;\n vaultId: string;\n fields: SdkItemField[];\n sections: Array<{ id: string; title: string }>;\n notes: string;\n tags: string[];\n websites: SdkWebsite[];\n version: number;\n files: Array<{ attributes: SdkFileAttributes; sectionId: string; fieldId: string }>;\n document?: SdkFileAttributes;\n createdAt: Date;\n updatedAt: Date;\n}\nexport interface SdkItemOverview {\n id: string;\n title: string;\n category: string;\n vaultId: string;\n websites: SdkWebsite[];\n updatedAt: Date;\n state: string;\n}\nexport interface SdkItemCreateParams {\n category: string;\n vaultId: string;\n title: string;\n fields?: SdkItemField[];\n sections?: Array<{ id: string; title: string }>;\n notes?: string;\n tags?: string[];\n websites?: SdkWebsite[];\n}\nexport interface SdkVaultOverview {\n id: string;\n title: string;\n description: string;\n vaultType: string;\n activeItemCount: number;\n contentVersion: number;\n}\nexport type SdkItemListFilter = {\n type: \"ByState\";\n content: { active: boolean; archived: boolean };\n};\nexport interface SdkGetAllResponse {\n individualResponses: Array<{ content?: SdkItem; error?: { type: string; message?: string } }>;\n}\n\nexport interface OnePasswordSdkClient {\n vaults: {\n list(params?: { decryptDetails?: boolean }): Promise<SdkVaultOverview[]>;\n create(params: {\n title: string;\n description?: string;\n allowAdminsAccess?: boolean;\n }): Promise<SdkVaultOverview>;\n delete(vaultId: string): Promise<void>;\n grantGroupPermissions(\n vaultId: string,\n groups: Array<{ groupId: string; permissions: number }>,\n ): Promise<void>;\n };\n items: {\n list(vaultId: string, ...filters: SdkItemListFilter[]): Promise<SdkItemOverview[]>;\n get(vaultId: string, itemId: string): Promise<SdkItem>;\n getAll(vaultId: string, itemIds: string[]): Promise<SdkGetAllResponse>;\n create(params: SdkItemCreateParams): Promise<SdkItem>;\n put(item: SdkItem): Promise<SdkItem>;\n archive(vaultId: string, itemId: string): Promise<void>;\n delete(vaultId: string, itemId: string): Promise<void>;\n files: {\n read(vaultId: string, itemId: string, attributes: SdkFileAttributes): Promise<Uint8Array>;\n };\n };\n}\n\nexport interface OnePasswordSdk {\n createClient(config: {\n auth: string;\n integrationName: string;\n integrationVersion: string;\n }): Promise<OnePasswordSdkClient>;\n RateLimitExceededError?: abstract new (...args: never[]) => Error;\n AuthExpiredError?: abstract new (...args: never[]) => Error;\n}\n\nexport const ONEPASSWORD_SDK_VERSION = \"0.5.0\";\nexport const ONEPASSWORD_INTEGRATION_NAME = \"OpenGeni\";\n\nlet sdkPromise: Promise<OnePasswordSdk> | null = null;\n\n/**\n * Lazily loads the pinned SDK (WASM) once per process. A server that cannot\n * load it (for example a broken image without the WASM core) reports\n * `provider_unavailable` with a plain reason, so connecting and syncing say\n * what is wrong instead of failing with a generic error, and the next call\n * tries again.\n */\nexport function loadOnePasswordSdk(\n importSdk: () => Promise<{\n createClient: unknown;\n RateLimitExceededError?: unknown;\n AuthExpiredError?: unknown;\n }> = () => import(\"@1password/sdk\"),\n): Promise<OnePasswordSdk> {\n const loading = (sdkPromise ??= importSdk().then(\n (module): OnePasswordSdk => ({\n createClient: module.createClient as OnePasswordSdk[\"createClient\"],\n ...(module.RateLimitExceededError\n ? {\n RateLimitExceededError:\n module.RateLimitExceededError as OnePasswordSdk[\"RateLimitExceededError\"] & {},\n }\n : {}),\n ...(module.AuthExpiredError\n ? { AuthExpiredError: module.AuthExpiredError as OnePasswordSdk[\"AuthExpiredError\"] & {} }\n : {}),\n }),\n (cause: unknown) => {\n sdkPromise = null;\n console.error(\"[vaults-onepassword] the 1Password SDK failed to load\", cause);\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"1Password support could not be loaded on this server. Ask whoever runs it to check the deployment.\",\n );\n },\n ));\n return loading;\n}\n\n/**\n * One signed-in client per token per process. Creating a client performs the\n * SRP sign-in (several requests), so reuse matters for the account quota.\n * The cache must hold the SDK `Client` object itself: the SDK releases the\n * WASM session when that object is garbage collected, so keeping only\n * `client.items` / `client.vaults` fails later calls with \"invalid client id\".\n */\nexport class OnePasswordClientCache {\n private readonly clients = new Map<string, Promise<OnePasswordSdkClient>>();\n\n get(key: string, create: () => Promise<OnePasswordSdkClient>): Promise<OnePasswordSdkClient> {\n let client = this.clients.get(key);\n if (!client) {\n client = create();\n this.clients.set(key, client);\n client.catch(() => {\n if (this.clients.get(key) === client) this.clients.delete(key);\n });\n }\n return client;\n }\n\n drop(key: string) {\n this.clients.delete(key);\n }\n\n /** True when a signed-in (or signing-in) client exists for `key`. */\n has(key: string): boolean {\n return this.clients.has(key);\n }\n\n clear() {\n this.clients.clear();\n }\n}\n\nexport const sharedOnePasswordClientCache = new OnePasswordClientCache();\n","import { VaultProviderError } from \"./contract\";\n\nexport const ONEPASSWORD_FAKE_TOKENS = [\"ops_fake_healthy\", \"ops_fake_sync_error\"] as const;\nexport type OnePasswordFakeToken = (typeof ONEPASSWORD_FAKE_TOKENS)[number];\n\nexport function isOnePasswordFakeToken(token: string): token is OnePasswordFakeToken {\n return (ONEPASSWORD_FAKE_TOKENS as readonly string[]).includes(token);\n}\n\nexport type OnePasswordTokenDescription = {\n /** Sign-in host, for example \"my.1password.com\". Never secret. */\n accountName: string | null;\n fake: boolean;\n};\n\nconst REQUIRED_KEYS = [\"signInAddress\", \"deviceUuid\", \"email\", \"srpX\", \"muk\", \"secretKey\"] as const;\n\n/**\n * Offline service-account token check: `ops_` + base64 JSON carrying the sign-in\n * address and key material. It costs no 1Password request. The error message never\n * echoes the token.\n */\nexport function describeOnePasswordToken(\n token: string,\n options: { allowFakeTokens?: boolean } = {},\n): OnePasswordTokenDescription {\n const trimmed = token.trim();\n if (options.allowFakeTokens && isOnePasswordFakeToken(trimmed)) {\n return { accountName: \"fake.1password.test\", fake: true };\n }\n const invalid = (detail: string) =>\n new VaultProviderError(\n \"provider_auth_invalid\",\n `This is not a 1Password service account token (${detail}). Create one in 1Password under Developer > Service accounts and paste the full token, which starts with \"ops_\".`,\n );\n if (!trimmed.startsWith(\"ops_\")) throw invalid(\"missing the ops_ prefix\");\n let decoded: unknown;\n try {\n const body = trimmed.slice(4).replace(/-/g, \"+\").replace(/_/g, \"/\");\n decoded = JSON.parse(Buffer.from(body, \"base64\").toString(\"utf8\"));\n } catch {\n throw invalid(\"it could not be decoded\");\n }\n if (!decoded || typeof decoded !== \"object\" || Array.isArray(decoded)) {\n throw invalid(\"it could not be decoded\");\n }\n const record = decoded as Record<string, unknown>;\n for (const key of REQUIRED_KEYS) {\n if (typeof record[key] !== \"string\" && typeof record[key] !== \"object\") {\n throw invalid(\"it is incomplete\");\n }\n }\n return { accountName: signInHost(record.signInAddress), fake: false };\n}\n\nfunction signInHost(value: unknown): string | null {\n if (typeof value !== \"string\" || !value) return null;\n try {\n return new URL(value.includes(\"://\") ? value : `https://${value}`).hostname || null;\n } catch {\n return null;\n }\n}\n\n/** Stable, non-reversible fingerprint used to key SDK clients per token. */\nexport async function onePasswordTokenFingerprint(token: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(token.trim()));\n return Buffer.from(digest).subarray(0, 12).toString(\"hex\");\n}\n","import {\n type ProviderCallBudget,\n type ProviderFieldValue,\n type ProviderItemMeta,\n type ProviderVault,\n type SecretMaterial,\n type VaultProvider,\n type VaultProviderCapabilities,\n type VaultProviderContext,\n VaultProviderError,\n parseTotpInput,\n} from \"./contract\";\nimport {\n ONEPASSWORD_REQUEST_COST,\n type OnePasswordOperation,\n type OnePasswordPlanTier,\n type ProviderCallOp,\n onePasswordQuotaFor,\n} from \"./budget\";\nimport { isOnePasswordSessionError, mapOnePasswordError } from \"./errors\";\nimport { applyWrite, buildCreateParams, mapItemFields, toProviderItemMeta } from \"./mapping\";\nimport {\n ONEPASSWORD_INTEGRATION_NAME,\n type OnePasswordClientCache,\n type OnePasswordSdk,\n type OnePasswordSdkClient,\n type SdkItem,\n loadOnePasswordSdk,\n sharedOnePasswordClientCache,\n} from \"./sdk\";\nimport { describeOnePasswordToken, onePasswordTokenFingerprint } from \"./token\";\n\n/** design §10.9 / VAULT_LIMITS.providerValueCacheMs */\nexport const ONEPASSWORD_VALUE_CACHE_MS = 60_000;\n/** Items per `items.getAll` request when mirroring metadata. */\nexport const ONEPASSWORD_GET_ALL_BATCH = 50;\n\n/**\n * Group permissions granted on a managed vault: the Teams \"edit\" bundle\n * (read, reveal, item history, create, update, archive, delete).\n */\nexport const ONEPASSWORD_MANAGED_GROUP_PERMISSIONS = 32 | 16 | 1024 | 128 | 64 | 256 | 512;\n\n/** Creation succeeded; only the subsequent sharing step failed or is unknown. */\nexport class OnePasswordVaultCreatedError extends VaultProviderError {\n constructor(\n readonly createdVault: ProviderVault,\n failure: VaultProviderError,\n ) {\n super(\n failure.code,\n \"The vault was created, but its group access could not be confirmed. Do not create it again.\",\n failure.retryAfterMs,\n );\n }\n}\n\n/**\n * 1Password vault and item IDs are short lowercase alphanumerics (26 chars).\n * Anything else cannot exist, so refuse it as not found before spending a\n * request (and before the SDK reports it as a generic validation error).\n */\nconst ONEPASSWORD_ID = /^[a-z0-9]{1,64}$/i;\nfunction assertOnePasswordIds(...ids: Array<string | undefined>) {\n for (const id of ids) {\n if (id !== undefined && !ONEPASSWORD_ID.test(id)) {\n throw new VaultProviderError(\"provider_not_found\", \"No such 1Password vault or item\");\n }\n }\n}\n\nexport type OnePasswordVaultProviderOptions = {\n token: string;\n planTier?: OnePasswordPlanTier;\n /** Injected SDK (tests); defaults to the pinned dynamic import. */\n sdk?: OnePasswordSdk | (() => Promise<OnePasswordSdk>);\n clientCache?: OnePasswordClientCache;\n integrationVersion?: string;\n now?: () => number;\n valueCacheMs?: number;\n};\n\nexport type OnePasswordVaultProvider = VaultProvider & {\n readonly planTier: OnePasswordPlanTier;\n /** Deletes a vault this service account created (managed-vault cleanup, live tests). */\n deleteVault(ctx: VaultProviderContext, externalVaultId: string): Promise<void>;\n /** Permanently deletes an item (live-test cleanup only; product paths archive). */\n deleteItem(\n ctx: VaultProviderContext,\n externalVaultId: string,\n externalItemId: string,\n ): Promise<void>;\n};\n\ntype CachedItem = { at: number; epoch: string | null; item: Promise<SdkItem> };\n\n/**\n * Values never outlive the attempt that read them: the cache is keyed by the\n * attempt's budget object (one per attempt or request), so it is dropped with it.\n * Within an attempt, entries are scoped to the connection and token that read\n * them, and to the vault's durable cache epoch: a mirror refresh in any API or\n * worker process advances the epoch, so later reads fetch the item again.\n */\nconst attemptItemCaches = new WeakMap<ProviderCallBudget, Map<string, CachedItem>>();\n\nexport function createOnePasswordVaultProvider(\n options: OnePasswordVaultProviderOptions,\n): OnePasswordVaultProvider {\n const token = options.token.trim();\n const planTier = options.planTier ?? \"teams\";\n const now = options.now ?? Date.now;\n const clients = options.clientCache ?? sharedOnePasswordClientCache;\n const valueCacheMs = options.valueCacheMs ?? ONEPASSWORD_VALUE_CACHE_MS;\n const description = describeOnePasswordToken(token);\n let fingerprint: Promise<string> | null = null;\n let sdkPromise: Promise<OnePasswordSdk> | null = null;\n\n const loadSdk = () => {\n sdkPromise ??=\n typeof options.sdk === \"function\"\n ? options.sdk()\n : options.sdk\n ? Promise.resolve(options.sdk)\n : loadOnePasswordSdk();\n return sdkPromise;\n };\n\n async function keys(ctx: VaultProviderContext) {\n fingerprint ??= onePasswordTokenFingerprint(token);\n const tokenKey = await fingerprint;\n return {\n client: `${ctx.connectionId ?? \"token\"}:${tokenKey}`,\n quota: ctx.connectionId ?? `token:${tokenKey}`,\n };\n }\n\n async function call<T>(\n ctx: VaultProviderContext,\n op: ProviderCallOp,\n operation: OnePasswordOperation,\n fn: (client: OnePasswordSdkClient) => Promise<T>,\n ): Promise<T> {\n ctx.signal?.throwIfAborted();\n const key = await keys(ctx);\n const quota = onePasswordQuotaFor(key.quota, planTier, now);\n ctx.budget.take(op);\n // A cold client signs in first; charge that before spending anything.\n const cost =\n ONEPASSWORD_REQUEST_COST[operation] +\n (clients.has(key.client) ? 0 : ONEPASSWORD_REQUEST_COST.signIn);\n quota.take(op, cost);\n const sdk = await loadSdk();\n const classes = {\n ...(sdk.RateLimitExceededError ? { RateLimitExceededError: sdk.RateLimitExceededError } : {}),\n ...(sdk.AuthExpiredError ? { AuthExpiredError: sdk.AuthExpiredError } : {}),\n };\n for (let attempt = 0; ; attempt += 1) {\n // Set once a mutation is handed to the SDK: a failure 1Password does not\n // classify after that may still have been applied.\n let sent = false;\n try {\n const client = await clients.get(key.client, () =>\n sdk.createClient({\n auth: token,\n integrationName: ONEPASSWORD_INTEGRATION_NAME,\n integrationVersion: options.integrationVersion ?? \"1\",\n }),\n );\n sent =\n op === \"write\" ||\n operation === \"vaultsCreate\" ||\n operation === \"vaultsDelete\" ||\n operation === \"grantGroupPermissions\";\n return await fn(client);\n } catch (error) {\n const mapped = mapOnePasswordError(error, classes);\n if (mapped.code === \"provider_rate_limited\" && mapped.retryAfterMs) {\n quota.block(mapped.retryAfterMs);\n }\n if (mapped.code === \"provider_auth_expired\" || mapped.code === \"provider_auth_invalid\") {\n clients.drop(key.client);\n }\n if (attempt === 0 && isOnePasswordSessionError(mapped)) continue;\n if (sent && mapped.code === \"provider_unavailable\") {\n // Never reported as a plain failure that invites saving it again.\n throw new VaultProviderError(\n \"provider_outcome_unknown\",\n \"1Password did not confirm the change; it may have been applied\",\n );\n }\n throw mapped;\n }\n }\n }\n\n function itemCache(ctx: VaultProviderContext): Map<string, CachedItem> {\n let cache = attemptItemCaches.get(ctx.budget);\n if (!cache) {\n cache = new Map();\n attemptItemCaches.set(ctx.budget, cache);\n }\n return cache;\n }\n\n /**\n * Live item read, cached per attempt for 60 s with single-flight. A changed\n * `cacheEpoch` or `forceRefresh` reads the item again and replaces the entry.\n */\n async function getItem(\n ctx: VaultProviderContext,\n vaultId: string,\n itemId: string,\n ): Promise<SdkItem> {\n const { client: clientKey } = await keys(ctx);\n // No await between the lookup and the insert below keeps the single flight.\n const cache = itemCache(ctx);\n const cacheKey = `${clientKey}|${vaultId}/${itemId}`;\n const epoch = ctx.cacheEpoch ?? null;\n const cached = cache.get(cacheKey);\n if (cached && !ctx.forceRefresh && cached.epoch === epoch && now() - cached.at < valueCacheMs) {\n return await cached.item;\n }\n const item = call(ctx, \"read\", \"itemsGet\", (client) => client.items.get(vaultId, itemId));\n cache.set(cacheKey, { at: now(), epoch, item });\n item.catch(() => {\n if (cache.get(cacheKey)?.item === item) cache.delete(cacheKey);\n });\n return await item;\n }\n\n /** Drops the attempt's cached copies of an item, whichever connection read them. */\n function forgetItem(ctx: VaultProviderContext, vaultId: string, itemId: string) {\n const cache = attemptItemCaches.get(ctx.budget);\n if (!cache) return;\n const suffix = `|${vaultId}/${itemId}`;\n for (const cacheKey of [...cache.keys()]) {\n if (cacheKey.endsWith(suffix)) cache.delete(cacheKey);\n }\n }\n\n async function materialFor(\n ctx: VaultProviderContext,\n item: SdkItem,\n externalFieldId: string,\n ): Promise<SecretMaterial> {\n const field = mapItemFields(item).find(\n (candidate) => candidate.externalFieldId === externalFieldId,\n );\n if (!field) {\n throw new VaultProviderError(\n \"provider_not_found\",\n `1Password item \"${item.title}\" has no field ${externalFieldId}`,\n );\n }\n if (field.source === \"notes\") return { type: \"text\", value: item.notes };\n if (field.source === \"file\") {\n const bytes = await call(ctx, \"read\", \"filesRead\", (client) =>\n client.items.files.read(item.vaultId, item.id, field.file),\n );\n return { type: \"bytes\", value: bytes };\n }\n if (field.kind === \"totp\") {\n try {\n return { type: \"totp\", params: parseTotpInput(field.field.value) };\n } catch {\n const details = field.field.details?.content as { code?: string } | undefined;\n if (details?.code) return { type: \"text\", value: details.code };\n throw new VaultProviderError(\n \"provider_unavailable\",\n `The one-time password in 1Password item \"${item.title}\" is not a valid TOTP seed`,\n );\n }\n }\n return { type: \"text\", value: field.field.value };\n }\n\n const provider: OnePasswordVaultProvider = {\n id: \"onepassword\",\n planTier,\n\n capabilities(): VaultProviderCapabilities {\n return {\n write: true,\n createVault: true,\n totp: true,\n // File and Document fields are readable; writing them is not supported.\n files: false,\n groupGrants: planTier !== \"family\",\n passkeys: false,\n };\n },\n\n async validate(ctx) {\n await provider.listVaults(ctx);\n return { accountName: description.accountName };\n },\n\n async listVaults(ctx): Promise<ProviderVault[]> {\n const vaults = await call(ctx, \"list\", \"vaultsList\", (client) => client.vaults.list());\n return vaults.map((vault) => ({\n externalVaultId: vault.id,\n name: vault.title,\n contentVersion: vault.contentVersion === undefined ? null : String(vault.contentVersion),\n itemCount: typeof vault.activeItemCount === \"number\" ? vault.activeItemCount : null,\n }));\n },\n\n async listItems(ctx, externalVaultId): Promise<ProviderItemMeta[]> {\n assertOnePasswordIds(externalVaultId);\n const overviews = await call(ctx, \"list\", \"itemsList\", (client) =>\n client.items.list(externalVaultId, {\n type: \"ByState\",\n content: { active: true, archived: false },\n }),\n );\n const items: ProviderItemMeta[] = [];\n for (let start = 0; start < overviews.length; start += ONEPASSWORD_GET_ALL_BATCH) {\n const ids = overviews.slice(start, start + ONEPASSWORD_GET_ALL_BATCH).map((o) => o.id);\n const batch = await call(ctx, \"read\", \"itemsGetAll\", (client) =>\n client.items.getAll(externalVaultId, ids),\n );\n for (const response of batch.individualResponses) {\n // An item deleted between list and getAll simply drops out of the mirror.\n if (response.content) items.push(toProviderItemMeta(response.content));\n }\n }\n return items;\n },\n\n async readFields(ctx, externalVaultId, externalItemId, externalFieldIds) {\n assertOnePasswordIds(externalVaultId, externalItemId);\n const item = await getItem(ctx, externalVaultId, externalItemId);\n const values: ProviderFieldValue[] = [];\n for (const externalFieldId of externalFieldIds) {\n values.push({ externalFieldId, material: await materialFor(ctx, item, externalFieldId) });\n }\n return values;\n },\n\n async writeItem(ctx, externalVaultId, write) {\n assertOnePasswordIds(externalVaultId, write.externalItemId);\n if (!write.externalItemId) {\n const params = buildCreateParams(externalVaultId, write);\n const created = await call(ctx, \"write\", \"itemsCreate\", (client) =>\n client.items.create(params),\n );\n return toProviderItemMeta(created);\n }\n const itemId = write.externalItemId;\n forgetItem(ctx, externalVaultId, itemId);\n for (let attempt = 0; ; attempt += 1) {\n const current = await call(ctx, \"read\", \"itemsGet\", (client) =>\n client.items.get(externalVaultId, itemId),\n );\n if (\n write.expectedVersion !== undefined &&\n write.expectedVersion !== null &&\n String(current.version) !== write.expectedVersion\n ) {\n throw new VaultProviderError(\n \"provider_conflict\",\n `1Password item \"${current.title}\" changed (version ${current.version}, expected ${write.expectedVersion}); reload and retry`,\n );\n }\n const next = applyWrite(current, write);\n try {\n const saved = await call(ctx, \"write\", \"itemsPut\", (client) => client.items.put(next));\n return toProviderItemMeta(saved);\n } catch (error) {\n // Without an explicit expected version, a concurrent edit is re-read and\n // the same field patch re-applied once; never overwrite a stale view.\n const retry =\n error instanceof VaultProviderError &&\n error.code === \"provider_conflict\" &&\n attempt === 0 &&\n (write.expectedVersion === undefined || write.expectedVersion === null);\n if (!retry) throw error;\n } finally {\n forgetItem(ctx, externalVaultId, itemId);\n }\n }\n },\n\n async archiveItem(ctx, externalVaultId, externalItemId) {\n assertOnePasswordIds(externalVaultId, externalItemId);\n await call(ctx, \"write\", \"itemsArchive\", (client) =>\n client.items.archive(externalVaultId, externalItemId),\n );\n forgetItem(ctx, externalVaultId, externalItemId);\n },\n\n async createVault(ctx, input) {\n if (input.groupId && planTier === \"family\") {\n throw new VaultProviderError(\n \"provider_unavailable\",\n \"1Password Families accounts have no groups; share the vault in 1Password instead\",\n );\n }\n const vault = await call(ctx, \"admin\", \"vaultsCreate\", (client) =>\n client.vaults.create({\n title: input.name,\n ...(input.description ? { description: input.description } : {}),\n allowAdminsAccess: input.allowAdminsAccess,\n }),\n );\n const created: ProviderVault = {\n externalVaultId: vault.id,\n name: vault.title,\n contentVersion: vault.contentVersion === undefined ? null : String(vault.contentVersion),\n itemCount: typeof vault.activeItemCount === \"number\" ? vault.activeItemCount : 0,\n };\n if (input.groupId) {\n const groupId = input.groupId;\n try {\n await call(ctx, \"admin\", \"grantGroupPermissions\", (client) =>\n client.vaults.grantGroupPermissions(vault.id, [\n { groupId, permissions: ONEPASSWORD_MANAGED_GROUP_PERMISSIONS },\n ]),\n );\n } catch (error) {\n throw new OnePasswordVaultCreatedError(\n created,\n error instanceof VaultProviderError ? error : mapOnePasswordError(error),\n );\n }\n }\n return created;\n },\n\n async deleteVault(ctx, externalVaultId) {\n assertOnePasswordIds(externalVaultId);\n await call(ctx, \"admin\", \"vaultsDelete\", (client) => client.vaults.delete(externalVaultId));\n },\n\n async deleteItem(ctx, externalVaultId, externalItemId) {\n assertOnePasswordIds(externalVaultId, externalItemId);\n await call(ctx, \"write\", \"itemsDelete\", (client) =>\n client.items.delete(externalVaultId, externalItemId),\n );\n forgetItem(ctx, externalVaultId, externalItemId);\n },\n };\n return provider;\n}\n","import { createFakeVaultProvider } from \"@opengeni/vaults/testing/fake-provider\";\n\nimport type { OnePasswordPlanTier } from \"./budget\";\nimport { type VaultProvider, VaultProviderError } from \"./contract\";\nimport { createOnePasswordVaultProvider } from \"./provider\";\nimport { type OnePasswordClientCache } from \"./sdk\";\nimport { type OnePasswordFakeToken, describeOnePasswordToken } from \"./token\";\n\nexport type OnePasswordConnectionProviderOptions = {\n token: string;\n planTier?: OnePasswordPlanTier;\n /** `settings.onePasswordFakeTokens` (refused by the managed runtime posture). */\n allowFakeTokens?: boolean;\n clientCache?: OnePasswordClientCache;\n};\n\n/** Stable IDs so API and worker processes agree on the fake vaults. */\nexport const ONEPASSWORD_FAKE_VAULT_IDS = {\n engineering: \"fakeengineeringvault000001\",\n shared: \"fakesharedvault00000000001\",\n} as const;\n\nconst fakeProviders = new Map<OnePasswordFakeToken, VaultProvider>();\n\nfunction fakeLogin(id: string, name: string, website: string, totp = false) {\n return {\n externalItemId: id,\n name,\n type: \"login\" as const,\n websites: [website],\n fields: [\n {\n externalFieldId: \"username\",\n name: \"username\",\n kind: \"text\" as const,\n value: `${id}@example.test`,\n },\n {\n externalFieldId: \"password\",\n name: \"password\",\n kind: \"concealed\" as const,\n value: `fake-${id}-password`,\n },\n ...(totp\n ? [\n {\n externalFieldId: \"otp\",\n name: \"one-time password\",\n kind: \"totp\" as const,\n value: \"otpauth://totp/Fake:engineering?secret=JBSWY3DPEHPK3PXP&period=30&digits=6\",\n },\n ]\n : []),\n ],\n };\n}\n\nfunction fakeProviderFor(token: OnePasswordFakeToken): VaultProvider {\n const existing = fakeProviders.get(token);\n if (existing) return existing;\n let provider: VaultProvider;\n if (token === \"ops_fake_healthy\") {\n provider = createFakeVaultProvider({\n accountName: \"fake.1password.test\",\n capabilities: { files: false, groupGrants: false },\n vaults: [\n {\n externalVaultId: ONEPASSWORD_FAKE_VAULT_IDS.engineering,\n name: \"Engineering\",\n items: [\n fakeLogin(\"fakeitemgithub000000000001\", \"GitHub\", \"https://github.com\", true),\n fakeLogin(\"fakeitemgrafana00000000001\", \"Grafana\", \"https://grafana.example.test\"),\n fakeLogin(\"fakeitemstatuspage0000001\", \"Statuspage\", \"https://status.example.test\"),\n {\n externalItemId: \"fakeitemstripekey00000001\",\n name: \"Stripe API key\",\n type: \"api_key\",\n fields: [\n {\n externalFieldId: \"credential\",\n name: \"credential\",\n kind: \"concealed\",\n value: \"sk_test_fake\",\n },\n ],\n },\n {\n externalItemId: \"fakeitemsentrydsn00000001\",\n name: \"Sentry DSN\",\n type: \"api_key\",\n fields: [\n {\n externalFieldId: \"credential\",\n name: \"credential\",\n kind: \"concealed\",\n value: \"https://fake@sentry.example.test/1\",\n },\n ],\n },\n {\n externalItemId: \"fakeitemoncallnote0000001\",\n name: \"On-call runbook\",\n type: \"note\",\n fields: [\n {\n externalFieldId: \"@notes\",\n name: \"note\",\n kind: \"concealed\",\n value: \"Page the fake on-call.\",\n },\n ],\n },\n ],\n },\n ],\n });\n } else {\n const base = createFakeVaultProvider({\n accountName: \"fake.1password.test\",\n capabilities: { files: false, groupGrants: false },\n vaults: [\n {\n externalVaultId: ONEPASSWORD_FAKE_VAULT_IDS.shared,\n name: \"Shared\",\n items: [\n fakeLogin(\n \"fakeitemaws000000000000001\",\n \"AWS console\",\n \"https://console.aws.amazon.com\",\n ),\n fakeLogin(\"fakeitemjira00000000000001\", \"Jira\", \"https://jira.example.test\"),\n fakeLogin(\"fakeitemwifi00000000000001\", \"Office Wi-Fi\", \"https://wifi.example.test\"),\n ],\n },\n ],\n });\n const syncError = () =>\n new VaultProviderError(\n \"provider_unavailable\",\n \"1Password could not be reached (simulated sync error for ops_fake_sync_error)\",\n );\n provider = {\n ...base,\n async listItems() {\n throw syncError();\n },\n async writeItem() {\n throw syncError();\n },\n };\n }\n fakeProviders.set(token, provider);\n return provider;\n}\n\n/**\n * The provider for one stored 1Password connection credential. Checks the\n * token offline first (no request); dev fake tokens resolve to a process-wide\n * in-memory fake only when `allowFakeTokens` is set.\n */\nexport function vaultProviderForOnePasswordConnection(\n options: OnePasswordConnectionProviderOptions,\n): VaultProvider & { readonly accountName: string | null; readonly fake: boolean } {\n const token = options.token.trim();\n const description = describeOnePasswordToken(token, {\n allowFakeTokens: options.allowFakeTokens ?? false,\n });\n const provider = description.fake\n ? fakeProviderFor(token as OnePasswordFakeToken)\n : createOnePasswordVaultProvider({\n token,\n planTier: options.planTier ?? \"teams\",\n ...(options.clientCache ? { clientCache: options.clientCache } : {}),\n });\n return { ...provider, accountName: description.accountName, fake: description.fake };\n}\n\nexport function resetOnePasswordFakeProvidersForTests() {\n fakeProviders.clear();\n}\n"],"mappings":"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","names":["VaultProviderError","sdkPromise"]}
|
package/dist/provider.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type VaultProvider, type VaultProviderContext } from "./contract.js";
|
|
1
|
+
import { type ProviderVault, type VaultProvider, type VaultProviderContext, VaultProviderError } from "./contract.js";
|
|
2
2
|
import { type OnePasswordPlanTier } from "./budget.js";
|
|
3
3
|
import { type OnePasswordClientCache, type OnePasswordSdk } from "./sdk.js";
|
|
4
4
|
/** design §10.9 / VAULT_LIMITS.providerValueCacheMs */
|
|
@@ -10,6 +10,11 @@ export declare const ONEPASSWORD_GET_ALL_BATCH = 50;
|
|
|
10
10
|
* (read, reveal, item history, create, update, archive, delete).
|
|
11
11
|
*/
|
|
12
12
|
export declare const ONEPASSWORD_MANAGED_GROUP_PERMISSIONS: number;
|
|
13
|
+
/** Creation succeeded; only the subsequent sharing step failed or is unknown. */
|
|
14
|
+
export declare class OnePasswordVaultCreatedError extends VaultProviderError {
|
|
15
|
+
readonly createdVault: ProviderVault;
|
|
16
|
+
constructor(createdVault: ProviderVault, failure: VaultProviderError);
|
|
17
|
+
}
|
|
13
18
|
export type OnePasswordVaultProviderOptions = {
|
|
14
19
|
token: string;
|
|
15
20
|
planTier?: OnePasswordPlanTier;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/vaults-onepassword",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "1Password service-account provider for Opengeni vaults. Load it only through dynamic import() from the API and worker: it carries the pinned @1password/sdk WASM core.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@1password/sdk": "0.5.0",
|
|
38
|
-
"@opengeni/contracts": "3.
|
|
39
|
-
"@opengeni/vaults": "3.
|
|
38
|
+
"@opengeni/contracts": "3.2.2",
|
|
39
|
+
"@opengeni/vaults": "3.2.2"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": ">=18"
|
package/src/index.ts
CHANGED
package/src/provider.ts
CHANGED
|
@@ -41,6 +41,20 @@ export const ONEPASSWORD_GET_ALL_BATCH = 50;
|
|
|
41
41
|
*/
|
|
42
42
|
export const ONEPASSWORD_MANAGED_GROUP_PERMISSIONS = 32 | 16 | 1024 | 128 | 64 | 256 | 512;
|
|
43
43
|
|
|
44
|
+
/** Creation succeeded; only the subsequent sharing step failed or is unknown. */
|
|
45
|
+
export class OnePasswordVaultCreatedError extends VaultProviderError {
|
|
46
|
+
constructor(
|
|
47
|
+
readonly createdVault: ProviderVault,
|
|
48
|
+
failure: VaultProviderError,
|
|
49
|
+
) {
|
|
50
|
+
super(
|
|
51
|
+
failure.code,
|
|
52
|
+
"The vault was created, but its group access could not be confirmed. Do not create it again.",
|
|
53
|
+
failure.retryAfterMs,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
44
58
|
/**
|
|
45
59
|
* 1Password vault and item IDs are short lowercase alphanumerics (26 chars).
|
|
46
60
|
* Anything else cannot exist, so refuse it as not found before spending a
|
|
@@ -78,11 +92,14 @@ export type OnePasswordVaultProvider = VaultProvider & {
|
|
|
78
92
|
): Promise<void>;
|
|
79
93
|
};
|
|
80
94
|
|
|
81
|
-
type CachedItem = { at: number; item: Promise<SdkItem> };
|
|
95
|
+
type CachedItem = { at: number; epoch: string | null; item: Promise<SdkItem> };
|
|
82
96
|
|
|
83
97
|
/**
|
|
84
98
|
* Values never outlive the attempt that read them: the cache is keyed by the
|
|
85
99
|
* attempt's budget object (one per attempt or request), so it is dropped with it.
|
|
100
|
+
* Within an attempt, entries are scoped to the connection and token that read
|
|
101
|
+
* them, and to the vault's durable cache epoch: a mirror refresh in any API or
|
|
102
|
+
* worker process advances the epoch, so later reads fetch the item again.
|
|
86
103
|
*/
|
|
87
104
|
const attemptItemCaches = new WeakMap<ProviderCallBudget, Map<string, CachedItem>>();
|
|
88
105
|
|
|
@@ -138,6 +155,9 @@ export function createOnePasswordVaultProvider(
|
|
|
138
155
|
...(sdk.AuthExpiredError ? { AuthExpiredError: sdk.AuthExpiredError } : {}),
|
|
139
156
|
};
|
|
140
157
|
for (let attempt = 0; ; attempt += 1) {
|
|
158
|
+
// Set once a mutation is handed to the SDK: a failure 1Password does not
|
|
159
|
+
// classify after that may still have been applied.
|
|
160
|
+
let sent = false;
|
|
141
161
|
try {
|
|
142
162
|
const client = await clients.get(key.client, () =>
|
|
143
163
|
sdk.createClient({
|
|
@@ -146,6 +166,11 @@ export function createOnePasswordVaultProvider(
|
|
|
146
166
|
integrationVersion: options.integrationVersion ?? "1",
|
|
147
167
|
}),
|
|
148
168
|
);
|
|
169
|
+
sent =
|
|
170
|
+
op === "write" ||
|
|
171
|
+
operation === "vaultsCreate" ||
|
|
172
|
+
operation === "vaultsDelete" ||
|
|
173
|
+
operation === "grantGroupPermissions";
|
|
149
174
|
return await fn(client);
|
|
150
175
|
} catch (error) {
|
|
151
176
|
const mapped = mapOnePasswordError(error, classes);
|
|
@@ -156,6 +181,13 @@ export function createOnePasswordVaultProvider(
|
|
|
156
181
|
clients.drop(key.client);
|
|
157
182
|
}
|
|
158
183
|
if (attempt === 0 && isOnePasswordSessionError(mapped)) continue;
|
|
184
|
+
if (sent && mapped.code === "provider_unavailable") {
|
|
185
|
+
// Never reported as a plain failure that invites saving it again.
|
|
186
|
+
throw new VaultProviderError(
|
|
187
|
+
"provider_outcome_unknown",
|
|
188
|
+
"1Password did not confirm the change; it may have been applied",
|
|
189
|
+
);
|
|
190
|
+
}
|
|
159
191
|
throw mapped;
|
|
160
192
|
}
|
|
161
193
|
}
|
|
@@ -170,22 +202,40 @@ export function createOnePasswordVaultProvider(
|
|
|
170
202
|
return cache;
|
|
171
203
|
}
|
|
172
204
|
|
|
173
|
-
/**
|
|
174
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Live item read, cached per attempt for 60 s with single-flight. A changed
|
|
207
|
+
* `cacheEpoch` or `forceRefresh` reads the item again and replaces the entry.
|
|
208
|
+
*/
|
|
209
|
+
async function getItem(
|
|
210
|
+
ctx: VaultProviderContext,
|
|
211
|
+
vaultId: string,
|
|
212
|
+
itemId: string,
|
|
213
|
+
): Promise<SdkItem> {
|
|
214
|
+
const { client: clientKey } = await keys(ctx);
|
|
215
|
+
// No await between the lookup and the insert below keeps the single flight.
|
|
175
216
|
const cache = itemCache(ctx);
|
|
176
|
-
const cacheKey = `${vaultId}/${itemId}`;
|
|
217
|
+
const cacheKey = `${clientKey}|${vaultId}/${itemId}`;
|
|
218
|
+
const epoch = ctx.cacheEpoch ?? null;
|
|
177
219
|
const cached = cache.get(cacheKey);
|
|
178
|
-
if (cached && now() - cached.at < valueCacheMs)
|
|
220
|
+
if (cached && !ctx.forceRefresh && cached.epoch === epoch && now() - cached.at < valueCacheMs) {
|
|
221
|
+
return await cached.item;
|
|
222
|
+
}
|
|
179
223
|
const item = call(ctx, "read", "itemsGet", (client) => client.items.get(vaultId, itemId));
|
|
180
|
-
cache.set(cacheKey, { at: now(), item });
|
|
224
|
+
cache.set(cacheKey, { at: now(), epoch, item });
|
|
181
225
|
item.catch(() => {
|
|
182
226
|
if (cache.get(cacheKey)?.item === item) cache.delete(cacheKey);
|
|
183
227
|
});
|
|
184
|
-
return item;
|
|
228
|
+
return await item;
|
|
185
229
|
}
|
|
186
230
|
|
|
231
|
+
/** Drops the attempt's cached copies of an item, whichever connection read them. */
|
|
187
232
|
function forgetItem(ctx: VaultProviderContext, vaultId: string, itemId: string) {
|
|
188
|
-
attemptItemCaches.get(ctx.budget)
|
|
233
|
+
const cache = attemptItemCaches.get(ctx.budget);
|
|
234
|
+
if (!cache) return;
|
|
235
|
+
const suffix = `|${vaultId}/${itemId}`;
|
|
236
|
+
for (const cacheKey of [...cache.keys()]) {
|
|
237
|
+
if (cacheKey.endsWith(suffix)) cache.delete(cacheKey);
|
|
238
|
+
}
|
|
189
239
|
}
|
|
190
240
|
|
|
191
241
|
async function materialFor(
|
|
@@ -353,20 +403,28 @@ export function createOnePasswordVaultProvider(
|
|
|
353
403
|
allowAdminsAccess: input.allowAdminsAccess,
|
|
354
404
|
}),
|
|
355
405
|
);
|
|
356
|
-
|
|
357
|
-
const groupId = input.groupId;
|
|
358
|
-
await call(ctx, "admin", "grantGroupPermissions", (client) =>
|
|
359
|
-
client.vaults.grantGroupPermissions(vault.id, [
|
|
360
|
-
{ groupId, permissions: ONEPASSWORD_MANAGED_GROUP_PERMISSIONS },
|
|
361
|
-
]),
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
return {
|
|
406
|
+
const created: ProviderVault = {
|
|
365
407
|
externalVaultId: vault.id,
|
|
366
408
|
name: vault.title,
|
|
367
409
|
contentVersion: vault.contentVersion === undefined ? null : String(vault.contentVersion),
|
|
368
410
|
itemCount: typeof vault.activeItemCount === "number" ? vault.activeItemCount : 0,
|
|
369
411
|
};
|
|
412
|
+
if (input.groupId) {
|
|
413
|
+
const groupId = input.groupId;
|
|
414
|
+
try {
|
|
415
|
+
await call(ctx, "admin", "grantGroupPermissions", (client) =>
|
|
416
|
+
client.vaults.grantGroupPermissions(vault.id, [
|
|
417
|
+
{ groupId, permissions: ONEPASSWORD_MANAGED_GROUP_PERMISSIONS },
|
|
418
|
+
]),
|
|
419
|
+
);
|
|
420
|
+
} catch (error) {
|
|
421
|
+
throw new OnePasswordVaultCreatedError(
|
|
422
|
+
created,
|
|
423
|
+
error instanceof VaultProviderError ? error : mapOnePasswordError(error),
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return created;
|
|
370
428
|
},
|
|
371
429
|
|
|
372
430
|
async deleteVault(ctx, externalVaultId) {
|