@yielded/auth-persistence-drizzle 0.1.0-beta.17 → 0.1.0-beta.19

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.
Files changed (142) hide show
  1. package/README.md +8 -1
  2. package/dist/D1.d.mts +120 -120
  3. package/dist/Libsql.d.mts +154 -154
  4. package/dist/Mysql2.d.mts +166 -166
  5. package/dist/Pglite.d.mts +166 -166
  6. package/dist/Postgres.d.mts +152 -152
  7. package/dist/SqliteBun.d.mts +168 -168
  8. package/dist/SqliteDo.d.mts +237 -259
  9. package/dist/SqliteDo.mjs +30 -45
  10. package/dist/SqliteDo.mjs.map +1 -1
  11. package/dist/SqliteNode.d.mts +154 -154
  12. package/dist/SqliteWasm.d.mts +163 -163
  13. package/dist/drizzle/crypto.mjs +11 -0
  14. package/dist/drizzle/crypto.mjs.map +1 -0
  15. package/dist/drizzle/d1-identity.mjs +2 -2
  16. package/dist/drizzle/d1-identity.mjs.map +1 -1
  17. package/dist/drizzle/d1-oauth.d.mts +16 -16
  18. package/dist/drizzle/d1-oauth.mjs.map +1 -1
  19. package/dist/drizzle/d1-passkey.d.mts +6 -6
  20. package/dist/drizzle/d1-passkey.mjs.map +1 -1
  21. package/dist/drizzle/d1-password-prepared.mjs +3 -3
  22. package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
  23. package/dist/drizzle/d1-passwords.d.mts +1 -1
  24. package/dist/drizzle/d1-passwords.mjs +1 -1
  25. package/dist/drizzle/d1-passwords.mjs.map +1 -1
  26. package/dist/drizzle/d1-phone.d.mts +3 -3
  27. package/dist/drizzle/d1-phone.mjs.map +1 -1
  28. package/dist/drizzle/d1-proofs.d.mts +1 -1
  29. package/dist/drizzle/d1-sessions.d.mts +1 -1
  30. package/dist/drizzle/d1-sessions.mjs +4 -3
  31. package/dist/drizzle/d1-sessions.mjs.map +1 -1
  32. package/dist/drizzle/d1-totp.d.mts +3 -3
  33. package/dist/drizzle/d1-totp.mjs.map +1 -1
  34. package/dist/drizzle/mysql-identity.mjs +2 -2
  35. package/dist/drizzle/mysql-identity.mjs.map +1 -1
  36. package/dist/drizzle/oauth-accounts.mjs +9 -8
  37. package/dist/drizzle/oauth-accounts.mjs.map +1 -1
  38. package/dist/drizzle/oauth-connected-collection.mjs +1 -1
  39. package/dist/drizzle/oauth-connected-collection.mjs.map +1 -1
  40. package/dist/drizzle/oauth-connected-custody.mjs +5 -4
  41. package/dist/drizzle/oauth-connected-custody.mjs.map +1 -1
  42. package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
  43. package/dist/drizzle/oauth-connected-flow.mjs +8 -7
  44. package/dist/drizzle/oauth-connected-flow.mjs.map +1 -1
  45. package/dist/drizzle/oauth-connected-management.mjs +3 -2
  46. package/dist/drizzle/oauth-connected-management.mjs.map +1 -1
  47. package/dist/drizzle/oauth-connected-reference.mjs +8 -4
  48. package/dist/drizzle/oauth-connected-reference.mjs.map +1 -1
  49. package/dist/drizzle/oauth-connected-settlement.mjs +4 -4
  50. package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -1
  51. package/dist/drizzle/oauth-connected-sign-in.mjs +11 -10
  52. package/dist/drizzle/oauth-connected-sign-in.mjs.map +1 -1
  53. package/dist/drizzle/oauth-connected-state.d.mts +265 -265
  54. package/dist/drizzle/oauth-connected-state.mjs +23 -20
  55. package/dist/drizzle/oauth-connected-state.mjs.map +1 -1
  56. package/dist/drizzle/oauth-connected-target.d.mts +105 -105
  57. package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
  58. package/dist/drizzle/oauth-drivers.mjs.map +1 -1
  59. package/dist/drizzle/oauth-flow.mjs +1 -1
  60. package/dist/drizzle/oauth-flow.mjs.map +1 -1
  61. package/dist/drizzle/oauth-model.d.mts +4 -4
  62. package/dist/drizzle/oauth-model.mjs.map +1 -1
  63. package/dist/drizzle/oauth-registration.mjs +2 -2
  64. package/dist/drizzle/oauth-registration.mjs.map +1 -1
  65. package/dist/drizzle/oauth-state.mjs +11 -12
  66. package/dist/drizzle/oauth-state.mjs.map +1 -1
  67. package/dist/drizzle/oauth-target.d.mts +4 -4
  68. package/dist/drizzle/oauth-target.mjs.map +1 -1
  69. package/dist/drizzle/passkey-drivers.mjs.map +1 -1
  70. package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
  71. package/dist/drizzle/passkey-write-target.d.mts +1 -1
  72. package/dist/drizzle/password-prepared-sql.mjs +1 -1
  73. package/dist/drizzle/password-prepared-sql.mjs.map +1 -1
  74. package/dist/drizzle/password-prepared-state.mjs +1 -1
  75. package/dist/drizzle/pg-identity.mjs +2 -2
  76. package/dist/drizzle/pg-identity.mjs.map +1 -1
  77. package/dist/drizzle/phone-model.d.mts +2 -2
  78. package/dist/drizzle/phone-model.mjs +3 -3
  79. package/dist/drizzle/phone-model.mjs.map +1 -1
  80. package/dist/drizzle/phone-target.d.mts +1 -1
  81. package/dist/drizzle/phone-target.mjs +2 -2
  82. package/dist/drizzle/phone-target.mjs.map +1 -1
  83. package/dist/drizzle/sqlite-do-database.d.mts +29 -0
  84. package/dist/drizzle/sqlite-do-database.mjs +45 -0
  85. package/dist/drizzle/sqlite-do-database.mjs.map +1 -0
  86. package/dist/drizzle/sqlite-emails.mjs.map +1 -1
  87. package/dist/drizzle/sqlite-identity.mjs +2 -2
  88. package/dist/drizzle/sqlite-identity.mjs.map +1 -1
  89. package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
  90. package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
  91. package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
  92. package/dist/drizzle/storage-validation.mjs +17 -9
  93. package/dist/drizzle/storage-validation.mjs.map +1 -1
  94. package/dist/drizzle/totp-state.mjs +8 -8
  95. package/dist/drizzle/totp-state.mjs.map +1 -1
  96. package/dist/drizzle/totp-target.d.mts +1 -1
  97. package/dist/drizzle/totp-target.mjs +2 -2
  98. package/dist/drizzle/totp-target.mjs.map +1 -1
  99. package/package.json +1 -1
  100. package/src/SqliteDo.ts +63 -70
  101. package/src/drizzle/crypto.ts +14 -0
  102. package/src/drizzle/d1-identity.ts +2 -2
  103. package/src/drizzle/d1-oauth.ts +14 -5
  104. package/src/drizzle/d1-passkey.ts +5 -1
  105. package/src/drizzle/d1-password-prepared.ts +11 -5
  106. package/src/drizzle/d1-passwords.ts +1 -1
  107. package/src/drizzle/d1-phone.ts +2 -1
  108. package/src/drizzle/d1-sessions.ts +8 -2
  109. package/src/drizzle/d1-totp.ts +6 -2
  110. package/src/drizzle/mysql-identity.ts +2 -2
  111. package/src/drizzle/oauth-accounts.ts +14 -13
  112. package/src/drizzle/oauth-connected-collection.ts +1 -1
  113. package/src/drizzle/oauth-connected-custody.ts +8 -6
  114. package/src/drizzle/oauth-connected-drivers.ts +9 -3
  115. package/src/drizzle/oauth-connected-flow.ts +6 -6
  116. package/src/drizzle/oauth-connected-management.ts +1 -1
  117. package/src/drizzle/oauth-connected-reference.ts +14 -9
  118. package/src/drizzle/oauth-connected-settlement.ts +4 -4
  119. package/src/drizzle/oauth-connected-sign-in.ts +11 -10
  120. package/src/drizzle/oauth-connected-state.ts +40 -25
  121. package/src/drizzle/oauth-connected-target.ts +9 -5
  122. package/src/drizzle/oauth-drivers.ts +13 -5
  123. package/src/drizzle/oauth-flow.ts +1 -1
  124. package/src/drizzle/oauth-model.ts +4 -4
  125. package/src/drizzle/oauth-registration.ts +2 -2
  126. package/src/drizzle/oauth-state.ts +17 -15
  127. package/src/drizzle/oauth-target.ts +11 -3
  128. package/src/drizzle/passkey-drivers.ts +7 -3
  129. package/src/drizzle/passkey-write-drivers.ts +11 -2
  130. package/src/drizzle/password-prepared-sql.ts +1 -1
  131. package/src/drizzle/pg-identity.ts +2 -2
  132. package/src/drizzle/phone-model.ts +3 -3
  133. package/src/drizzle/phone-target.ts +11 -4
  134. package/src/drizzle/sqlite-do-database.ts +87 -0
  135. package/src/drizzle/sqlite-emails.ts +1 -1
  136. package/src/drizzle/sqlite-identity.ts +2 -2
  137. package/src/drizzle/sqlite-passwords.ts +1 -1
  138. package/src/drizzle/sqlite-proofs.ts +2 -2
  139. package/src/drizzle/sqlite-sessions.ts +2 -2
  140. package/src/drizzle/storage-validation.ts +15 -6
  141. package/src/drizzle/totp-state.ts +8 -8
  142. package/src/drizzle/totp-target.ts +11 -5
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-connected-settlement.mjs","names":["clientKey","S.clientKey","cohortKey","S.cohortKey","S.nativeCopy","C.summary","S.retainedUntil","S.current","S.action","F.expected","S.client","S.configuration","F.exact","F.terminal","F.readTuple","S.cohort","S.readGrant","F.sameTarget","C.noFormerOwner","S.orderNumber","F.acquireTuple","C.fence","C.storeJob"],"sources":["../../src/drizzle/oauth-connected-settlement.ts"],"sourcesContent":["import * as M from \"@yielded/auth/OAuth\";\nimport { snapshotOAuthSync } from \"@yielded/auth/OAuth\";\nimport { ne, sql } from \"drizzle-orm\";\nimport { Effect } from \"effect\";\n\nimport * as C from \"./oauth-connected-custody\";\nimport * as F from \"./oauth-connected-flow\";\nimport * as S from \"./oauth-connected-state\";\nimport { both, col, equal, CurrentOAuthTransaction } from \"./oauth-owner\";\nimport { invariant, sameIdentity, oauthIdentityKey } from \"./oauth-state\";\n\nexport const validMetadata = (context: M.OAuthConnectedTokenContext, now: number) => {\n const m = context.metadata,\n p = context.configuration.profile;\n\n return (\n p.provider === context.identity.provider &&\n context.configuration.provider === context.identity.provider &&\n context.configuration.issuer === context.identity.issuer &&\n m.obtainedAtMillis <= now &&\n m.useUntilMillis > m.obtainedAtMillis &&\n m.useUntilMillis <= m.obtainedAtMillis + p.maximumAccessLifetimeMillis &&\n (m.accessExpiresAtMillis === undefined || m.useUntilMillis <= m.accessExpiresAtMillis) &&\n m.scopes.every((v) => p.scopes.includes(v)) &&\n m.resources.every((v) => p.resources.includes(v)) &&\n new Set(m.scopes).size === m.scopes.length &&\n new Set(m.resources).size === m.resources.length &&\n (m.refreshUseUntilMillis === undefined ||\n (p.retention === \"access-and-refresh\" &&\n p.maximumRefreshLifetimeMillis !== undefined &&\n m.refreshUseUntilMillis > m.obtainedAtMillis &&\n m.refreshUseUntilMillis <= m.obtainedAtMillis + p.maximumRefreshLifetimeMillis &&\n (m.refreshExpiresAtMillis === undefined ||\n m.refreshUseUntilMillis <= m.refreshExpiresAtMillis)))\n );\n};\n\n/** The only writer that activates or replaces a confirmed connected grant. */\nexport const activateGrant = Effect.fn(\"oauthConnected.activateGrant\")(function* (\n mapping: S.Mapping,\n grant: M.OAuthConnectedStoredGrant,\n native: unknown,\n now: number,\n replacing: boolean,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const token = grant.context;\n const g = mapping.grant;\n const identityKey = oauthIdentityKey(token.identity);\n const clientKey = S.clientKey(token.configuration);\n const cohortKey = S.cohortKey(clientKey, identityKey);\n\n const values = {\n ...g.encodeInsert({\n grant: snapshotOAuthSync(M.OAuthConnectedStoredGrant, grant),\n subjectId: S.nativeCopy(native),\n }),\n [g.moduleId]: token.moduleId,\n [g.grantId]: token.grantId,\n [g.subjectId]: native,\n [g.identityKey]: identityKey,\n [g.activeIdentityKey]: identityKey,\n [g.clientKey]: clientKey,\n [g.cohortKey]: cohortKey,\n [g.profileKey]: token.configuration.profile.key,\n [g.grantVersion]: token.grantVersion,\n [g.tokenVersion]: token.tokenVersion,\n [g.cohortGeneration]: token.cohortGeneration,\n [g.state]: \"Active\",\n [g.version]: owner.marker,\n [g.context]: S.tokenContextStorage.encode(token),\n [g.sealed]: S.sealedStorage.encode(grant.sealed),\n [g.summary]: S.summaryStorage.encode(C.summary(token)),\n [g.revocationJobId]: null,\n [g.refreshWork]: \"None\",\n [g.refreshClaim]: null,\n [g.refreshClaimExpiresAt]: null,\n [g.retentionUntil]: mapping.clock.encodeInstant(\n S.retainedUntil(\n mapping,\n Math.max(now, token.metadata.useUntilMillis, token.metadata.refreshUseUntilMillis ?? 0),\n ),\n ),\n };\n\n if (!replacing) {\n yield* owner.insert(g.table, values, {\n [g.moduleId]: token.moduleId,\n [g.grantId]: token.grantId,\n });\n } else\n yield* owner.update(\n g.table,\n { [g.moduleId]: token.moduleId, [g.grantId]: token.grantId },\n values,\n );\n});\n\nexport const settle = Effect.fn(\"oauthConnected.settle\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"settle\">,\n) {\n const owner = yield* CurrentOAuthTransaction;\n\n const c = input.claim.flow.context,\n out = input.outcome;\n\n const found = yield* S.current(mapping, c.revision.subjectId);\n\n const authorized =\n found !== undefined &&\n (yield* S.action(mapping, found, input.authorization, \"settle\", F.expected(input.claim.flow)));\n\n const cl = yield* S.client(mapping, S.configuration(input.claim.flow), false);\n\n if (cl === undefined) return { _tag: \"Rejected\" } as const;\n if (out._tag !== \"Verified\" && out._tag !== \"Quarantined\") {\n const claimed = yield* F.exact(mapping, input.claim);\n\n if (claimed === undefined) return { _tag: \"Rejected\" } as const;\n const state = out._tag === \"Unissued\" ? \"Rejected\" : out._tag;\n\n yield* F.terminal(\n mapping,\n input.claim,\n state,\n out._tag === \"Cancelled\" || out._tag === \"Unissued\" ? \"Resolved\" : \"Unresolved\",\n );\n\n return { _tag: state } as\n | { readonly _tag: \"Cancelled\" }\n | { readonly _tag: \"Rejected\" }\n | { readonly _tag: \"Conflict\" }\n | { readonly _tag: \"Ambiguous\" };\n }\n\n const grant = snapshotOAuthSync(M.OAuthConnectedStoredGrant, out.grant),\n token = grant.context;\n\n invariant(\n token.moduleId === c.moduleId &&\n token.subjectId === c.revision.subjectId &&\n token.grantId === c.grantId &&\n token.identity.provider === c.provider &&\n token.identity.issuer === c.issuer &&\n S.clientKey(token.configuration) === cl.id &&\n S.tokenContextStorage.encode({\n ...token,\n configuration: S.configuration(input.claim.flow),\n }) === S.tokenContextStorage.encode(token),\n );\n const native = yield* mapping.subjectId.toNative(c.revision.subjectId);\n\n const tuple = yield* F.readTuple(mapping.ownership, token.identity),\n t = mapping.ownership.tuple;\n\n if (\n tuple.row[t.state] === \"Reserved\" ||\n (tuple.row[t.state] === \"Owned\" && !mapping.subjectId.equals(tuple.row[t.subjectId], native))\n ) {\n const claimed = yield* F.exact(mapping, input.claim);\n\n if (claimed !== undefined) yield* F.terminal(mapping, input.claim, \"Conflict\", \"Unresolved\");\n\n return { _tag: \"Conflict\" } as const;\n }\n const co = yield* S.cohort(mapping, cl.id, tuple.key, true);\n const original = yield* S.readGrant(mapping, c.moduleId, c.grantId);\n const g = mapping.grant;\n\n const other = yield* owner.read(\n g.table,\n both(\n equal(g.table, {\n [g.moduleId]: c.moduleId,\n [g.subjectId]: native,\n [g.profileKey]: c.profile.key,\n [g.activeIdentityKey]: tuple.key,\n }),\n ne(col(g.table, g.grantId), c.grantId),\n ),\n { limit: 1 },\n );\n\n const claimed = yield* F.exact(mapping, input.claim);\n\n if (claimed === undefined) return { _tag: \"Rejected\" } as const;\n invariant(\n token.exchangeOrder === input.claim.order &&\n validMetadata(token, claimed.now) &&\n token.metadata.obtainedAtMillis >= input.claim.claimedAtMillis,\n );\n const reconnect = c.reconnect;\n\n const targetOkay =\n reconnect === undefined\n ? original === undefined\n : original !== undefined &&\n F.sameTarget(reconnect, original.context) &&\n sameIdentity(reconnect.identity, token.identity) &&\n original.row[g.refreshWork] !== \"Unresolved\";\n\n const previousSafe = yield* C.noFormerOwner(mapping, tuple.key, cl.id, native);\n\n const active =\n out._tag === \"Verified\" &&\n authorized &&\n claimed.active &&\n c.profile.issuance === \"active\" &&\n token.metadata.useUntilMillis > claimed.now &&\n !co.blocked &&\n co.generation === token.cohortGeneration &&\n S.orderNumber(input.claim.order) > co.cutoff &&\n targetOkay &&\n other.rows.length === 0 &&\n previousSafe;\n\n if (!active) {\n // Foreign historical custody never authorizes a new remote operation.\n if (!previousSafe) {\n yield* F.terminal(mapping, input.claim, \"Conflict\", \"Unresolved\");\n\n return { _tag: \"Conflict\" } as const;\n }\n if (tuple.row[t.state] === \"Unowned\")\n yield* F.acquireTuple(mapping.ownership, token.identity, tuple.key, S.nativeCopy(native));\n yield* C.fence(mapping, cl, co);\n if (out.cleanup !== undefined) {\n yield* C.storeJob(mapping, out.cleanup, token, native, claimed.now);\n yield* F.terminal(mapping, input.claim, \"Quarantined\", \"Resolved\", { cohort: co.id });\n } else\n yield* F.terminal(mapping, input.claim, \"Quarantined\", \"Unresolved\", {\n cohort: co.id,\n sealed: grant,\n });\n\n return { _tag: targetOkay && other.rows.length === 0 ? \"Rejected\" : \"Conflict\" } as\n | { readonly _tag: \"Rejected\" }\n | { readonly _tag: \"Conflict\" };\n }\n if (tuple.row[t.state] === \"Unowned\")\n yield* F.acquireTuple(mapping.ownership, token.identity, tuple.key, S.nativeCopy(native));\n\n yield* activateGrant(mapping, grant, native, claimed.now, original !== undefined);\n yield* F.terminal(mapping, input.claim, \"Connected\", \"Resolved\", { cohort: co.id });\n owner.postconditions.push(\n sql`${mapping.clock.engineNowMillis} >= ${claimed.now} and ${mapping.clock.engineNowMillis} < ${Math.min(input.claim.claimExpiresAtMillis, token.metadata.useUntilMillis)}`,\n );\n\n return { _tag: \"Connected\", grant } as const;\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"oauth-connected-settlement.mjs","names":["clientKey","S.clientKey","cohortKey","S.cohortKey","S.nativeCopy","C.summary","S.retainedUntil","S.current","S.action","F.expected","S.client","S.configuration","F.exact","F.terminal","F.readTuple","S.cohort","S.readGrant","F.sameTarget","C.noFormerOwner","S.orderNumber","F.acquireTuple","C.fence","C.storeJob"],"sources":["../../src/drizzle/oauth-connected-settlement.ts"],"sourcesContent":["import * as M from \"@yielded/auth/OAuth\";\nimport { snapshotOAuthSync } from \"@yielded/auth/OAuth\";\nimport { ne, sql } from \"drizzle-orm\";\nimport { Effect } from \"effect\";\n\nimport * as C from \"./oauth-connected-custody\";\nimport * as F from \"./oauth-connected-flow\";\nimport * as S from \"./oauth-connected-state\";\nimport { both, col, equal, CurrentOAuthTransaction } from \"./oauth-owner\";\nimport { invariant, sameIdentity, oauthIdentityKey } from \"./oauth-state\";\n\nexport const validMetadata = (context: M.OAuthConnectedTokenContext, now: number) => {\n const m = context.metadata,\n p = context.configuration.profile;\n\n return (\n p.provider === context.identity.provider &&\n context.configuration.provider === context.identity.provider &&\n context.configuration.issuer === context.identity.issuer &&\n m.obtainedAtMillis <= now &&\n m.useUntilMillis > m.obtainedAtMillis &&\n m.useUntilMillis <= m.obtainedAtMillis + p.maximumAccessLifetimeMillis &&\n (m.accessExpiresAtMillis === undefined || m.useUntilMillis <= m.accessExpiresAtMillis) &&\n m.scopes.every((v) => p.scopes.includes(v)) &&\n m.resources.every((v) => p.resources.includes(v)) &&\n new Set(m.scopes).size === m.scopes.length &&\n new Set(m.resources).size === m.resources.length &&\n (m.refreshUseUntilMillis === undefined ||\n (p.retention === \"access-and-refresh\" &&\n p.maximumRefreshLifetimeMillis !== undefined &&\n m.refreshUseUntilMillis > m.obtainedAtMillis &&\n m.refreshUseUntilMillis <= m.obtainedAtMillis + p.maximumRefreshLifetimeMillis &&\n (m.refreshExpiresAtMillis === undefined ||\n m.refreshUseUntilMillis <= m.refreshExpiresAtMillis)))\n );\n};\n\n/** The only writer that activates or replaces a confirmed connected grant. */\nexport const activateGrant = Effect.fn(\"oauthConnected.activateGrant\")(function* (\n mapping: S.Mapping,\n grant: M.OAuthConnectedStoredGrant,\n native: unknown,\n now: number,\n replacing: boolean,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const token = grant.context;\n const g = mapping.grant;\n const identityKey = yield* oauthIdentityKey(token.identity);\n const clientKey = yield* S.clientKey(token.configuration);\n const cohortKey = yield* S.cohortKey(clientKey, identityKey);\n\n const values = {\n ...g.encodeInsert({\n grant: snapshotOAuthSync(M.OAuthConnectedStoredGrant, grant),\n subjectId: S.nativeCopy(native),\n }),\n [g.moduleId]: token.moduleId,\n [g.grantId]: token.grantId,\n [g.subjectId]: native,\n [g.identityKey]: identityKey,\n [g.activeIdentityKey]: identityKey,\n [g.clientKey]: clientKey,\n [g.cohortKey]: cohortKey,\n [g.profileKey]: token.configuration.profile.key,\n [g.grantVersion]: token.grantVersion,\n [g.tokenVersion]: token.tokenVersion,\n [g.cohortGeneration]: token.cohortGeneration,\n [g.state]: \"Active\",\n [g.version]: owner.marker,\n [g.context]: S.tokenContextStorage.encode(token),\n [g.sealed]: S.sealedStorage.encode(grant.sealed),\n [g.summary]: S.summaryStorage.encode(C.summary(token)),\n [g.revocationJobId]: null,\n [g.refreshWork]: \"None\",\n [g.refreshClaim]: null,\n [g.refreshClaimExpiresAt]: null,\n [g.retentionUntil]: mapping.clock.encodeInstant(\n S.retainedUntil(\n mapping,\n Math.max(now, token.metadata.useUntilMillis, token.metadata.refreshUseUntilMillis ?? 0),\n ),\n ),\n };\n\n if (!replacing) {\n yield* owner.insert(g.table, values, {\n [g.moduleId]: token.moduleId,\n [g.grantId]: token.grantId,\n });\n } else\n yield* owner.update(\n g.table,\n { [g.moduleId]: token.moduleId, [g.grantId]: token.grantId },\n values,\n );\n});\n\nexport const settle = Effect.fn(\"oauthConnected.settle\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"settle\">,\n) {\n const owner = yield* CurrentOAuthTransaction;\n\n const c = input.claim.flow.context,\n out = input.outcome;\n\n const found = yield* S.current(mapping, c.revision.subjectId);\n\n const authorized =\n found !== undefined &&\n (yield* S.action(mapping, found, input.authorization, \"settle\", F.expected(input.claim.flow)));\n\n const cl = yield* S.client(mapping, S.configuration(input.claim.flow), false);\n\n if (cl === undefined) return { _tag: \"Rejected\" } as const;\n if (out._tag !== \"Verified\" && out._tag !== \"Quarantined\") {\n const claimed = yield* F.exact(mapping, input.claim);\n\n if (claimed === undefined) return { _tag: \"Rejected\" } as const;\n const state = out._tag === \"Unissued\" ? \"Rejected\" : out._tag;\n\n yield* F.terminal(\n mapping,\n input.claim,\n state,\n out._tag === \"Cancelled\" || out._tag === \"Unissued\" ? \"Resolved\" : \"Unresolved\",\n );\n\n return { _tag: state } as\n | { readonly _tag: \"Cancelled\" }\n | { readonly _tag: \"Rejected\" }\n | { readonly _tag: \"Conflict\" }\n | { readonly _tag: \"Ambiguous\" };\n }\n\n const grant = snapshotOAuthSync(M.OAuthConnectedStoredGrant, out.grant),\n token = grant.context;\n\n invariant(\n token.moduleId === c.moduleId &&\n token.subjectId === c.revision.subjectId &&\n token.grantId === c.grantId &&\n token.identity.provider === c.provider &&\n token.identity.issuer === c.issuer &&\n (yield* S.clientKey(token.configuration)) === cl.id &&\n S.tokenContextStorage.encode({\n ...token,\n configuration: S.configuration(input.claim.flow),\n }) === S.tokenContextStorage.encode(token),\n );\n const native = yield* mapping.subjectId.toNative(c.revision.subjectId);\n\n const tuple = yield* F.readTuple(mapping.ownership, token.identity),\n t = mapping.ownership.tuple;\n\n if (\n tuple.row[t.state] === \"Reserved\" ||\n (tuple.row[t.state] === \"Owned\" && !mapping.subjectId.equals(tuple.row[t.subjectId], native))\n ) {\n const claimed = yield* F.exact(mapping, input.claim);\n\n if (claimed !== undefined) yield* F.terminal(mapping, input.claim, \"Conflict\", \"Unresolved\");\n\n return { _tag: \"Conflict\" } as const;\n }\n const co = yield* S.cohort(mapping, cl.id, tuple.key, true);\n const original = yield* S.readGrant(mapping, c.moduleId, c.grantId);\n const g = mapping.grant;\n\n const other = yield* owner.read(\n g.table,\n both(\n equal(g.table, {\n [g.moduleId]: c.moduleId,\n [g.subjectId]: native,\n [g.profileKey]: c.profile.key,\n [g.activeIdentityKey]: tuple.key,\n }),\n ne(col(g.table, g.grantId), c.grantId),\n ),\n { limit: 1 },\n );\n\n const claimed = yield* F.exact(mapping, input.claim);\n\n if (claimed === undefined) return { _tag: \"Rejected\" } as const;\n invariant(\n token.exchangeOrder === input.claim.order &&\n validMetadata(token, claimed.now) &&\n token.metadata.obtainedAtMillis >= input.claim.claimedAtMillis,\n );\n const reconnect = c.reconnect;\n\n const targetOkay =\n reconnect === undefined\n ? original === undefined\n : original !== undefined &&\n F.sameTarget(reconnect, original.context) &&\n sameIdentity(reconnect.identity, token.identity) &&\n original.row[g.refreshWork] !== \"Unresolved\";\n\n const previousSafe = yield* C.noFormerOwner(mapping, tuple.key, cl.id, native);\n\n const active =\n out._tag === \"Verified\" &&\n authorized &&\n claimed.active &&\n c.profile.issuance === \"active\" &&\n token.metadata.useUntilMillis > claimed.now &&\n !co.blocked &&\n co.generation === token.cohortGeneration &&\n S.orderNumber(input.claim.order) > co.cutoff &&\n targetOkay &&\n other.rows.length === 0 &&\n previousSafe;\n\n if (!active) {\n // Foreign historical custody never authorizes a new remote operation.\n if (!previousSafe) {\n yield* F.terminal(mapping, input.claim, \"Conflict\", \"Unresolved\");\n\n return { _tag: \"Conflict\" } as const;\n }\n if (tuple.row[t.state] === \"Unowned\")\n yield* F.acquireTuple(mapping.ownership, token.identity, tuple.key, S.nativeCopy(native));\n yield* C.fence(mapping, cl, co);\n if (out.cleanup !== undefined) {\n yield* C.storeJob(mapping, out.cleanup, token, native, claimed.now);\n yield* F.terminal(mapping, input.claim, \"Quarantined\", \"Resolved\", { cohort: co.id });\n } else\n yield* F.terminal(mapping, input.claim, \"Quarantined\", \"Unresolved\", {\n cohort: co.id,\n sealed: grant,\n });\n\n return { _tag: targetOkay && other.rows.length === 0 ? \"Rejected\" : \"Conflict\" } as\n | { readonly _tag: \"Rejected\" }\n | { readonly _tag: \"Conflict\" };\n }\n if (tuple.row[t.state] === \"Unowned\")\n yield* F.acquireTuple(mapping.ownership, token.identity, tuple.key, S.nativeCopy(native));\n\n yield* activateGrant(mapping, grant, native, claimed.now, original !== undefined);\n yield* F.terminal(mapping, input.claim, \"Connected\", \"Resolved\", { cohort: co.id });\n owner.postconditions.push(\n sql`${mapping.clock.engineNowMillis} >= ${claimed.now} and ${mapping.clock.engineNowMillis} < ${Math.min(input.claim.claimExpiresAtMillis, token.metadata.useUntilMillis)}`,\n );\n\n return { _tag: \"Connected\", grant } as const;\n});\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { digest, invariant, oauthIdentityKey, sameIdentity, sameRevision, storage, unavailable } from "./oauth-state.mjs";
1
+ import { digest } from "./crypto.mjs";
2
+ import { invariant, oauthIdentityKey, sameIdentity, sameRevision, storage, unavailable } from "./oauth-state.mjs";
2
3
  import { both } from "./transaction-owner.mjs";
