(
input: MintOAuthConnectionInput,
)
| 4392 | // existing name), this path upserts on purpose: reconnect/refresh re-mints |
| 4393 | // the SAME connection, stamping the OAuth columns. |
| 4394 | const mintOAuthConnection = ( |
| 4395 | input: MintOAuthConnectionInput, |
| 4396 | ): Effect.Effect<Connection, StorageFailure> => |
| 4397 | Effect.gen(function* () { |
| 4398 | const name = connectionIdentifier(String(input.name)); |
| 4399 | yield* requireUserSubject(input.owner); |
| 4400 | const integrationRow = yield* findIntegrationRow(input.integration); |
| 4401 | if (!integrationRow) { |
| 4402 | return yield* new StorageError({ |
| 4403 | message: `Integration not found: ${input.integration}`, |
| 4404 | cause: undefined, |
| 4405 | }); |
| 4406 | } |
| 4407 | const keys = yield* Effect.try({ |
| 4408 | try: () => ownedKeys(input.owner), |
| 4409 | catch: (cause) => storageFailureFromUnknown("invalid owner", cause), |
| 4410 | }); |
| 4411 | const now = new Date(); |
| 4412 | const ref: ConnectionRef = { |
| 4413 | owner: input.owner, |
| 4414 | integration: input.integration, |
| 4415 | name, |
| 4416 | }; |
| 4417 | // Label precedence: an explicit (user-chosen) label always wins; a |
| 4418 | // derived label (OIDC claims) only FILLS an empty slot. Like |
| 4419 | // `description` below, a reconnect or token refresh must not erase a |
| 4420 | // label the user curated. Resolved once, used by every write below. |
| 4421 | let identityLabel: string | null = null; |
| 4422 | // The core-owned per-connection state this mint writes WHOLESALE: |
| 4423 | // whatever a previous grant recorded (a stale reauth verdict, an old |
| 4424 | // missing-scope set) describes a credential that no longer exists. |
| 4425 | const nextProviderState = { |
| 4426 | ...(input.missingOAuthScopes === undefined || input.missingOAuthScopes.length === 0 |
| 4427 | ? {} |
| 4428 | : { missingOAuthScopes: input.missingOAuthScopes }), |
| 4429 | ...(input.enterpriseManaged === undefined |
| 4430 | ? {} |
| 4431 | : { |
| 4432 | [ENTERPRISE_MANAGED_PROVIDER_STATE_KEY]: input.enterpriseManaged, |
| 4433 | }), |
| 4434 | }; |
| 4435 | // Null, not `{}`, when this grant records nothing: an empty object would |
| 4436 | // read back as "state exists and is empty" on a column whose absence is |
| 4437 | // what every reader tests. |
| 4438 | const providerState = |
| 4439 | Object.keys(nextProviderState).length === 0 ? null : nextProviderState; |
| 4440 | const credentialProvider = credentialProviders.get(input.provider); |
| 4441 | const credentialSet = credentialProvider?.set; |
| 4442 | if (!credentialProvider || !credentialSet) { |
| 4443 | return yield* new StorageError({ |
| 4444 | message: `Credential provider ${input.provider} is not registered as writable.`, |
| 4445 | cause: undefined, |
| 4446 | }); |
| 4447 | } |
| 4448 | const credentialAttemptId = crypto.randomUUID(); |
| 4449 | const credentialWrite = makeCredentialWriteAttempt( |
| 4450 | credentialWriteRuntimeId, |
| 4451 | credentialAttemptId, |
no test coverage detected