{"version":3,"file":"phone-native.mjs","names":[],"sources":["../../src/internal/phone-native.ts"],"sourcesContent":["import {\n  CurrentCommitJournal,\n  type LifecycleHooks,\n  type PreparedCommit,\n  type CommitJournal,\n} from \"@yielded/auth/Hooks\";\nimport { LoginIdentifier } from \"@yielded/auth/Identity\";\nimport * as P from \"@yielded/auth/PhoneOtp\";\nimport { ProofRedemptionInput } from \"@yielded/auth/Proofs\";\nimport {\n  AuthenticationRevision,\n  AuthenticationRequirement,\n  SecurityRevision,\n  snapshotAuthenticationEvidence,\n} from \"@yielded/auth/Sessions\";\nimport * as Cause from \"effect/Cause\";\nimport * as Context from \"effect/Context\";\nimport * as Digest from \"effect/crypto/Digest\";\nimport * as SecureRandom from \"effect/crypto/SecureRandom\";\nimport * as DateTime from \"effect/DateTime\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Option from \"effect/Option\";\nimport * as Schema from \"effect/Schema\";\nimport * as SqlClient from \"effect/sql/SqlClient\";\nimport type * as Statement from \"effect/sql/Statement\";\n\nimport type { PhoneSubjectProvisioning } from \"./configuration\";\nimport { randomId } from \"./crypto\";\nimport { sqlBatchAssertion } from \"./d1-planning\";\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { AnyPhoneMapping } from \"./models/phone-model\";\nimport type { NativeSqlTables, SqlTable } from \"./native-sql-table\";\nimport { passwordEvidenceSatisfiedAt } from \"./password-policy\";\nimport { makeNativeProofStore } from \"./proof-native\";\nimport { exactSqlText, executeSqlChange } from \"./sql-change\";\nimport {\n  appendSqlBatchStatement,\n  CurrentSqlCommit,\n  makeSqlCommitExecutor,\n  registerSqlBatchPostcondition,\n  registerSqlCommitReceipt,\n  registerSqlPostcondition,\n  SqlBatchCommit,\n} from \"./sql-commit\";\n\nconst unavailable = () => P.PhoneOtpUnavailable.make({});\n\nconst invalidState = () => unavailable();\n\nconst resolve = <A>(\n  value: A | Effect.Effect<A, PersistenceMappingError>,\n): Effect.Effect<A, PersistenceMappingError> =>\n  Effect.isEffect(value) ? value : Effect.succeed(value);\n\nconst targetCodec = Schema.fromJsonString(P.PhoneLifecycleTarget);\nconst SubjectValues = Schema.Record(Schema.String, Schema.Unknown);\n\n/** Application subject preparation for the phone commit owner. The default supplies\n * no values; explicit mappings then require their own allocator and insert encoder. */\nexport class PhoneRegistrationValues extends Context.Service<\n  PhoneRegistrationValues,\n  Option.Option<PhoneSubjectProvisioning>\n>()(\"@yielded/auth-persistence/PhoneRegistrationValues\") {\n  static readonly defaultLayer = Layer.succeed(PhoneRegistrationValues, Option.none());\n}\n\nconst sameRevision = (a: AuthenticationRevision, b: AuthenticationRevision) =>\n  a.subjectId === b.subjectId &&\n  a.securityRevision === b.securityRevision &&\n  a.credentials.length === b.credentials.length &&\n  a.credentials.every((f) =>\n    b.credentials.some((g) => f.credentialId === g.credentialId && f.revision === g.revision),\n  );\n\n/** Canonical identifier rows own phone custody, including permanent retired numbers. */\nexport const makeNativePhoneServices = Effect.fnUntraced(function* (\n  tables: NativeSqlTables,\n  mapping: AnyPhoneMapping,\n): Effect.fn.Return<\n  {\n    readonly phonePersistence: P.PhonePersistence[\"Service\"];\n    readonly phoneSignInTargets: P.PhoneSignInTargets[\"Service\"];\n  },\n  P.PhoneOtpUnavailable,\n  | SqlClient.SqlClient\n  | LifecycleHooks\n  | SecureRandom.SecureRandom\n  | Digest.Digest\n  | SqlBatchCommit\n  | PhoneRegistrationValues\n> {\n  const batch = yield* SqlBatchCommit;\n  const sql = (yield* SqlClient.SqlClient).withoutTransforms();\n  const executor = yield* makeSqlCommitExecutor(unavailable);\n  const crypto = yield* SecureRandom.SecureRandom;\n  const digests = yield* Digest.Digest;\n  const external = yield* Effect.serviceOption(CurrentSqlCommit);\n  const provisioning = yield* PhoneRegistrationValues;\n\n  const s = mapping.subject,\n    i = mapping.identifier,\n    c = mapping.credential;\n\n  const registration =\n    Option.isSome(provisioning) ||\n    (mapping.subjectIds.allocate !== undefined && s.encodeInsert !== undefined);\n\n  const subject = tables(s.table),\n    identifier = tables(i.table),\n    credential = tables(c.table);\n\n  const now = tables.expression(mapping.engineNowMillis);\n\n  const activeSubject = tables.expression(s.activeCondition),\n    activeIdentifier = tables.expression(i.activeCondition),\n    activeCredential = tables.expression(c.activeCondition);\n\n  const lock = sql.onDialectOrElse({ sqlite: () => sql``, orElse: () => sql`for update` });\n\n  const exact = (t: SqlTable, key: string, value: unknown) =>\n    exactSqlText(sql, t.column(key), t.value(key, value));\n\n  const id = (t: SqlTable, key: string, value: unknown) =>\n    sql`${t.column(key)} = ${t.value(key, value)}`;\n\n  const numberKey = (number: string) =>\n    sql.and([exact(identifier, i.namespace, \"phone\"), exact(identifier, i.value, number)]);\n\n  const run = <A, E, R>(work: Effect.Effect<A, E, R>) =>\n    batch === undefined\n      ? executor.run(\n          work.pipe(\n            Effect.provideService(SecureRandom.SecureRandom, crypto),\n            Effect.provideService(Digest.Digest, digests),\n          ),\n        )\n      : executor\n          .batch(\n            work.pipe(\n              Effect.provideService(SecureRandom.SecureRandom, crypto),\n              Effect.provideService(Digest.Digest, digests),\n            ),\n          )\n          .pipe(Effect.provideService(SqlBatchCommit, batch));\n\n  const stage = Effect.fnUntraced(function* (statement: Statement.Fragment) {\n    if (batch === undefined) {\n      if (!((yield* executeSqlChange(sql, statement)) === 1)) return yield* invalidState();\n    } else {\n      yield* appendSqlBatchStatement(sql`${statement}`);\n      yield* appendSqlBatchStatement(sqlBatchAssertion(sql, sql`changes() = 1`));\n    }\n  });\n\n  const prepare = Effect.fnUntraced(function* <A>(\n    decision: P.PhoneMutationDecision,\n    project: (decision: P.PhoneMutationDecision, journal: CommitJournal) => PreparedCommit<A>,\n  ) {\n    const result = project(decision, yield* CurrentCommitJournal);\n\n    yield* registerSqlCommitReceipt(result);\n\n    return result;\n  });\n\n  const capture = Effect.fnUntraced(function* (\n    input: Parameters<P.PhonePersistence[\"Service\"][\"target\"]>[0],\n  ) {\n    if (!(input.moduleId === mapping.moduleId)) return yield* invalidState();\n\n    const numbers =\n      input.sourcePhoneNumber === undefined || input.sourcePhoneNumber === input.phoneNumber\n        ? [input.phoneNumber]\n        : [input.phoneNumber, input.sourcePhoneNumber];\n\n    const rows =\n      yield* sql`select ${identifier.fields(\"phone_identifier_\")}, case when ${activeIdentifier} then 1 else 0 end as identifier_active from ${identifier.name} where ${sql.or(numbers.map(numberKey))} limit 3`;\n\n    if (!(rows.length <= numbers.length)) return yield* invalidState();\n\n    const identifiers = rows.map((row) => ({\n      row: identifier.decode(row, \"phone_identifier_\"),\n      active: Number(row.identifier_active) === 1,\n    }));\n\n    if (\n      !identifiers.every(\n        ({ row }) => row[i.namespace] === \"phone\" && numbers.includes(String(row[i.value])),\n      )\n    )\n      return yield* invalidState();\n    const destination = identifiers.find(({ row }) => row[i.value] === input.phoneNumber);\n    const source = identifiers.find(({ row }) => row[i.value] === input.sourcePhoneNumber);\n\n    const subjectId =\n      input.subjectId ??\n      (destination === undefined\n        ? undefined\n        : yield* resolve(mapping.subjectIds.toSubject(destination.row[i.subjectId])));\n\n    let subjectRow: Record<string, unknown> | undefined;\n    let revision: AuthenticationRevision | null = null;\n    const factors: { readonly row: Record<string, unknown>; readonly active: boolean }[] = [];\n    let instant: number;\n\n    if (subjectId === undefined) {\n      const clock = yield* sql`select ${now} as engine_now`;\n\n      instant = Number(clock[0]?.engine_now);\n    } else {\n      const native = yield* resolve(mapping.subjectIds.toNative(subjectId));\n\n      if (!((yield* resolve(mapping.subjectIds.toSubject(native))) === subjectId))\n        return yield* invalidState();\n\n      const joined =\n        yield* sql`select ${subject.fields(\"phone_subject_\")}, ${credential.fields(\"phone_factor_\")}, case when ${activeSubject} then 1 else 0 end as subject_active, case when ${activeCredential} then 1 else 0 end as credential_active, ${now} as engine_now from ${subject.name} left join ${credential.name} on ${id(credential, c.subjectId, native)} and (${activeCredential} ${identifiers.length === 0 ? sql`` : sql`or ${sql.or(identifiers.map((value) => exact(credential, c.id, value.row[i.credentialId])))}`}) where ${id(subject, s.id, native)} limit 67`;\n\n      if (!(joined.length <= 66)) return yield* invalidState();\n      const first = joined[0];\n\n      instant = Number(first?.engine_now);\n      if (first !== undefined) {\n        subjectRow = subject.decode(first, \"phone_subject_\");\n        if (!((yield* resolve(mapping.subjectIds.toSubject(subjectRow[s.id]))) === subjectId))\n          return yield* invalidState();\n        for (const joinedRow of joined) {\n          const row = credential.decode(joinedRow, \"phone_factor_\");\n\n          if (row[c.id] === null || row[c.id] === undefined) continue;\n          if (!((yield* resolve(mapping.subjectIds.toSubject(row[c.subjectId]))) === subjectId))\n            return yield* invalidState();\n          if (factors.some((f) => f.row[c.id] === row[c.id])) return yield* invalidState();\n          factors.push({ row, active: Number(joinedRow.credential_active) === 1 });\n        }\n        if (!(factors.filter((f) => f.active).length <= 64)) return yield* invalidState();\n        if (Number(first.subject_active) === 1)\n          revision = yield* Schema.decodeUnknownEffect(AuthenticationRevision)({\n            subjectId,\n            securityRevision: subjectRow[s.securityRevision],\n            credentials: factors\n              .filter((f) => f.active)\n              .map((f) => ({ credentialId: f.row[c.id], revision: f.row[c.revision] }))\n              .sort((a, b) => String(a.credentialId).localeCompare(String(b.credentialId))),\n          });\n      }\n    }\n    if (!Number.isSafeInteger(instant)) return yield* invalidState();\n\n    const custody = Effect.fnUntraced(function* (value: typeof destination) {\n      if (value === undefined || value.row[i.moduleId] !== mapping.moduleId) return null;\n      const factor = factors.find((f) => f.row[c.id] === value.row[i.credentialId]);\n\n      if (factor === undefined) return null;\n      const owner = yield* resolve(mapping.subjectIds.toSubject(value.row[i.subjectId]));\n\n      if (owner !== subjectId) return null;\n\n      return yield* Schema.decodeUnknownEffect(P.PhoneCustody)({\n        phoneNumber: value.row[i.value],\n        subjectId: owner,\n        credentialId: value.row[i.credentialId],\n        custodyRevision: value.row[i.revision],\n        credentialRevision: factor.row[c.revision],\n        verifiedAtMillis:\n          value.row[i.verifiedAt] === null || value.row[i.verifiedAt] === undefined\n            ? null\n            : mapping.proofs.clock.decodeInstant(value.row[i.verifiedAt]),\n        state:\n          !value.active || !factor.active\n            ? \"retired\"\n            : value.row[i.verifiedAt] === null || value.row[i.verifiedAt] === undefined\n              ? \"unverified\"\n              : \"verified\",\n      });\n    });\n\n    const targetCustody = yield* custody(destination);\n    const sourceCustody = yield* custody(source);\n\n    const eligible =\n      input.action === \"register\"\n        ? registration && destination === undefined\n        : revision !== null &&\n          input.subjectId === subjectId &&\n          (destination === undefined ||\n            (targetCustody !== null &&\n              targetCustody.subjectId === subjectId &&\n              targetCustody.state === \"unverified\")) &&\n          (input.action !== \"change\" ||\n            (input.sourcePhoneNumber !== input.phoneNumber &&\n              sourceCustody !== null &&\n              sourceCustody.subjectId === subjectId &&\n              sourceCustody.state === \"verified\"));\n\n    const target = yield* Schema.decodeEffect(P.PhoneLifecycleTarget)({\n      phoneNumber: input.phoneNumber,\n      custody: targetCustody,\n      source: sourceCustody,\n      revision,\n      eligible,\n    });\n\n    return { target, subjectRow, destination, source, factors, now: instant };\n  });\n\n  const phoneSignInTargets: P.PhoneSignInTargets[\"Service\"] = {\n    lookup: (input) =>\n      executor.read(\n        Effect.gen(function* () {\n          const current = yield* capture({ ...input, action: \"verify\" });\n          const { custody, revision } = current.target;\n\n          if (\n            custody === null ||\n            custody.state !== \"verified\" ||\n            custody.verifiedAtMillis === null ||\n            revision === null ||\n            current.subjectRow === undefined ||\n            !revision.credentials.some(\n              (f) =>\n                f.credentialId === custody.credentialId &&\n                f.revision === custody.credentialRevision,\n            )\n          )\n            return Option.none();\n\n          return Option.some(\n            yield* Schema.decodeEffect(P.PhoneCredentialSnapshot)({\n              moduleId: input.moduleId,\n              phoneNumber: input.phoneNumber,\n              custodyRevision: custody.custodyRevision,\n              verifiedAtMillis: custody.verifiedAtMillis,\n              credentialId: custody.credentialId,\n              credentialRevision: custody.credentialRevision,\n              revision,\n              requirement: yield* resolve(mapping.subject.decodeRequirement(current.subjectRow)),\n            }),\n          );\n        }),\n      ),\n  };\n\n  const phonePersistence: P.PhonePersistence[\"Service\"] = {\n    target: (input) => executor.read(Effect.map(capture({ ...input }), (value) => value.target)),\n    mutate: (original, project) =>\n      run(\n        Effect.gen(function* () {\n          const target = yield* Schema.decodeEffect(targetCodec)(\n            yield* Schema.encodeEffect(targetCodec)(original.target),\n          );\n\n          const redemption = yield* Schema.decodeEffect(Schema.toCodecIso(ProofRedemptionInput))(\n            yield* Schema.encodeEffect(Schema.toCodecIso(ProofRedemptionInput))(\n              original.redemption.input,\n            ),\n          );\n\n          const input = {\n            ...original,\n            target,\n            redemption: { input: redemption, prepare: original.redemption.prepare },\n          };\n\n          const rejected = () => prepare({ _tag: \"Rejected\" }, project);\n\n          if (!(input.moduleId === mapping.moduleId)) return yield* invalidState();\n          if (input.action === \"register\" && !registration) return yield* rejected();\n          const policy = yield* Schema.decodeEffect(P.PhoneLifecyclePolicy)(input.policy);\n\n          if (\n            policy.maximumEvidenceAgeMillis !== mapping.policy.maximumEvidenceAgeMillis ||\n            policy.requireImmediateInvalidation !== mapping.policy.requireImmediateInvalidation\n          )\n            return yield* rejected();\n          if (target.revision !== null) {\n            const native = yield* resolve(mapping.subjectIds.toNative(target.revision.subjectId));\n\n            const rows =\n              yield* sql`select ${subject.fields(\"phone_locked_\")} from ${subject.name} where ${id(subject, s.id, native)} limit 2 ${batch === undefined ? lock : sql``}`;\n\n            if (\n              rows.length !== 1 ||\n              (yield* resolve(\n                mapping.subjectIds.toSubject(subject.decode(rows[0]!, \"phone_locked_\")[s.id]),\n              )) !== target.revision.subjectId\n            )\n              return yield* rejected();\n          }\n\n          const captured = yield* capture({\n            moduleId: input.moduleId,\n            action: input.action,\n            phoneNumber: target.phoneNumber,\n            ...(target.revision === null ? {} : { subjectId: target.revision.subjectId }),\n            ...(target.source === null ? {} : { sourcePhoneNumber: target.source.phoneNumber }),\n          });\n\n          if (\n            !captured.target.eligible ||\n            (yield* Schema.encodeEffect(targetCodec)(captured.target)) !==\n              (yield* Schema.encodeEffect(targetCodec)(target))\n          )\n            return yield* rejected();\n          const binding = redemption.binding;\n\n          if (\n            redemption.moduleId !== `${mapping.moduleId}/lifecycle` ||\n            redemption.purpose !== \"phone-lifecycle\" ||\n            binding.identifier.namespace !== \"phone\" ||\n            binding.identifier.value !== target.phoneNumber\n          )\n            return yield* rejected();\n          if (\n            input.action === \"register\"\n              ? binding._tag !== \"Identifier\"\n              : binding._tag === \"Identifier\" ||\n                target.revision === null ||\n                !sameRevision(binding.revision, target.revision)\n          )\n            return yield* rejected();\n          if (\n            (input.action === \"verify\" && binding._tag !== \"Subject\") ||\n            (input.action === \"change\" && binding._tag !== \"IdentifierChange\")\n          )\n            return yield* rejected();\n          const freshness: Statement.Fragment[] = [];\n\n          if (input.action !== \"register\") {\n            const authorization = input.authorization;\n\n            if (\n              authorization === undefined ||\n              target.revision === null ||\n              captured.subjectRow === undefined\n            )\n              return yield* rejected();\n            const evidence = yield* snapshotAuthenticationEvidence(authorization.evidence);\n            const challenge = authorization.challenge;\n\n            if (\n              challenge.moduleId !== mapping.moduleId ||\n              challenge.action !== input.action ||\n              challenge.commandId !== input.commandId ||\n              challenge.phoneNumber !== target.phoneNumber ||\n              challenge.sourcePhoneNumber !== target.source?.phoneNumber ||\n              challenge.flowId !== binding.flowId ||\n              challenge.bindingDigest !== binding.contextDigest ||\n              challenge.flowId !== evidence.flowId ||\n              challenge.bindingDigest !== evidence.bindingDigest ||\n              !sameRevision(challenge.revision, target.revision) ||\n              !sameRevision(evidence.revision, target.revision)\n            )\n              return yield* rejected();\n\n            const requirements = [\n              authorization.requirement,\n              authorization.actionRequirement,\n              yield* resolve(s.decodeRequirement(captured.subjectRow)),\n              ...(s.decodeActionRequirement === undefined\n                ? []\n                : [yield* resolve(s.decodeActionRequirement(captured.subjectRow, input.action))]),\n            ];\n\n            for (const originalRequirement of requirements) {\n              const requirement =\n                yield* Schema.decodeEffect(AuthenticationRequirement)(originalRequirement);\n\n              if (!(yield* passwordEvidenceSatisfiedAt(evidence, requirement, captured.now)))\n                return yield* rejected();\n            }\n            if (evidence.proofs.length === 0) return yield* rejected();\n            for (const proof of evidence.proofs) {\n              const at = DateTime.toEpochMillis(proof.verifiedAt);\n\n              const age = Math.min(\n                policy.maximumEvidenceAgeMillis,\n                ...requirements.map((r) => r.maximumAgeMillis),\n              );\n\n              if (\n                !target.revision.credentials.some((f) => f.credentialId === proof.credentialId) ||\n                at > captured.now ||\n                captured.now >= at + age\n              )\n                return yield* rejected();\n              freshness.push(sql`${now} >= ${at} and ${now} < ${at + age}`);\n            }\n          }\n          const store = yield* makeNativeProofStore(tables, mapping.proofs, batch !== undefined);\n          const result = yield* store.redeemLocked(redemption);\n\n          const proofReceipt = input.redemption.prepare(\n            result.decision,\n            yield* CurrentCommitJournal,\n            (value) => value,\n          );\n\n          yield* registerSqlCommitReceipt(proofReceipt);\n          if (result.decision !== \"redeemed\") return yield* rejected();\n          freshness.push(result.validUntil);\n\n          const preparedSubject =\n            input.action === \"register\" && Option.isSome(provisioning)\n              ? yield* provisioning.value\n                  .values({\n                    requestId: `phone-registration:${mapping.moduleId}:${redemption.proofId}`,\n                    identifier: LoginIdentifier.make({\n                      namespace: \"phone\",\n                      value: target.phoneNumber,\n                    }),\n                  })\n                  .pipe(Effect.flatMap(Schema.decodeUnknownEffect(SubjectValues)))\n              : undefined;\n\n          const subjectId =\n            input.action === \"register\"\n              ? yield* resolve(\n                  mapping.subjectIds.toSubject(\n                    preparedSubject === undefined\n                      ? yield* resolve(mapping.subjectIds.allocate!())\n                      : preparedSubject[s.id],\n                  ),\n                )\n              : target.revision!.subjectId;\n\n          const native = yield* resolve(mapping.subjectIds.toNative(subjectId));\n\n          if (!((yield* resolve(mapping.subjectIds.toSubject(native))) === subjectId))\n            return yield* invalidState();\n\n          const securityRevision =\n              preparedSubject === undefined\n                ? SecurityRevision.make(yield* randomId)\n                : yield* Schema.decodeUnknownEffect(SecurityRevision)(\n                    preparedSubject[s.securityRevision],\n                  ),\n            credentialRevision = SecurityRevision.make(yield* randomId),\n            custodyRevision = SecurityRevision.make(yield* randomId);\n\n          const credentialId = target.custody?.credentialId ?? (yield* randomId);\n\n          const factorCondition = (revision: AuthenticationRevision) =>\n            sql.and([\n              sql`(select count(*) from ${credential.name} where ${id(credential, c.subjectId, native)} and ${activeCredential}) = ${revision.credentials.length}`,\n              ...revision.credentials.map(\n                (f) =>\n                  sql`exists(select 1 from ${credential.name} where ${id(credential, c.subjectId, native)} and ${exact(credential, c.id, f.credentialId)} and ${exact(credential, c.revision, f.revision)} and ${activeCredential})`,\n              ),\n            ]);\n\n          if (target.revision !== null && batch !== undefined)\n            yield* appendSqlBatchStatement(\n              sqlBatchAssertion(\n                sql,\n                sql.and([\n                  sql`exists(select 1 from ${subject.name} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, target.revision.securityRevision)} and ${activeSubject})`,\n                  factorCondition(target.revision),\n                  ...freshness,\n                ]),\n              ),\n            );\n          let subjectRow = captured.subjectRow;\n\n          if (input.action === \"register\") {\n            const inserted =\n              preparedSubject ??\n              s.encodeInsert!({\n                id: native,\n                securityRevision,\n                phoneNumber: target.phoneNumber,\n              });\n\n            yield* stage(subject.insert(inserted));\n            // Native provisioning decodes database defaults in the final guarded\n            // read; fixed batches require complete encoder values.\n            subjectRow = inserted;\n          }\n          if (!(subjectRow !== undefined)) return yield* invalidState();\n          const finalConditions: Statement.Fragment[] = [...freshness];\n\n          if (target.source !== null) {\n            const source = target.source;\n\n            const retiredCustody = SecurityRevision.make(yield* randomId),\n              retiredCredential = SecurityRevision.make(yield* randomId);\n\n            yield* stage(\n              sql`${identifier.update({ [i.status]: i.encodeStatus(false), [i.revision]: retiredCustody })} where ${numberKey(source.phoneNumber)} and ${exact(identifier, i.moduleId, mapping.moduleId)} and ${exact(identifier, i.credentialId, source.credentialId)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.revision, source.custodyRevision)} and ${activeIdentifier}`,\n            );\n            yield* stage(\n              sql`${credential.update({ [c.status]: c.encodeStatus(false), [c.revision]: retiredCredential })} where ${id(credential, c.subjectId, native)} and ${exact(credential, c.id, source.credentialId)} and ${exact(credential, c.revision, source.credentialRevision)} and ${activeCredential}`,\n            );\n            finalConditions.push(\n              sql`exists(select 1 from ${identifier.name} where ${numberKey(source.phoneNumber)} and ${exact(identifier, i.moduleId, mapping.moduleId)} and ${exact(identifier, i.credentialId, source.credentialId)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.revision, retiredCustody)} and not (${activeIdentifier}))`,\n              sql`exists(select 1 from ${credential.name} where ${id(credential, c.subjectId, native)} and ${exact(credential, c.id, source.credentialId)} and ${exact(credential, c.revision, retiredCredential)} and not (${activeCredential}))`,\n            );\n          }\n\n          const values = {\n            [i.moduleId]: mapping.moduleId,\n            [i.credentialId]: credentialId,\n            [i.namespace]: \"phone\",\n            [i.value]: target.phoneNumber,\n            [i.subjectId]: native,\n            [i.revision]: custodyRevision,\n            [i.verifiedAt]: mapping.encodeInstant(captured.now),\n            [i.status]: i.encodeStatus(true),\n          };\n\n          if (target.custody === null) {\n            yield* stage(\n              identifier.insert({\n                ...i.encodeInsert({\n                  moduleId: mapping.moduleId,\n                  credentialId,\n                  phoneNumber: target.phoneNumber,\n                  subjectId: native,\n                  revision: custodyRevision,\n                  verifiedAtMillis: captured.now,\n                  active: true,\n                }),\n                ...values,\n              }),\n            );\n            yield* stage(\n              credential.insert(\n                c.encodeInsert({\n                  credentialId,\n                  subjectId: native,\n                  revision: credentialRevision,\n                  active: true,\n                }),\n              ),\n            );\n          } else {\n            yield* stage(\n              sql`${identifier.update(values)} where ${numberKey(target.phoneNumber)} and ${exact(identifier, i.moduleId, mapping.moduleId)} and ${exact(identifier, i.credentialId, credentialId)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.revision, target.custody.custodyRevision)} and ${identifier.column(i.verifiedAt)} is null and ${activeIdentifier}`,\n            );\n            yield* stage(\n              sql`${credential.update({ [c.revision]: credentialRevision, [c.status]: c.encodeStatus(true) })} where ${id(credential, c.subjectId, native)} and ${exact(credential, c.id, credentialId)} and ${exact(credential, c.revision, target.custody.credentialRevision)} and ${activeCredential}`,\n            );\n          }\n\n          const revision = yield* Schema.decodeEffect(AuthenticationRevision)({\n            subjectId,\n            securityRevision,\n            credentials: [\n              ...(target.revision?.credentials ?? []).filter(\n                (f) =>\n                  f.credentialId !== credentialId && f.credentialId !== target.source?.credentialId,\n              ),\n              { credentialId, revision: credentialRevision },\n            ].sort((a, b) => a.credentialId.localeCompare(b.credentialId)),\n          });\n\n          finalConditions.push(\n            factorCondition(revision),\n            sql`exists(select 1 from ${identifier.name} where ${numberKey(target.phoneNumber)} and ${exact(identifier, i.moduleId, mapping.moduleId)} and ${exact(identifier, i.credentialId, credentialId)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.revision, custodyRevision)} and ${id(identifier, i.verifiedAt, mapping.encodeInstant(captured.now))} and ${activeIdentifier})`,\n          );\n          const resultingState = sql.and(finalConditions);\n\n          if (input.action !== \"register\") {\n            if (!(target.revision !== null)) return yield* invalidState();\n            yield* stage(\n              sql`${subject.update({ [s.securityRevision]: securityRevision })} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, target.revision.securityRevision)} and ${activeSubject} and ${resultingState}`,\n            );\n            subjectRow = { ...subjectRow, [s.securityRevision]: securityRevision };\n          }\n          finalConditions.push(\n            sql`exists(select 1 from ${subject.name} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, securityRevision)} and ${activeSubject})`,\n          );\n          if (input.action === \"register\" && batch === undefined) {\n            const rows =\n              yield* sql`select ${subject.fields(\"provisioned_\")} from ${subject.name} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, securityRevision)} and ${activeSubject} and ${resultingState} limit 2`;\n\n            if (!(rows.length === 1)) return yield* invalidState();\n            subjectRow = subject.decode(rows[0]!, \"provisioned_\");\n          }\n          const final = sql.and(finalConditions);\n\n          if (batch !== undefined)\n            yield* registerSqlBatchPostcondition({\n              name: \"phone-custody-authority\",\n              statement: sqlBatchAssertion(sql, final),\n            });\n          else if (Option.isSome(external))\n            yield* registerSqlPostcondition({\n              name: \"phone-custody-authority\",\n              check: Effect.gen(function* () {\n                const rows = yield* sql`select 1 as valid where ${final}`;\n\n                if (!(rows.length === 1)) return yield* invalidState();\n              }).pipe(\n                Effect.catchCause((cause) =>\n                  Effect.failCause(\n                    Cause.map(cause, (error) =>\n                      PersistenceMappingError.make({ operation: \"decode\", cause: error }),\n                    ),\n                  ),\n                ),\n              ),\n            });\n\n          return yield* prepare(\n            {\n              _tag: \"Accepted\",\n              credential: {\n                moduleId: mapping.moduleId,\n                phoneNumber: target.phoneNumber,\n                custodyRevision,\n                verifiedAtMillis: captured.now,\n                credentialId,\n                credentialRevision,\n                revision,\n                requirement: yield* resolve(mapping.subject.decodeRequirement(subjectRow)),\n              },\n            },\n            project,\n          );\n        }),\n      ),\n  };\n\n  return { phonePersistence, phoneSignInTargets };\n});\n"],"mappings":"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"}