3
4
  import { CurrentOAuthTransaction, equal } from "./oauth-owner.mjs";
4
5
  import { exactClaim } from "./oauth-flow.mjs";
@@ -64,7 +65,7 @@ const claimSignIn = Effect.fn("oauthConnected.claimSignIn")(function* (mapping,
64
65
  [f.stateDigest]: c.stateDigest,
65
66
  [f.snapshot]: null,
66
67
  [f.claimId]: claim.claimId,
67
- [f.claimDigest]: digest(reservationStorage.encode(reservation)),
68
+ [f.claimDigest]: yield* digest(reservationStorage.encode(reservation)),
68
69
  [f.claimOrder]: mapping.order.encode(order),
69
70
  [f.claimedAt]: mapping.clock.encodeInstant(claim.claimedAtMillis),
70
71
  [f.claimExpiresAt]: mapping.clock.encodeInstant(claim.claimExpiresAtMillis),
@@ -86,8 +87,8 @@ const exact = Effect.fn("oauthConnected.exactSignIn")(function* (mapping, reserv
86
87
  [f.flowId]: c.flowId
87
88
  };
88
89
  const row = (yield* owner.read(f.table, equal(f.table, key), { limit: 1 })).rows[0];
89
- if (row === void 0 || row[f.work] !== "Unresolved" || row[f.claimId] !== reservation.claim.claimId || row[f.claimDigest] !== digest(reservationStorage.encode(reservation))) return void 0;
90
- invariant(row[f.subjectId] === null && row[f.commandId] === c.commandId && row[f.clientKey] === clientKey(reservation.configuration) && nativeOrder(mapping, row[f.claimOrder]) === orderNumber(reservation.order));
90
+ if (row === void 0 || row[f.work] !== "Unresolved" || row[f.claimId] !== reservation.claim.claimId || row[f.claimDigest] !== (yield* digest(reservationStorage.encode(reservation)))) return void 0;
91
+ invariant(row[f.subjectId] === null && row[f.commandId] === c.commandId && row[f.clientKey] === (yield* clientKey(reservation.configuration)) && nativeOrder(mapping, row[f.claimOrder]) === orderNumber(reservation.order));
91
92
  const now = yield* owner.now(mapping.clock);
92
93
  invariant(now >= reservation.claim.claimedAtMillis);
93
94
  return {
@@ -110,7 +111,7 @@ const credential = Effect.fn("oauthConnected.signInCredential")(function* (mappi
110
111
  [c.moduleId]: context.moduleId,
111
112
  [c.credentialId]: input.credentialId,
112
113
  [c.subjectId]: found.nativeId,
113
- [c.identityKey]: oauthIdentityKey(input.identity),
114
+ [c.identityKey]: yield* oauthIdentityKey(input.identity),
114
115
  [c.credentialRevision]: input.credentialRevision
115
116
  }), c.activeCondition);
116
117
  const login = yield* owner.read(c.table, loginWhere, { limit: 1 });
@@ -153,11 +154,11 @@ const slot = Effect.fn("oauthConnected.signInSlot")(function* (mapping, moduleId
153
154
  });
154
155
  /** Orders belong to one client registration. Moving a profile to another client
155
156
  * requires a newer profile generation; retired clients cannot replace it later. */
156
- const canReplace = (reservation, previous) => {
157
+ const canReplace = Effect.fnUntraced(function* (reservation, previous) {
157
158
  const generation = reservation.configuration.profile.generation;
158
159
  const oldGeneration = previous.configuration.profile.generation;
159
- return clientKey(reservation.configuration) === clientKey(previous.configuration) ? generation >= oldGeneration && orderNumber(reservation.order) > orderNumber(previous.exchangeOrder) : generation > oldGeneration;
160
- };
160
+ return (yield* clientKey(reservation.configuration)) === (yield* clientKey(previous.configuration)) ? generation >= oldGeneration && orderNumber(reservation.order) > orderNumber(previous.exchangeOrder) : generation > oldGeneration;
161
+ });
161
162
  const inspectSignIn = Effect.fn("oauthConnected.inspectSignIn")(function* (mapping, input) {
162
163
  const found = yield* credential(mapping, input.reservation, input.credential);
163
164
  if (found === void 0) return { _tag: "Rejected" };
@@ -171,7 +172,7 @@ const inspectSignIn = Effect.fn("oauthConnected.inspectSignIn")(function* (mappi
171
172
  const previous = yield* slot(mapping, r.claim.flow.context.moduleId, found.nativeId, tuple.key, r.configuration.profile.key);
172
173
  const held = yield* exact(mapping, r);
173
174
  if (held === void 0) return { _tag: "Rejected" };
174
- const quarantine = !held.active || co.blocked || orderNumber(r.order) <= co.cutoff || previous?.row[mapping.grant.refreshWork] === "Unresolved" || previous !== void 0 && !canReplace(r, previous.context);
175
+ const quarantine = !held.active || co.blocked || orderNumber(r.order) <= co.cutoff || previous?.row[mapping.grant.refreshWork] === "Unresolved" || previous !== void 0 && !(yield* canReplace(r, previous.context));
175
176
  return snapshotOAuthSync(M.OAuthSignInAccessInspection, {
176
177
  _tag: quarantine ? "Quarantine" : "Target",
177
178
  grantId: previous?.context.grantId ?? input.grantId,
@@ -210,7 +211,7 @@ const settleSignIn = Effect.fn("oauthConnected.settleSignIn")(function* (mapping
210
211
  const held = yield* exact(mapping, r);
211
212
  if (held === void 0) return { _tag: "Rejected" };
212
213
  invariant(token.exchangeOrder === r.order && validMetadata(token, held.now) && token.metadata.obtainedAtMillis >= r.claim.claimedAtMillis);
213
- const target = out.previous === void 0 ? previous === void 0 : previous !== void 0 && sameTarget(out.previous, previous.context) && sameIdentity(previous.context.identity, token.identity) && previous.row[mapping.grant.refreshWork] !== "Unresolved" && canReplace(r, previous.context);
214
+ const target = out.previous === void 0 ? previous === void 0 : previous !== void 0 && sameTarget(out.previous, previous.context) && sameIdentity(previous.context.identity, token.identity) && previous.row[mapping.grant.refreshWork] !== "Unresolved" && (yield* canReplace(r, previous.context));
214
215
  const previousSafe = yield* noFormerOwner(mapping, tuple.key, cl.id, native);
215
216
  if (!owned || !previousSafe) {
216
217
  yield* owner.update(f.table, held.key, {
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-connected-sign-in.mjs","names":["client","S.client","S.touchScope","S.nextOrder","S.clientKey","S.nativeOrder","S.orderNumber","S.current","S.policy","S.readGrant","F.inspectTuple","S.cohort","F.readTuple","F.sameTarget","C.noFormerOwner","C.fence","C.storeJob"],"sources":["../../src/drizzle/oauth-connected-sign-in.ts"],"sourcesContent":["import * as M from \"@yielded/auth/OAuth\";\nimport { snapshotOAuthSync } from \"@yielded/auth/OAuth\";\nimport { sql } from \"drizzle-orm\";\nimport { Effect, Schema } from \"effect\";\n\nimport * as C from \"./oauth-connected-custody\";\nimport * as F from \"./oauth-connected-flow\";\nimport { activateGrant, validMetadata } from \"./oauth-connected-settlement\";\nimport * as S from \"./oauth-connected-state\";\nimport { exactClaim } from \"./oauth-flow\";\nimport { both, equal, CurrentOAuthTransaction } from \"./oauth-owner\";\nimport {\n digest,\n invariant,\n oauthIdentityKey,\n sameIdentity,\n sameRevision,\n storage,\n unavailable,\n} from \"./oauth-state\";\n\nconst reservationStorage = storage(M.OAuthSignInAccessClaim);\nconst configurationStorage = storage(M.OAuthConnectedConfiguration);\n\n/** Reservation rows share the connected-work ledger, but have no browser\n * snapshot or subject. They can never enter the authenticated connect flow. */\nexport const claimSignIn = Effect.fn(\"oauthConnected.claimSignIn\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"claimSignIn\">,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const signIn = mapping.signIn;\n const encode = mapping.flow.encodeSignIn;\n\n if (signIn === undefined || encode === undefined) return yield* unavailable();\n const { claim, configuration } = input;\n const c = claim.flow.context;\n\n invariant(\n c.access !== undefined &&\n configurationStorage.encode(configuration) ===\n configurationStorage.encode({ ...c, profile: c.access }),\n );\n if (configuration.profile.revocation === \"cohort\")\n invariant(mapping.revocation.mode === \"cohort\");\n const client = yield* S.client(mapping, configuration, true);\n\n invariant(client !== undefined);\n const exact = yield* exactClaim({ ...mapping, flow: signIn.flow }, claim, \"sign-in\");\n\n if (exact === undefined) return yield* unavailable();\n const f = mapping.flow;\n const key = { [f.moduleId]: c.moduleId, [f.flowId]: c.flowId };\n const prior = yield* owner.read(f.table, equal(f.table, key), { limit: 1 });\n\n const command = yield* owner.read(\n f.table,\n equal(f.table, { [f.moduleId]: c.moduleId, [f.commandId]: c.commandId }),\n { limit: 1 },\n );\n\n if (prior.rows.length || command.rows.length) return yield* unavailable();\n yield* S.touchScope(mapping, client.scope);\n const order = yield* S.nextOrder(mapping, client);\n\n const reservation = snapshotOAuthSync(M.OAuthSignInAccessClaim, {\n claim,\n configuration,\n order: String(order),\n });\n\n const inserted = yield* owner.insert(\n f.table,\n {\n ...encode(reservation),\n ...key,\n [f.commandId]: c.commandId,\n [f.subjectId]: null,\n [f.clientKey]: client.id,\n [f.cohortKey]: null,\n [f.state]: \"Claimed\",\n [f.version]: owner.marker,\n [f.stateDigest]: c.stateDigest,\n [f.snapshot]: null,\n [f.claimId]: claim.claimId,\n [f.claimDigest]: digest(reservationStorage.encode(reservation)),\n [f.claimOrder]: mapping.order.encode(order),\n [f.claimedAt]: mapping.clock.encodeInstant(claim.claimedAtMillis),\n [f.claimExpiresAt]: mapping.clock.encodeInstant(claim.claimExpiresAtMillis),\n [f.expiresAt]: mapping.clock.encodeInstant(c.expiresAtMillis),\n [f.retentionUntil]: mapping.clock.encodeInstant(claim.flow.retentionUntilMillis),\n [f.work]: \"Unresolved\",\n [f.custody]: null,\n },\n key,\n );\n\n prior.rows = inserted.rows;\n command.rows = inserted.rows;\n\n return reservation;\n});\n\nconst exact = Effect.fn(\"oauthConnected.exactSignIn\")(function* (\n mapping: S.Mapping,\n reservation: M.OAuthSignInAccessClaim,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const f = mapping.flow;\n const c = reservation.claim.flow.context;\n const key = { [f.moduleId]: c.moduleId, [f.flowId]: c.flowId };\n const read = yield* owner.read(f.table, equal(f.table, key), { limit: 1 });\n const row = read.rows[0];\n\n if (\n row === undefined ||\n row[f.work] !== \"Unresolved\" ||\n row[f.claimId] !== reservation.claim.claimId ||\n row[f.claimDigest] !== digest(reservationStorage.encode(reservation))\n )\n return undefined;\n invariant(\n row[f.subjectId] === null &&\n row[f.commandId] === c.commandId &&\n row[f.clientKey] === S.clientKey(reservation.configuration) &&\n S.nativeOrder(mapping, row[f.claimOrder]) === S.orderNumber(reservation.order),\n );\n const now = yield* owner.now(mapping.clock);\n\n invariant(now >= reservation.claim.claimedAtMillis);\n\n return {\n key,\n row,\n now,\n active: row[f.state] === \"Claimed\" && now < reservation.claim.claimExpiresAtMillis,\n };\n});\n\nconst credential = Effect.fn(\"oauthConnected.signInCredential\")(function* (\n mapping: S.Mapping,\n reservation: M.OAuthSignInAccessClaim,\n input: M.OAuthCredentialSnapshot,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const signIn = mapping.signIn;\n\n if (signIn === undefined) return undefined;\n const context = reservation.claim.flow.context;\n\n if (\n input.moduleId !== context.moduleId ||\n input.identity.provider !== context.provider ||\n input.identity.issuer !== context.issuer\n )\n return undefined;\n const found = yield* S.current(mapping, input.revision.subjectId);\n\n if (found === undefined || !sameRevision(found.revision, input.revision)) return undefined;\n const c = signIn.credential;\n\n const loginWhere = both(\n equal(c.table, {\n [c.moduleId]: context.moduleId,\n [c.credentialId]: input.credentialId,\n [c.subjectId]: found.nativeId,\n [c.identityKey]: oauthIdentityKey(input.identity),\n [c.credentialRevision]: input.credentialRevision,\n }),\n c.activeCondition,\n );\n\n const login = yield* owner.read(c.table, loginWhere, { limit: 1 });\n\n if (login.rows.length !== 1 || !c.isActiveStatus(login.rows[0]![c.status])) return undefined;\n const f = signIn.flow;\n\n const verifiedWhere = equal(f.table, {\n [f.moduleId]: context.moduleId,\n [f.flowId]: context.flowId,\n [f.state]: \"Verified\",\n [f.claimId]: reservation.claim.claimId,\n [f.stateDigest]: context.stateDigest,\n [f.claimedAt]: mapping.clock.encodeInstant(reservation.claim.claimedAtMillis),\n [f.claimExpiresAt]: mapping.clock.encodeInstant(reservation.claim.claimExpiresAtMillis),\n });\n\n const verified = yield* owner.read(f.table, verifiedWhere, { limit: 1 });\n\n if (verified.rows.length !== 1) return undefined;\n owner.postconditions.push(\n sql`exists(select 1 from ${c.table} where ${loginWhere})`,\n sql`exists(select 1 from ${f.table} where ${verifiedWhere})`,\n );\n if (\n !(yield* S.policy(mapping, {\n kind: \"sign-in\",\n subjectId: found.nativeId,\n revision: found.revision,\n credential: snapshotOAuthSync(M.OAuthCredentialSnapshot, input),\n configuration: reservation.configuration,\n }))\n )\n return undefined;\n\n return found;\n});\n\nconst slot = Effect.fn(\"oauthConnected.signInSlot\")(function* (\n mapping: S.Mapping,\n moduleId: string,\n native: unknown,\n identityKey: string,\n profileKey: string,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const g = mapping.grant;\n\n const rows = yield* owner.read(\n g.table,\n equal(g.table, {\n [g.moduleId]: moduleId,\n [g.subjectId]: native,\n [g.profileKey]: profileKey,\n [g.activeIdentityKey]: identityKey,\n }),\n { limit: 1, admissionOnly: true },\n );\n\n const row = rows.rows[0];\n\n if (row === undefined) return undefined;\n\n return yield* S.readGrant(\n mapping,\n moduleId,\n yield* Schema.decodeUnknownEffect(M.OAuthGrantId)(row[g.grantId]).pipe(\n Effect.mapError(unavailable),\n ),\n );\n});\n\n/** Orders belong to one client registration. Moving a profile to another client\n * requires a newer profile generation; retired clients cannot replace it later. */\nconst canReplace = (\n reservation: M.OAuthSignInAccessClaim,\n previous: M.OAuthConnectedTokenContext,\n) => {\n const generation = reservation.configuration.profile.generation;\n const oldGeneration = previous.configuration.profile.generation;\n\n return S.clientKey(reservation.configuration) === S.clientKey(previous.configuration)\n ? generation >= oldGeneration &&\n S.orderNumber(reservation.order) > S.orderNumber(previous.exchangeOrder)\n : generation > oldGeneration;\n};\n\nexport const inspectSignIn = Effect.fn(\"oauthConnected.inspectSignIn\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"inspectSignIn\">,\n) {\n const found = yield* credential(mapping, input.reservation, input.credential);\n\n if (found === undefined) return { _tag: \"Rejected\" } as const;\n const r = input.reservation;\n const cl = yield* S.client(mapping, r.configuration, false);\n\n if (cl === undefined) return { _tag: \"Rejected\" } as const;\n const tuple = yield* F.inspectTuple(mapping, input.credential.identity);\n const t = mapping.ownership.tuple;\n\n if (\n tuple.row?.[t.state] !== \"Owned\" ||\n !mapping.subjectId.equals(tuple.row[t.subjectId], found.nativeId)\n )\n return { _tag: \"Rejected\" } as const;\n const co = yield* S.cohort(mapping, cl.id, tuple.key, false);\n\n const previous = yield* slot(\n mapping,\n r.claim.flow.context.moduleId,\n found.nativeId,\n tuple.key,\n r.configuration.profile.key,\n );\n\n const held = yield* exact(mapping, r);\n\n if (held === undefined) return { _tag: \"Rejected\" } as const;\n\n const quarantine =\n !held.active ||\n co.blocked ||\n S.orderNumber(r.order) <= co.cutoff ||\n previous?.row[mapping.grant.refreshWork] === \"Unresolved\" ||\n (previous !== undefined && !canReplace(r, previous.context));\n\n return snapshotOAuthSync(M.OAuthSignInAccessInspection, {\n _tag: quarantine ? \"Quarantine\" : \"Target\",\n grantId: previous?.context.grantId ?? input.grantId,\n cohortGeneration: co.generation,\n ...(previous === undefined\n ? {}\n : { previous: snapshotOAuthSync(M.OAuthConnectedTarget, previous.context) }),\n });\n});\n\nexport const settleSignIn = Effect.fn(\"oauthConnected.settleSignIn\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"settleSignIn\">,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const r = input.reservation;\n const out = input.outcome;\n const found = out._tag === \"Verified\" ? yield* credential(mapping, r, out.credential) : undefined;\n const cl = yield* S.client(mapping, r.configuration, false);\n\n if (cl === undefined) return { _tag: \"Rejected\" } as const;\n const f = mapping.flow;\n\n if (out._tag !== \"Verified\") {\n const held = yield* exact(mapping, r);\n\n if (held === undefined) return { _tag: \"Rejected\" } as const;\n // Unissued means the provider definitely returned no token. Resolve that\n // reservation. A Rejected outcome can follow a real exchange, so it stays open.\n const state = out._tag === \"Unissued\" ? \"Rejected\" : out._tag;\n\n yield* owner.update(f.table, held.key, {\n [f.state]: state,\n [f.work]: out._tag === \"Cancelled\" || out._tag === \"Unissued\" ? \"Resolved\" : \"Unresolved\",\n [f.version]: owner.marker,\n });\n\n return { _tag: state };\n }\n const token = out.grant.context;\n\n invariant(\n token.moduleId === r.claim.flow.context.moduleId &&\n token.subjectId === out.credential.revision.subjectId &&\n sameIdentity(token.identity, out.credential.identity) &&\n configurationStorage.encode(token.configuration) ===\n configurationStorage.encode(r.configuration),\n );\n const native = yield* mapping.subjectId.toNative(token.subjectId);\n const tuple = yield* F.readTuple(mapping.ownership, token.identity);\n const t = mapping.ownership.tuple;\n\n const owned =\n tuple.row[t.state] === \"Owned\" && mapping.subjectId.equals(tuple.row[t.subjectId], native);\n\n const co = yield* S.cohort(mapping, cl.id, tuple.key, true);\n const previous = yield* S.readGrant(mapping, token.moduleId, token.grantId);\n\n const activeSlot = yield* slot(\n mapping,\n token.moduleId,\n native,\n tuple.key,\n token.configuration.profile.key,\n );\n\n const held = yield* exact(mapping, r);\n\n if (held === undefined) return { _tag: \"Rejected\" } as const;\n invariant(\n token.exchangeOrder === r.order &&\n validMetadata(token, held.now) &&\n token.metadata.obtainedAtMillis >= r.claim.claimedAtMillis,\n );\n\n const target =\n out.previous === undefined\n ? previous === undefined\n : previous !== undefined &&\n F.sameTarget(out.previous, previous.context) &&\n sameIdentity(previous.context.identity, token.identity) &&\n previous.row[mapping.grant.refreshWork] !== \"Unresolved\" &&\n canReplace(r, previous.context);\n\n const previousSafe = yield* C.noFormerOwner(mapping, tuple.key, cl.id, native);\n\n if (!owned || !previousSafe) {\n yield* owner.update(f.table, held.key, { [f.state]: \"Conflict\", [f.version]: owner.marker });\n\n return { _tag: \"Conflict\" } as const;\n }\n if (\n out.quarantine ||\n found === undefined ||\n !held.active ||\n !target ||\n (activeSlot !== undefined && activeSlot.context.grantId !== token.grantId) ||\n co.blocked ||\n S.orderNumber(r.order) <= co.cutoff ||\n co.generation !== token.cohortGeneration ||\n token.metadata.useUntilMillis <= held.now ||\n token.configuration.profile.issuance !== \"active\"\n ) {\n if (token.configuration.profile.revocation === \"unsupported\") {\n // No remote cleanup can run for this profile. Discard the losing material;\n // it must neither replace nor revoke the currently installed grant.\n yield* owner.update(f.table, held.key, {\n [f.state]: \"Rejected\",\n [f.work]: \"Resolved\",\n [f.subjectId]: native,\n [f.cohortKey]: co.id,\n [f.custody]: null,\n [f.version]: owner.marker,\n });\n } else {\n yield* C.fence(mapping, cl, co);\n if (out.cleanup === undefined) return yield* unavailable();\n yield* C.storeJob(mapping, out.cleanup, token, native, held.now);\n yield* owner.update(f.table, held.key, {\n [f.state]: \"Quarantined\",\n [f.work]: \"Resolved\",\n [f.subjectId]: native,\n [f.cohortKey]: co.id,\n [f.custody]: null,\n [f.version]: owner.marker,\n });\n }\n\n return { _tag: \"Rejected\" } as const;\n }\n yield* activateGrant(mapping, out.grant, native, held.now, previous !== undefined);\n yield* owner.update(f.table, held.key, {\n [f.state]: \"Connected\",\n [f.work]: \"Resolved\",\n [f.subjectId]: native,\n [f.cohortKey]: co.id,\n [f.custody]: null,\n [f.version]: owner.marker,\n });\n owner.postconditions.push(\n sql`${mapping.clock.engineNowMillis} >= ${held.now} and ${mapping.clock.engineNowMillis} < ${Math.min(r.claim.claimExpiresAtMillis, token.metadata.useUntilMillis)}`,\n );\n\n return { _tag: \"Connected\", grant: out.grant } as const;\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"oauth-connected-sign-in.mjs","names":["client","S.client","S.touchScope","S.nextOrder","S.clientKey","S.nativeOrder","S.orderNumber","S.current","S.policy","S.readGrant","F.inspectTuple","S.cohort","F.readTuple","F.sameTarget","C.noFormerOwner","C.fence","C.storeJob"],"sources":["../../src/drizzle/oauth-connected-sign-in.ts"],"sourcesContent":["import * as M from \"@yielded/auth/OAuth\";\nimport { snapshotOAuthSync } from \"@yielded/auth/OAuth\";\nimport { sql } from \"drizzle-orm\";\nimport { Effect, Schema } from \"effect\";\n\nimport * as C from \"./oauth-connected-custody\";\nimport * as F from \"./oauth-connected-flow\";\nimport { activateGrant, validMetadata } from \"./oauth-connected-settlement\";\nimport * as S from \"./oauth-connected-state\";\nimport { exactClaim } from \"./oauth-flow\";\nimport { both, equal, CurrentOAuthTransaction } from \"./oauth-owner\";\nimport {\n digest,\n invariant,\n oauthIdentityKey,\n sameIdentity,\n sameRevision,\n storage,\n unavailable,\n} from \"./oauth-state\";\n\nconst reservationStorage = storage(M.OAuthSignInAccessClaim);\nconst configurationStorage = storage(M.OAuthConnectedConfiguration);\n\n/** Reservation rows share the connected-work ledger, but have no browser\n * snapshot or subject. They can never enter the authenticated connect flow. */\nexport const claimSignIn = Effect.fn(\"oauthConnected.claimSignIn\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"claimSignIn\">,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const signIn = mapping.signIn;\n const encode = mapping.flow.encodeSignIn;\n\n if (signIn === undefined || encode === undefined) return yield* unavailable();\n const { claim, configuration } = input;\n const c = claim.flow.context;\n\n invariant(\n c.access !== undefined &&\n configurationStorage.encode(configuration) ===\n configurationStorage.encode({ ...c, profile: c.access }),\n );\n if (configuration.profile.revocation === \"cohort\")\n invariant(mapping.revocation.mode === \"cohort\");\n const client = yield* S.client(mapping, configuration, true);\n\n invariant(client !== undefined);\n const exact = yield* exactClaim({ ...mapping, flow: signIn.flow }, claim, \"sign-in\");\n\n if (exact === undefined) return yield* unavailable();\n const f = mapping.flow;\n const key = { [f.moduleId]: c.moduleId, [f.flowId]: c.flowId };\n const prior = yield* owner.read(f.table, equal(f.table, key), { limit: 1 });\n\n const command = yield* owner.read(\n f.table,\n equal(f.table, { [f.moduleId]: c.moduleId, [f.commandId]: c.commandId }),\n { limit: 1 },\n );\n\n if (prior.rows.length || command.rows.length) return yield* unavailable();\n yield* S.touchScope(mapping, client.scope);\n const order = yield* S.nextOrder(mapping, client);\n\n const reservation = snapshotOAuthSync(M.OAuthSignInAccessClaim, {\n claim,\n configuration,\n order: String(order),\n });\n\n const inserted = yield* owner.insert(\n f.table,\n {\n ...encode(reservation),\n ...key,\n [f.commandId]: c.commandId,\n [f.subjectId]: null,\n [f.clientKey]: client.id,\n [f.cohortKey]: null,\n [f.state]: \"Claimed\",\n [f.version]: owner.marker,\n [f.stateDigest]: c.stateDigest,\n [f.snapshot]: null,\n [f.claimId]: claim.claimId,\n [f.claimDigest]: yield* digest(reservationStorage.encode(reservation)),\n [f.claimOrder]: mapping.order.encode(order),\n [f.claimedAt]: mapping.clock.encodeInstant(claim.claimedAtMillis),\n [f.claimExpiresAt]: mapping.clock.encodeInstant(claim.claimExpiresAtMillis),\n [f.expiresAt]: mapping.clock.encodeInstant(c.expiresAtMillis),\n [f.retentionUntil]: mapping.clock.encodeInstant(claim.flow.retentionUntilMillis),\n [f.work]: \"Unresolved\",\n [f.custody]: null,\n },\n key,\n );\n\n prior.rows = inserted.rows;\n command.rows = inserted.rows;\n\n return reservation;\n});\n\nconst exact = Effect.fn(\"oauthConnected.exactSignIn\")(function* (\n mapping: S.Mapping,\n reservation: M.OAuthSignInAccessClaim,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const f = mapping.flow;\n const c = reservation.claim.flow.context;\n const key = { [f.moduleId]: c.moduleId, [f.flowId]: c.flowId };\n const read = yield* owner.read(f.table, equal(f.table, key), { limit: 1 });\n const row = read.rows[0];\n\n if (\n row === undefined ||\n row[f.work] !== \"Unresolved\" ||\n row[f.claimId] !== reservation.claim.claimId ||\n row[f.claimDigest] !== (yield* digest(reservationStorage.encode(reservation)))\n )\n return undefined;\n invariant(\n row[f.subjectId] === null &&\n row[f.commandId] === c.commandId &&\n row[f.clientKey] === (yield* S.clientKey(reservation.configuration)) &&\n S.nativeOrder(mapping, row[f.claimOrder]) === S.orderNumber(reservation.order),\n );\n const now = yield* owner.now(mapping.clock);\n\n invariant(now >= reservation.claim.claimedAtMillis);\n\n return {\n key,\n row,\n now,\n active: row[f.state] === \"Claimed\" && now < reservation.claim.claimExpiresAtMillis,\n };\n});\n\nconst credential = Effect.fn(\"oauthConnected.signInCredential\")(function* (\n mapping: S.Mapping,\n reservation: M.OAuthSignInAccessClaim,\n input: M.OAuthCredentialSnapshot,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const signIn = mapping.signIn;\n\n if (signIn === undefined) return undefined;\n const context = reservation.claim.flow.context;\n\n if (\n input.moduleId !== context.moduleId ||\n input.identity.provider !== context.provider ||\n input.identity.issuer !== context.issuer\n )\n return undefined;\n const found = yield* S.current(mapping, input.revision.subjectId);\n\n if (found === undefined || !sameRevision(found.revision, input.revision)) return undefined;\n const c = signIn.credential;\n\n const loginWhere = both(\n equal(c.table, {\n [c.moduleId]: context.moduleId,\n [c.credentialId]: input.credentialId,\n [c.subjectId]: found.nativeId,\n [c.identityKey]: yield* oauthIdentityKey(input.identity),\n [c.credentialRevision]: input.credentialRevision,\n }),\n c.activeCondition,\n );\n\n const login = yield* owner.read(c.table, loginWhere, { limit: 1 });\n\n if (login.rows.length !== 1 || !c.isActiveStatus(login.rows[0]![c.status])) return undefined;\n const f = signIn.flow;\n\n const verifiedWhere = equal(f.table, {\n [f.moduleId]: context.moduleId,\n [f.flowId]: context.flowId,\n [f.state]: \"Verified\",\n [f.claimId]: reservation.claim.claimId,\n [f.stateDigest]: context.stateDigest,\n [f.claimedAt]: mapping.clock.encodeInstant(reservation.claim.claimedAtMillis),\n [f.claimExpiresAt]: mapping.clock.encodeInstant(reservation.claim.claimExpiresAtMillis),\n });\n\n const verified = yield* owner.read(f.table, verifiedWhere, { limit: 1 });\n\n if (verified.rows.length !== 1) return undefined;\n owner.postconditions.push(\n sql`exists(select 1 from ${c.table} where ${loginWhere})`,\n sql`exists(select 1 from ${f.table} where ${verifiedWhere})`,\n );\n if (\n !(yield* S.policy(mapping, {\n kind: \"sign-in\",\n subjectId: found.nativeId,\n revision: found.revision,\n credential: snapshotOAuthSync(M.OAuthCredentialSnapshot, input),\n configuration: reservation.configuration,\n }))\n )\n return undefined;\n\n return found;\n});\n\nconst slot = Effect.fn(\"oauthConnected.signInSlot\")(function* (\n mapping: S.Mapping,\n moduleId: string,\n native: unknown,\n identityKey: string,\n profileKey: string,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const g = mapping.grant;\n\n const rows = yield* owner.read(\n g.table,\n equal(g.table, {\n [g.moduleId]: moduleId,\n [g.subjectId]: native,\n [g.profileKey]: profileKey,\n [g.activeIdentityKey]: identityKey,\n }),\n { limit: 1, admissionOnly: true },\n );\n\n const row = rows.rows[0];\n\n if (row === undefined) return undefined;\n\n return yield* S.readGrant(\n mapping,\n moduleId,\n yield* Schema.decodeUnknownEffect(M.OAuthGrantId)(row[g.grantId]).pipe(\n Effect.mapError(unavailable),\n ),\n );\n});\n\n/** Orders belong to one client registration. Moving a profile to another client\n * requires a newer profile generation; retired clients cannot replace it later. */\nconst canReplace = Effect.fnUntraced(function* (\n reservation: M.OAuthSignInAccessClaim,\n previous: M.OAuthConnectedTokenContext,\n) {\n const generation = reservation.configuration.profile.generation;\n const oldGeneration = previous.configuration.profile.generation;\n\n return (yield* S.clientKey(reservation.configuration)) ===\n (yield* S.clientKey(previous.configuration))\n ? generation >= oldGeneration &&\n S.orderNumber(reservation.order) > S.orderNumber(previous.exchangeOrder)\n : generation > oldGeneration;\n});\n\nexport const inspectSignIn = Effect.fn(\"oauthConnected.inspectSignIn\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"inspectSignIn\">,\n) {\n const found = yield* credential(mapping, input.reservation, input.credential);\n\n if (found === undefined) return { _tag: \"Rejected\" } as const;\n const r = input.reservation;\n const cl = yield* S.client(mapping, r.configuration, false);\n\n if (cl === undefined) return { _tag: \"Rejected\" } as const;\n const tuple = yield* F.inspectTuple(mapping, input.credential.identity);\n const t = mapping.ownership.tuple;\n\n if (\n tuple.row?.[t.state] !== \"Owned\" ||\n !mapping.subjectId.equals(tuple.row[t.subjectId], found.nativeId)\n )\n return { _tag: \"Rejected\" } as const;\n const co = yield* S.cohort(mapping, cl.id, tuple.key, false);\n\n const previous = yield* slot(\n mapping,\n r.claim.flow.context.moduleId,\n found.nativeId,\n tuple.key,\n r.configuration.profile.key,\n );\n\n const held = yield* exact(mapping, r);\n\n if (held === undefined) return { _tag: \"Rejected\" } as const;\n\n const quarantine =\n !held.active ||\n co.blocked ||\n S.orderNumber(r.order) <= co.cutoff ||\n previous?.row[mapping.grant.refreshWork] === \"Unresolved\" ||\n (previous !== undefined && !(yield* canReplace(r, previous.context)));\n\n return snapshotOAuthSync(M.OAuthSignInAccessInspection, {\n _tag: quarantine ? \"Quarantine\" : \"Target\",\n grantId: previous?.context.grantId ?? input.grantId,\n cohortGeneration: co.generation,\n ...(previous === undefined\n ? {}\n : { previous: snapshotOAuthSync(M.OAuthConnectedTarget, previous.context) }),\n });\n});\n\nexport const settleSignIn = Effect.fn(\"oauthConnected.settleSignIn\")(function* (\n mapping: S.Mapping,\n input: F.Input<\"settleSignIn\">,\n) {\n const owner = yield* CurrentOAuthTransaction;\n const r = input.reservation;\n const out = input.outcome;\n const found = out._tag === \"Verified\" ? yield* credential(mapping, r, out.credential) : undefined;\n const cl = yield* S.client(mapping, r.configuration, false);\n\n if (cl === undefined) return { _tag: \"Rejected\" } as const;\n const f = mapping.flow;\n\n if (out._tag !== \"Verified\") {\n const held = yield* exact(mapping, r);\n\n if (held === undefined) return { _tag: \"Rejected\" } as const;\n // Unissued means the provider definitely returned no token. Resolve that\n // reservation. A Rejected outcome can follow a real exchange, so it stays open.\n const state = out._tag === \"Unissued\" ? \"Rejected\" : out._tag;\n\n yield* owner.update(f.table, held.key, {\n [f.state]: state,\n [f.work]: out._tag === \"Cancelled\" || out._tag === \"Unissued\" ? \"Resolved\" : \"Unresolved\",\n [f.version]: owner.marker,\n });\n\n return { _tag: state };\n }\n const token = out.grant.context;\n\n invariant(\n token.moduleId === r.claim.flow.context.moduleId &&\n token.subjectId === out.credential.revision.subjectId &&\n sameIdentity(token.identity, out.credential.identity) &&\n configurationStorage.encode(token.configuration) ===\n configurationStorage.encode(r.configuration),\n );\n const native = yield* mapping.subjectId.toNative(token.subjectId);\n const tuple = yield* F.readTuple(mapping.ownership, token.identity);\n const t = mapping.ownership.tuple;\n\n const owned =\n tuple.row[t.state] === \"Owned\" && mapping.subjectId.equals(tuple.row[t.subjectId], native);\n\n const co = yield* S.cohort(mapping, cl.id, tuple.key, true);\n const previous = yield* S.readGrant(mapping, token.moduleId, token.grantId);\n\n const activeSlot = yield* slot(\n mapping,\n token.moduleId,\n native,\n tuple.key,\n token.configuration.profile.key,\n );\n\n const held = yield* exact(mapping, r);\n\n if (held === undefined) return { _tag: \"Rejected\" } as const;\n invariant(\n token.exchangeOrder === r.order &&\n validMetadata(token, held.now) &&\n token.metadata.obtainedAtMillis >= r.claim.claimedAtMillis,\n );\n\n const target =\n out.previous === undefined\n ? previous === undefined\n : previous !== undefined &&\n F.sameTarget(out.previous, previous.context) &&\n sameIdentity(previous.context.identity, token.identity) &&\n previous.row[mapping.grant.refreshWork] !== \"Unresolved\" &&\n (yield* canReplace(r, previous.context));\n\n const previousSafe = yield* C.noFormerOwner(mapping, tuple.key, cl.id, native);\n\n if (!owned || !previousSafe) {\n yield* owner.update(f.table, held.key, { [f.state]: \"Conflict\", [f.version]: owner.marker });\n\n return { _tag: \"Conflict\" } as const;\n }\n if (\n out.quarantine ||\n found === undefined ||\n !held.active ||\n !target ||\n (activeSlot !== undefined && activeSlot.context.grantId !== token.grantId) ||\n co.blocked ||\n S.orderNumber(r.order) <= co.cutoff ||\n co.generation !== token.cohortGeneration ||\n token.metadata.useUntilMillis <= held.now ||\n token.configuration.profile.issuance !== \"active\"\n ) {\n if (token.configuration.profile.revocation === \"unsupported\") {\n // No remote cleanup can run for this profile. Discard the losing material;\n // it must neither replace nor revoke the currently installed grant.\n yield* owner.update(f.table, held.key, {\n [f.state]: \"Rejected\",\n [f.work]: \"Resolved\",\n [f.subjectId]: native,\n [f.cohortKey]: co.id,\n [f.custody]: null,\n [f.version]: owner.marker,\n });\n } else {\n yield* C.fence(mapping, cl, co);\n if (out.cleanup === undefined) return yield* unavailable();\n yield* C.storeJob(mapping, out.cleanup, token, native, held.now);\n yield* owner.update(f.table, held.key, {\n [f.state]: \"Quarantined\",\n [f.work]: \"Resolved\",\n [f.subjectId]: native,\n [f.cohortKey]: co.id,\n [f.custody]: null,\n [f.version]: owner.marker,\n });\n }\n\n return { _tag: \"Rejected\" } as const;\n }\n yield* activateGrant(mapping, out.grant, native, held.now, previous !== undefined);\n yield* owner.update(f.table, held.key, {\n [f.state]: \"Connected\",\n [f.work]: \"Resolved\",\n [f.subjectId]: native,\n [f.cohortKey]: co.id,\n [f.custody]: null,\n [f.version]: owner.marker,\n });\n owner.postconditions.push(\n sql`${mapping.clock.engineNowMillis} >= ${held.now} and ${mapping.clock.engineNowMillis} < ${Math.min(r.claim.claimExpiresAtMillis, token.metadata.useUntilMillis)}`,\n );\n\n return { _tag: \"Connected\", grant: out.grant } as const;\n});\n"],"mappings":"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"}