@yielded/auth-persistence 0.1.0-beta.25 → 0.1.0-beta.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -8
- package/dist/Adapter.d.mts +47 -33
- package/dist/Adapter.mjs +36 -23
- package/dist/OAuthPersistence.d.mts +35 -51
- package/dist/OAuthPersistence.mjs +60 -68
- package/dist/OAuthPersistence.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/internal/browser-login.d.mts +1 -1
- package/dist/internal/browser-login.mjs +29 -9
- package/dist/internal/browser-login.mjs.map +1 -1
- package/dist/internal/configuration.d.mts +13 -8
- package/dist/internal/configuration.mjs.map +1 -1
- package/dist/internal/crypto.d.mts +1 -0
- package/dist/internal/crypto.mjs +1 -1
- package/dist/internal/d1-planning.mjs +8 -0
- package/dist/internal/d1-planning.mjs.map +1 -0
- package/dist/internal/email-native-state.mjs +135 -0
- package/dist/internal/email-native-state.mjs.map +1 -0
- package/dist/internal/email-native.d.mts +17 -0
- package/dist/internal/email-native.mjs +245 -0
- package/dist/internal/email-native.mjs.map +1 -0
- package/dist/internal/email-policy.mjs +92 -0
- package/dist/internal/email-policy.mjs.map +1 -0
- package/dist/internal/email-registration-native.d.mts +38 -0
- package/dist/internal/email-registration-native.mjs +171 -0
- package/dist/internal/email-registration-native.mjs.map +1 -0
- package/dist/internal/models/email-model.d.mts +40 -104
- package/dist/internal/models/email-model.mjs +3 -5
- package/dist/internal/models/email-model.mjs.map +1 -1
- package/dist/internal/models/oauth-connected-model.d.mts +44 -213
- package/dist/internal/models/oauth-connected-model.mjs +6 -14
- package/dist/internal/models/oauth-connected-model.mjs.map +1 -1
- package/dist/internal/models/oauth-model.d.mts +95 -244
- package/dist/internal/models/oauth-model.mjs +28 -22
- package/dist/internal/models/oauth-model.mjs.map +1 -1
- package/dist/internal/models/passkey-model.d.mts +11 -147
- package/dist/internal/models/passkey-model.mjs +5 -24
- package/dist/internal/models/passkey-model.mjs.map +1 -1
- package/dist/internal/models/passkey-registration-ceremony-model.d.mts +5 -39
- package/dist/internal/models/passkey-write-model.d.mts +17 -75
- package/dist/internal/models/passkey-write-model.mjs +1 -7
- package/dist/internal/models/passkey-write-model.mjs.map +1 -1
- package/dist/internal/models/password-model.d.mts +14 -81
- package/dist/internal/models/password-model.mjs +1 -4
- package/dist/internal/models/password-model.mjs.map +1 -1
- package/dist/internal/models/phone-model.d.mts +86 -0
- package/dist/internal/models/phone-model.mjs +10 -0
- package/dist/internal/models/phone-model.mjs.map +1 -0
- package/dist/internal/models/proof-model.d.mts +43 -272
- package/dist/internal/models/proof-model.mjs +2 -10
- package/dist/internal/models/proof-model.mjs.map +1 -1
- package/dist/internal/models/session-model.d.mts +74 -93
- package/dist/internal/models/session-model.mjs +3 -11
- package/dist/internal/models/session-model.mjs.map +1 -1
- package/dist/internal/models/step-up-model.d.mts +12 -50
- package/dist/internal/models/step-up-model.mjs +2 -4
- package/dist/internal/models/step-up-model.mjs.map +1 -1
- package/dist/internal/models/totp-model.d.mts +76 -0
- package/dist/internal/models/totp-model.mjs +10 -0
- package/dist/internal/models/totp-model.mjs.map +1 -0
- package/dist/internal/native-sql-table.d.mts +21 -4
- package/dist/internal/native-sql-table.mjs +9 -5
- package/dist/internal/native-sql-table.mjs.map +1 -1
- package/dist/internal/oauth/native-accounts.d.mts +17 -0
- package/dist/internal/oauth/native-accounts.mjs +290 -0
- package/dist/internal/oauth/native-accounts.mjs.map +1 -0
- package/dist/internal/oauth/native-connected-state.d.mts +11 -0
- package/dist/internal/oauth/native-connected-state.mjs +146 -0
- package/dist/internal/oauth/native-connected-state.mjs.map +1 -0
- package/dist/internal/oauth/native-connected.d.mts +15 -0
- package/dist/internal/oauth/native-connected.mjs +462 -0
- package/dist/internal/oauth/native-connected.mjs.map +1 -0
- package/dist/internal/oauth/native-flow.mjs +138 -0
- package/dist/internal/oauth/native-flow.mjs.map +1 -0
- package/dist/internal/oauth/native-layers.d.mts +24 -0
- package/dist/internal/oauth/native-layers.mjs +13 -0
- package/dist/internal/oauth/native-layers.mjs.map +1 -0
- package/dist/internal/oauth/native-mutation.mjs +122 -0
- package/dist/internal/oauth/native-mutation.mjs.map +1 -0
- package/dist/internal/oauth/native-registration.d.mts +24 -0
- package/dist/internal/oauth/native-registration.mjs +328 -0
- package/dist/internal/oauth/native-registration.mjs.map +1 -0
- package/dist/internal/oauth/native-revocations.d.mts +17 -0
- package/dist/internal/oauth/native-revocations.mjs +106 -0
- package/dist/internal/oauth/native-revocations.mjs.map +1 -0
- package/dist/internal/oauth/native-sign-in.d.mts +17 -0
- package/dist/internal/oauth/native-sign-in.mjs +50 -0
- package/dist/internal/oauth/native-sign-in.mjs.map +1 -0
- package/dist/internal/oauth/native-state.d.mts +10 -0
- package/dist/internal/oauth/native-state.mjs +214 -0
- package/dist/internal/oauth/native-state.mjs.map +1 -0
- package/dist/internal/oauth/state.d.mts +10 -0
- package/dist/internal/oauth/state.mjs +3 -27
- package/dist/internal/oauth/state.mjs.map +1 -1
- package/dist/internal/passkey-actions.mjs +55 -0
- package/dist/internal/passkey-actions.mjs.map +1 -0
- package/dist/internal/passkey-inputs.mjs +73 -0
- package/dist/internal/passkey-inputs.mjs.map +1 -0
- package/dist/internal/passkey-managed.mjs +224 -0
- package/dist/internal/passkey-managed.mjs.map +1 -0
- package/dist/internal/passkey-native-ceremony.d.mts +35 -0
- package/dist/internal/passkey-native-ceremony.mjs +38 -0
- package/dist/internal/passkey-native-ceremony.mjs.map +1 -0
- package/dist/internal/passkey-native-flow.mjs +91 -0
- package/dist/internal/passkey-native-flow.mjs.map +1 -0
- package/dist/internal/passkey-native-registration.d.mts +10 -0
- package/dist/internal/passkey-native-registration.mjs +114 -0
- package/dist/internal/passkey-native-registration.mjs.map +1 -0
- package/dist/internal/passkey-native-state.d.mts +15 -0
- package/dist/internal/passkey-native-state.mjs +186 -0
- package/dist/internal/passkey-native-state.mjs.map +1 -0
- package/dist/internal/passkey-native-write.d.mts +82 -0
- package/dist/internal/passkey-native-write.mjs +330 -0
- package/dist/internal/passkey-native-write.mjs.map +1 -0
- package/dist/internal/passkey-native.d.mts +835 -0
- package/dist/internal/passkey-native.mjs +175 -0
- package/dist/internal/passkey-native.mjs.map +1 -0
- package/dist/internal/passkey-policy.mjs +115 -0
- package/dist/internal/passkey-policy.mjs.map +1 -0
- package/dist/internal/password-credentials.mjs +38 -9
- package/dist/internal/password-credentials.mjs.map +1 -1
- package/dist/internal/password-native.d.mts +14 -0
- package/dist/internal/password-native.mjs +292 -0
- package/dist/internal/password-native.mjs.map +1 -0
- package/dist/internal/password-policy.mjs +93 -0
- package/dist/internal/password-policy.mjs.map +1 -0
- package/dist/internal/password-registration-native.d.mts +22 -0
- package/dist/internal/password-registration-native.mjs +142 -0
- package/dist/internal/password-registration-native.mjs.map +1 -0
- package/dist/internal/persistence.d.mts +6 -19
- package/dist/internal/persistence.mjs +199 -166
- package/dist/internal/persistence.mjs.map +1 -1
- package/dist/internal/phone-composed.mjs +79 -0
- package/dist/internal/phone-composed.mjs.map +1 -0
- package/dist/internal/phone-native.d.mts +15 -0
- package/dist/internal/phone-native.mjs +354 -0
- package/dist/internal/phone-native.mjs.map +1 -0
- package/dist/internal/proof-native.d.mts +15 -0
- package/dist/internal/proof-native.mjs +289 -0
- package/dist/internal/proof-native.mjs.map +1 -0
- package/dist/internal/registration.mjs +50 -60
- package/dist/internal/registration.mjs.map +1 -1
- package/dist/internal/session-native-authority.d.mts +15 -0
- package/dist/internal/session-native-authority.mjs +91 -0
- package/dist/internal/session-native-authority.mjs.map +1 -0
- package/dist/internal/session-native-cleanup.d.mts +14 -0
- package/dist/internal/session-native-cleanup.mjs +48 -0
- package/dist/internal/session-native-cleanup.mjs.map +1 -0
- package/dist/internal/session-native-login.d.mts +15 -0
- package/dist/internal/session-native-login.mjs +87 -0
- package/dist/internal/session-native-login.mjs.map +1 -0
- package/dist/internal/session-native-pending-read.mjs +42 -0
- package/dist/internal/session-native-pending-read.mjs.map +1 -0
- package/dist/internal/session-native-pending.mjs +134 -0
- package/dist/internal/session-native-pending.mjs.map +1 -0
- package/dist/internal/session-native-record.mjs +79 -0
- package/dist/internal/session-native-record.mjs.map +1 -0
- package/dist/internal/session-native-state.mjs +130 -0
- package/dist/internal/session-native-state.mjs.map +1 -0
- package/dist/internal/session-native-stateful.d.mts +16 -0
- package/dist/internal/session-native-stateful.mjs +225 -0
- package/dist/internal/session-native-stateful.mjs.map +1 -0
- package/dist/internal/session-native-step-up.d.mts +15 -0
- package/dist/internal/session-native-step-up.mjs +212 -0
- package/dist/internal/session-native-step-up.mjs.map +1 -0
- package/dist/internal/session-native-validity.d.mts +15 -0
- package/dist/internal/session-native-validity.mjs +97 -0
- package/dist/internal/session-native-validity.mjs.map +1 -0
- package/dist/internal/session-policy.mjs +29 -0
- package/dist/internal/session-policy.mjs.map +1 -0
- package/dist/internal/sql-authority.d.mts +16 -0
- package/dist/internal/sql-authority.mjs +32 -0
- package/dist/internal/sql-authority.mjs.map +1 -0
- package/dist/internal/sql-change.mjs +21 -0
- package/dist/internal/sql-change.mjs.map +1 -0
- package/dist/internal/sql-cleanup.mjs +35 -0
- package/dist/internal/sql-cleanup.mjs.map +1 -0
- package/dist/internal/sql-commit.d.mts +72 -0
- package/dist/internal/sql-commit.mjs +176 -0
- package/dist/internal/sql-commit.mjs.map +1 -0
- package/dist/internal/sql-expression.d.mts +17 -0
- package/dist/internal/sql-expression.mjs +49 -0
- package/dist/internal/sql-expression.mjs.map +1 -0
- package/dist/internal/sql-oauth-connected-model.d.mts +7 -23
- package/dist/internal/sql-oauth-model.d.mts +27 -52
- package/dist/internal/sql-oauth-model.mjs +3 -4
- package/dist/internal/sql-oauth-model.mjs.map +1 -1
- package/dist/internal/sql-persistence.mjs +5 -9
- package/dist/internal/sql-persistence.mjs.map +1 -1
- package/dist/internal/sql-storage-validation.mjs +1 -2
- package/dist/internal/sql-storage-validation.mjs.map +1 -1
- package/dist/internal/sql-table.d.mts +3 -16
- package/dist/internal/sql-table.mjs +21 -42
- package/dist/internal/sql-table.mjs.map +1 -1
- package/dist/internal/standalone.mjs +2 -3
- package/dist/internal/standalone.mjs.map +1 -1
- package/dist/internal/step-up-state.mjs +5 -8
- package/dist/internal/step-up-state.mjs.map +1 -1
- package/dist/internal/storage-clock.mjs +44 -0
- package/dist/internal/storage-clock.mjs.map +1 -0
- package/dist/internal/storage-mapping.d.mts +11 -8
- package/dist/internal/storage-mapping.mjs +88 -302
- package/dist/internal/storage-mapping.mjs.map +1 -1
- package/dist/internal/storage-plans.mjs +15 -73
- package/dist/internal/storage-plans.mjs.map +1 -1
- package/dist/internal/storage-tables.d.mts +37 -520
- package/dist/internal/storage-tables.mjs +31 -211
- package/dist/internal/storage-tables.mjs.map +1 -1
- package/dist/internal/storage-validation.d.mts +1 -6
- package/dist/internal/storage-validation.mjs +1 -42
- package/dist/internal/storage-validation.mjs.map +1 -1
- package/dist/internal/table-model.d.mts +21 -0
- package/dist/internal/totp-native.d.mts +15 -0
- package/dist/internal/totp-native.mjs +401 -0
- package/dist/internal/totp-native.mjs.map +1 -0
- package/package.json +1 -1
- package/src/Adapter.ts +143 -199
- package/src/OAuthPersistence.ts +128 -271
- package/src/index.ts +1 -1
- package/src/internal/browser-login.ts +54 -24
- package/src/internal/configuration.ts +16 -31
- package/src/internal/d1-planning.ts +7 -0
- package/src/internal/email-native-state.ts +247 -0
- package/src/internal/email-native.ts +514 -0
- package/src/internal/email-policy.ts +235 -0
- package/src/internal/email-registration-native.ts +386 -0
- package/src/internal/models/email-model.ts +76 -214
- package/src/internal/models/oauth-connected-model.ts +50 -288
- package/src/internal/models/oauth-model.ts +147 -368
- package/src/internal/models/passkey-model.ts +11 -208
- package/src/internal/models/passkey-registration-ceremony-model.ts +6 -60
- package/src/internal/models/passkey-write-model.ts +14 -95
- package/src/internal/models/password-model.ts +26 -147
- package/src/internal/models/phone-model.ts +110 -0
- package/src/internal/models/proof-model.ts +48 -404
- package/src/internal/models/session-model.ts +102 -200
- package/src/internal/models/step-up-model.ts +17 -96
- package/src/internal/models/totp-model.ts +82 -0
- package/src/internal/native-sql-table.ts +32 -11
- package/src/internal/oauth/native-accounts.ts +576 -0
- package/src/internal/oauth/native-connected-state.ts +288 -0
- package/src/internal/oauth/native-connected.ts +888 -0
- package/src/internal/oauth/native-flow.ts +253 -0
- package/src/internal/oauth/native-layers.ts +83 -0
- package/src/internal/oauth/native-mutation.ts +222 -0
- package/src/internal/oauth/native-registration.ts +545 -0
- package/src/internal/oauth/native-revocations.ts +190 -0
- package/src/internal/oauth/native-sign-in.ts +111 -0
- package/src/internal/oauth/native-state.ts +346 -0
- package/src/internal/oauth/state.ts +2 -70
- package/src/internal/passkey-actions.ts +70 -0
- package/src/internal/passkey-inputs.ts +56 -0
- package/src/internal/passkey-managed.ts +360 -0
- package/src/internal/passkey-native-ceremony.ts +66 -0
- package/src/internal/passkey-native-flow.ts +140 -0
- package/src/internal/passkey-native-registration.ts +221 -0
- package/src/internal/passkey-native-state.ts +335 -0
- package/src/internal/passkey-native-write.ts +611 -0
- package/src/internal/passkey-native.ts +372 -0
- package/src/internal/passkey-policy.ts +246 -0
- package/src/internal/password-credentials.ts +52 -10
- package/src/internal/password-native.ts +571 -0
- package/src/internal/password-policy.ts +307 -0
- package/src/internal/password-registration-native.ts +322 -0
- package/src/internal/persistence.ts +336 -290
- package/src/internal/phone-composed.ts +86 -0
- package/src/internal/phone-native.ts +659 -0
- package/src/internal/proof-native.ts +448 -0
- package/src/internal/registration.ts +96 -143
- package/src/internal/session-native-authority.ts +247 -0
- package/src/internal/session-native-cleanup.ts +65 -0
- package/src/internal/session-native-login.ts +205 -0
- package/src/internal/session-native-pending-read.ts +68 -0
- package/src/internal/session-native-pending.ts +223 -0
- package/src/internal/session-native-record.ts +141 -0
- package/src/internal/session-native-state.ts +259 -0
- package/src/internal/session-native-stateful.ts +512 -0
- package/src/internal/session-native-step-up.ts +450 -0
- package/src/internal/session-native-validity.ts +208 -0
- package/src/internal/session-policy.ts +59 -0
- package/src/internal/sql-authority.ts +56 -0
- package/src/internal/sql-change.ts +38 -0
- package/src/internal/sql-cleanup.ts +56 -0
- package/src/internal/sql-commit.ts +435 -0
- package/src/internal/sql-expression.ts +94 -0
- package/src/internal/sql-metadata.ts +100 -0
- package/src/internal/sql-oauth-connected-model.ts +6 -95
- package/src/internal/sql-oauth-model.ts +31 -134
- package/src/internal/sql-persistence.ts +2 -6
- package/src/internal/sql-storage-validation.ts +1 -2
- package/src/internal/sql-table.ts +19 -52
- package/src/internal/standalone.ts +2 -11
- package/src/internal/step-up-state.ts +4 -17
- package/src/internal/storage-clock.ts +58 -0
- package/src/internal/storage-mapping.ts +125 -340
- package/src/internal/storage-plans.ts +14 -80
- package/src/internal/storage-tables.ts +28 -212
- package/src/internal/storage-validation.ts +0 -58
- package/src/internal/table-model.ts +24 -0
- package/src/internal/totp-native.ts +701 -0
- package/dist/internal/PasswordPreparedPostconditions.d.mts +0 -22
- package/dist/internal/PasswordPreparedPostconditions.mjs +0 -12
- package/dist/internal/PasswordPreparedPostconditions.mjs.map +0 -1
- package/dist/internal/authority-snapshot.mjs +0 -53
- package/dist/internal/authority-snapshot.mjs.map +0 -1
- package/dist/internal/email-kernel.d.mts +0 -276
- package/dist/internal/email-kernel.mjs +0 -497
- package/dist/internal/email-kernel.mjs.map +0 -1
- package/dist/internal/models/passkey-registration-ceremony-model.mjs +0 -18
- package/dist/internal/models/passkey-registration-ceremony-model.mjs.map +0 -1
- package/dist/internal/oauth/accounts.d.mts +0 -8
- package/dist/internal/oauth/accounts.mjs +0 -379
- package/dist/internal/oauth/accounts.mjs.map +0 -1
- package/dist/internal/oauth/connected-access.d.mts +0 -9
- package/dist/internal/oauth/connected-access.mjs +0 -229
- package/dist/internal/oauth/connected-access.mjs.map +0 -1
- package/dist/internal/oauth/connected-collection.d.mts +0 -7
- package/dist/internal/oauth/connected-collection.mjs +0 -214
- package/dist/internal/oauth/connected-collection.mjs.map +0 -1
- package/dist/internal/oauth/connected-custody.d.mts +0 -6
- package/dist/internal/oauth/connected-custody.mjs +0 -165
- package/dist/internal/oauth/connected-custody.mjs.map +0 -1
- package/dist/internal/oauth/connected-flow.d.mts +0 -7
- package/dist/internal/oauth/connected-flow.mjs +0 -324
- package/dist/internal/oauth/connected-flow.mjs.map +0 -1
- package/dist/internal/oauth/connected-input.mjs +0 -122
- package/dist/internal/oauth/connected-input.mjs.map +0 -1
- package/dist/internal/oauth/connected-keys.d.mts +0 -2
- package/dist/internal/oauth/connected-keys.mjs +0 -22
- package/dist/internal/oauth/connected-keys.mjs.map +0 -1
- package/dist/internal/oauth/connected-maintenance.d.mts +0 -9
- package/dist/internal/oauth/connected-maintenance.mjs +0 -226
- package/dist/internal/oauth/connected-maintenance.mjs.map +0 -1
- package/dist/internal/oauth/connected-management.d.mts +0 -9
- package/dist/internal/oauth/connected-management.mjs +0 -243
- package/dist/internal/oauth/connected-management.mjs.map +0 -1
- package/dist/internal/oauth/connected-reference.mjs +0 -63
- package/dist/internal/oauth/connected-reference.mjs.map +0 -1
- package/dist/internal/oauth/connected-settlement.d.mts +0 -8
- package/dist/internal/oauth/connected-settlement.mjs +0 -141
- package/dist/internal/oauth/connected-settlement.mjs.map +0 -1
- package/dist/internal/oauth/connected-sign-in.d.mts +0 -10
- package/dist/internal/oauth/connected-sign-in.mjs +0 -281
- package/dist/internal/oauth/connected-sign-in.mjs.map +0 -1
- package/dist/internal/oauth/connected-state.d.mts +0 -14
- package/dist/internal/oauth/connected-state.mjs +0 -469
- package/dist/internal/oauth/connected-state.mjs.map +0 -1
- package/dist/internal/oauth/connected-target.d.mts +0 -21
- package/dist/internal/oauth/connected-target.mjs +0 -117
- package/dist/internal/oauth/connected-target.mjs.map +0 -1
- package/dist/internal/oauth/flow.d.mts +0 -5
- package/dist/internal/oauth/flow.mjs +0 -279
- package/dist/internal/oauth/flow.mjs.map +0 -1
- package/dist/internal/oauth/input.mjs +0 -127
- package/dist/internal/oauth/input.mjs.map +0 -1
- package/dist/internal/oauth/owner.d.mts +0 -10
- package/dist/internal/oauth/owner.mjs +0 -10
- package/dist/internal/oauth/owner.mjs.map +0 -1
- package/dist/internal/oauth/query-compiler.d.mts +0 -7
- package/dist/internal/oauth/query-compiler.mjs +0 -9
- package/dist/internal/oauth/query-compiler.mjs.map +0 -1
- package/dist/internal/oauth/registration.d.mts +0 -7
- package/dist/internal/oauth/registration.mjs +0 -393
- package/dist/internal/oauth/registration.mjs.map +0 -1
- package/dist/internal/oauth/target.d.mts +0 -31
- package/dist/internal/oauth/target.mjs +0 -273
- package/dist/internal/oauth/target.mjs.map +0 -1
- package/dist/internal/oauth-kernel.d.mts +0 -1423
- package/dist/internal/oauth-kernel.mjs +0 -187
- package/dist/internal/oauth-kernel.mjs.map +0 -1
- package/dist/internal/passkey/admission.d.mts +0 -6
- package/dist/internal/passkey/admission.mjs +0 -220
- package/dist/internal/passkey/admission.mjs.map +0 -1
- package/dist/internal/passkey/credentials.d.mts +0 -14
- package/dist/internal/passkey/credentials.mjs +0 -249
- package/dist/internal/passkey/credentials.mjs.map +0 -1
- package/dist/internal/passkey/enrollment.mjs +0 -138
- package/dist/internal/passkey/enrollment.mjs.map +0 -1
- package/dist/internal/passkey/flow.d.mts +0 -21
- package/dist/internal/passkey/flow.mjs +0 -452
- package/dist/internal/passkey/flow.mjs.map +0 -1
- package/dist/internal/passkey/management.mjs +0 -231
- package/dist/internal/passkey/management.mjs.map +0 -1
- package/dist/internal/passkey/registration-ceremony.d.mts +0 -9
- package/dist/internal/passkey/registration-ceremony.mjs +0 -129
- package/dist/internal/passkey/registration-ceremony.mjs.map +0 -1
- package/dist/internal/passkey/registration-custody.d.mts +0 -2
- package/dist/internal/passkey/registration-custody.mjs +0 -52
- package/dist/internal/passkey/registration-custody.mjs.map +0 -1
- package/dist/internal/passkey/registration-write.mjs +0 -211
- package/dist/internal/passkey/registration-write.mjs.map +0 -1
- package/dist/internal/passkey/state.d.mts +0 -10
- package/dist/internal/passkey/state.mjs +0 -234
- package/dist/internal/passkey/state.mjs.map +0 -1
- package/dist/internal/passkey/target.d.mts +0 -20
- package/dist/internal/passkey/target.mjs +0 -200
- package/dist/internal/passkey/target.mjs.map +0 -1
- package/dist/internal/passkey/write-state.d.mts +0 -17
- package/dist/internal/passkey/write-state.mjs +0 -354
- package/dist/internal/passkey/write-state.mjs.map +0 -1
- package/dist/internal/passkey/write-target.mjs +0 -192
- package/dist/internal/passkey/write-target.mjs.map +0 -1
- package/dist/internal/passkey-kernel.d.mts +0 -6045
- package/dist/internal/passkey-kernel.mjs +0 -49
- package/dist/internal/passkey-kernel.mjs.map +0 -1
- package/dist/internal/passkeys.d.mts +0 -7
- package/dist/internal/passkeys.mjs +0 -387
- package/dist/internal/passkeys.mjs.map +0 -1
- package/dist/internal/password-credentials.d.mts +0 -11
- package/dist/internal/password-kernel.d.mts +0 -278
- package/dist/internal/password-kernel.mjs +0 -508
- package/dist/internal/password-kernel.mjs.map +0 -1
- package/dist/internal/phone-kernel.d.mts +0 -162
- package/dist/internal/phone-kernel.mjs +0 -437
- package/dist/internal/phone-kernel.mjs.map +0 -1
- package/dist/internal/proof-kernel.d.mts +0 -94
- package/dist/internal/proof-kernel.mjs +0 -624
- package/dist/internal/proof-kernel.mjs.map +0 -1
- package/dist/internal/query-operations.d.mts +0 -68
- package/dist/internal/session-kernel.d.mts +0 -62
- package/dist/internal/session-kernel.mjs +0 -820
- package/dist/internal/session-kernel.mjs.map +0 -1
- package/dist/internal/sql-oauth-connected-model.mjs +0 -7
- package/dist/internal/sql-oauth-connected-model.mjs.map +0 -1
- package/dist/internal/sql-query.d.mts +0 -12
- package/dist/internal/sql-query.mjs +0 -206
- package/dist/internal/sql-query.mjs.map +0 -1
- package/dist/internal/step-up-state.d.mts +0 -49
- package/dist/internal/transaction-execution-kernel.d.mts +0 -37
- package/dist/internal/transaction-execution-kernel.mjs +0 -120
- package/dist/internal/transaction-execution-kernel.mjs.map +0 -1
- package/dist/internal/transaction-kernel.d.mts +0 -81
- package/dist/internal/transaction-kernel.mjs +0 -264
- package/dist/internal/transaction-kernel.mjs.map +0 -1
- package/src/internal/PasswordPreparedPostconditions.ts +0 -30
- package/src/internal/authority-snapshot.ts +0 -91
- package/src/internal/email-kernel.ts +0 -1556
- package/src/internal/oauth/accounts.ts +0 -839
- package/src/internal/oauth/connected-access.ts +0 -388
- package/src/internal/oauth/connected-collection.ts +0 -345
- package/src/internal/oauth/connected-custody.ts +0 -308
- package/src/internal/oauth/connected-flow.ts +0 -562
- package/src/internal/oauth/connected-input.ts +0 -147
- package/src/internal/oauth/connected-keys.ts +0 -31
- package/src/internal/oauth/connected-maintenance.ts +0 -379
- package/src/internal/oauth/connected-management.ts +0 -391
- package/src/internal/oauth/connected-reference.ts +0 -135
- package/src/internal/oauth/connected-settlement.ts +0 -278
- package/src/internal/oauth/connected-sign-in.ts +0 -472
- package/src/internal/oauth/connected-state.ts +0 -924
- package/src/internal/oauth/connected-target.ts +0 -307
- package/src/internal/oauth/flow.ts +0 -505
- package/src/internal/oauth/input.ts +0 -201
- package/src/internal/oauth/owner.ts +0 -22
- package/src/internal/oauth/query-compiler.ts +0 -15
- package/src/internal/oauth/registration.ts +0 -676
- package/src/internal/oauth/target.ts +0 -803
- package/src/internal/oauth-kernel.ts +0 -294
- package/src/internal/passkey/admission.ts +0 -368
- package/src/internal/passkey/credentials.ts +0 -511
- package/src/internal/passkey/enrollment.ts +0 -326
- package/src/internal/passkey/flow.ts +0 -1062
- package/src/internal/passkey/management.ts +0 -426
- package/src/internal/passkey/registration-ceremony.ts +0 -283
- package/src/internal/passkey/registration-custody.ts +0 -91
- package/src/internal/passkey/registration-write.ts +0 -426
- package/src/internal/passkey/state.ts +0 -351
- package/src/internal/passkey/target.ts +0 -598
- package/src/internal/passkey/write-state.ts +0 -692
- package/src/internal/passkey/write-target.ts +0 -450
- package/src/internal/passkey-kernel.ts +0 -112
- package/src/internal/passkeys.ts +0 -652
- package/src/internal/password-kernel.ts +0 -1523
- package/src/internal/phone-kernel.ts +0 -872
- package/src/internal/proof-kernel.ts +0 -1992
- package/src/internal/query-operations.ts +0 -91
- package/src/internal/session-kernel.ts +0 -2406
- package/src/internal/sql-query.ts +0 -304
- package/src/internal/transaction-execution-kernel.ts +0 -335
- package/src/internal/transaction-kernel.ts +0 -603
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { exactSqlText } from "./sql-change.mjs";
|
|
2
|
+
import { Effect, Option, Schema } from "effect";
|
|
3
|
+
import { EmailCredentialSnapshot, EmailUnavailable } from "@yielded/auth/Email";
|
|
4
|
+
import { AuthenticationRevision } from "@yielded/auth/Sessions";
|
|
5
|
+
import { SqlClient } from "effect/sql/SqlClient";
|
|
6
|
+
import { LoginIdentifier } from "@yielded/auth/Identity";
|
|
7
|
+
//#region src/internal/email-native-state.ts
|
|
8
|
+
const emailUnavailable = () => EmailUnavailable.make({});
|
|
9
|
+
const ensureEmail = (condition) => {
|
|
10
|
+
if (!condition) throw emailUnavailable();
|
|
11
|
+
};
|
|
12
|
+
/** Every role binds the decoded native subject through its own physical column codec. */
|
|
13
|
+
const makeNativeEmailReader = Effect.fnUntraced(function* (tables, mapping, engineNow) {
|
|
14
|
+
const sql = (yield* SqlClient).withoutTransforms();
|
|
15
|
+
const s = mapping.subject, i = mapping.identifier, c = mapping.credential, a = mapping.authorityCredential;
|
|
16
|
+
const subject = tables(s.table).as("email_subject"), targetIdentifier = tables(i.table).as("email_target_identifier"), sourceIdentifier = tables(i.table).as("email_source_identifier"), targetCredential = tables(c.table).as("email_target_credential"), sourceCredential = tables(c.table).as("email_source_credential"), authority = tables(a.table).as("email_authority"), sourceAuthority = tables(a.table).as("email_source_authority"), cardinality = tables(c.table).as("email_cardinality");
|
|
17
|
+
const exact = (t, key, value) => exactSqlText(sql, t.column(key), t.value(key, value));
|
|
18
|
+
const id = (t, key, value) => sql`${t.column(key)} = ${t.value(key, value)}`;
|
|
19
|
+
const identifierKey = (t, value) => sql.and([exact(t, i.namespace, value.namespace), exact(t, i.value, value.value)]);
|
|
20
|
+
const credentialKey = (t, moduleId, value) => sql.and([
|
|
21
|
+
exact(t, c.moduleId, moduleId),
|
|
22
|
+
exact(t, c.identifierNamespace, value.namespace),
|
|
23
|
+
exact(t, c.identifierValue, value.value)
|
|
24
|
+
]);
|
|
25
|
+
const selected = (t, row, prefix, key) => {
|
|
26
|
+
const decoded = t.decode(row, prefix);
|
|
27
|
+
return decoded[key] === null || decoded[key] === void 0 ? void 0 : decoded;
|
|
28
|
+
};
|
|
29
|
+
const owned = Effect.fnUntraced(function* (row, key, subjectId) {
|
|
30
|
+
return row !== void 0 && (yield* mapping.subjectId.toSubject(row[key])) === subjectId;
|
|
31
|
+
});
|
|
32
|
+
const read = Effect.fnUntraced(function* (input) {
|
|
33
|
+
const native = yield* mapping.subjectId.toNative(input.subjectId);
|
|
34
|
+
let source = input.sourceIdentifier;
|
|
35
|
+
if (input.sourceCredentialId !== void 0 && source === void 0) {
|
|
36
|
+
const table = tables(c.table);
|
|
37
|
+
const rows = yield* sql`select ${table.fields("email_source_lookup_")} from ${table.name} where ${exact(table, c.moduleId, input.moduleId)} and ${exact(table, c.credentialId, input.sourceCredentialId)} and ${id(table, c.subjectId, native)} limit 2`;
|
|
38
|
+
if (rows.length !== 1) return void 0;
|
|
39
|
+
const row = table.decode(rows[0], "email_source_lookup_");
|
|
40
|
+
ensureEmail(row[c.credentialId] === input.sourceCredentialId);
|
|
41
|
+
source = yield* Schema.decodeUnknownEffect(LoginIdentifier)({
|
|
42
|
+
namespace: row[c.identifierNamespace],
|
|
43
|
+
value: row[c.identifierValue]
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const rows = yield* sql`select ${subject.fields("email_subject_")}, ${targetIdentifier.fields("email_target_identifier_")}, ${sourceIdentifier.fields("email_source_identifier_")}, ${targetCredential.fields("email_target_credential_")}, ${sourceCredential.fields("email_source_credential_")}, ${authority.fields("email_authority_")}, ${sourceAuthority.fields("email_source_authority_")}, ${engineNow ?? sql`0`} as engine_now, case when ${input.single === true && input.sourceCredentialId === void 0 ? sql`exists(select 1 from ${cardinality.name} where ${id(cardinality, c.subjectId, native)} and ${exact(cardinality, c.moduleId, input.moduleId)} and ${id(cardinality, c.status, c.activeStatusValue)})` : sql`1 = 0`} then 1 else 0 end as cardinality_conflict
|
|
47
|
+
from ${subject.name}
|
|
48
|
+
left join ${targetIdentifier.name} on ${identifierKey(targetIdentifier, input.identifier)}
|
|
49
|
+
left join ${sourceIdentifier.name} on ${source === void 0 ? sql`1 = 0` : identifierKey(sourceIdentifier, source)}
|
|
50
|
+
left join ${targetCredential.name} on ${credentialKey(targetCredential, input.moduleId, input.identifier)}
|
|
51
|
+
left join ${sourceCredential.name} on ${input.sourceCredentialId === void 0 ? sql`1 = 0` : sql.and([exact(sourceCredential, c.moduleId, input.moduleId), exact(sourceCredential, c.credentialId, input.sourceCredentialId)])}
|
|
52
|
+
left join ${sourceAuthority.name} on ${input.sourceCredentialId === void 0 ? sql`1 = 0` : sql.and([id(sourceAuthority, a.subjectId, native), exact(sourceAuthority, a.credentialId, input.sourceCredentialId)])}
|
|
53
|
+
left join ${authority.name} on ${id(authority, a.subjectId, native)} and ${id(authority, a.status, a.activeStatusValue)}
|
|
54
|
+
where ${id(subject, s.id, native)} and ${input.validity ?? sql`1 = 1`} limit 65`;
|
|
55
|
+
ensureEmail(rows.length <= 64);
|
|
56
|
+
const first = rows[0];
|
|
57
|
+
if (first === void 0) return void 0;
|
|
58
|
+
const subjectRow = subject.decode(first, "email_subject_");
|
|
59
|
+
ensureEmail((yield* mapping.subjectId.toSubject(subjectRow[s.id])) === input.subjectId);
|
|
60
|
+
if (!s.isActiveStatus(subjectRow[s.status])) return void 0;
|
|
61
|
+
const factors = [];
|
|
62
|
+
for (const row of rows) {
|
|
63
|
+
const factor = selected(authority, row, "email_authority_", a.credentialId);
|
|
64
|
+
if (factor === void 0) continue;
|
|
65
|
+
ensureEmail((yield* owned(factor, a.subjectId, input.subjectId)) && a.isActiveStatus(factor[a.status]));
|
|
66
|
+
ensureEmail(!factors.some((f) => f.credentialId === factor[a.credentialId]));
|
|
67
|
+
factors.push({
|
|
68
|
+
credentialId: factor[a.credentialId],
|
|
69
|
+
revision: factor[a.revision]
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const revision = yield* Schema.decodeUnknownEffect(AuthenticationRevision)({
|
|
73
|
+
subjectId: input.subjectId,
|
|
74
|
+
securityRevision: subjectRow[s.securityRevision],
|
|
75
|
+
credentials: factors.sort((a, b) => String(a.credentialId).localeCompare(String(b.credentialId)))
|
|
76
|
+
});
|
|
77
|
+
const targetRow = selected(targetIdentifier, first, "email_target_identifier_", i.namespace), sourceRow = selected(sourceIdentifier, first, "email_source_identifier_", i.namespace), targetFactor = selected(targetCredential, first, "email_target_credential_", c.credentialId), sourceFactor = selected(sourceCredential, first, "email_source_credential_", c.credentialId);
|
|
78
|
+
const snapshot = Effect.fnUntraced(function* (identifierRow, credentialRow, value) {
|
|
79
|
+
if (identifierRow === void 0 || credentialRow === void 0 || value === void 0 || !i.isCurrent(identifierRow) || identifierRow[i.verifiedAt] === null || identifierRow[i.verifiedAt] === void 0 || !c.isActiveStatus(credentialRow[c.status]) || !(yield* owned(identifierRow, i.subjectId, input.subjectId)) || !(yield* owned(credentialRow, c.subjectId, input.subjectId))) return void 0;
|
|
80
|
+
ensureEmail(identifierRow[i.namespace] === value.namespace && identifierRow[i.value] === value.value && credentialRow[c.moduleId] === input.moduleId && credentialRow[c.identifierNamespace] === value.namespace && credentialRow[c.identifierValue] === value.value);
|
|
81
|
+
if (!revision.credentials.some((f) => f.credentialId === credentialRow[c.credentialId] && f.revision === credentialRow[c.credentialRevision])) return void 0;
|
|
82
|
+
const decoded = yield* c.decode({
|
|
83
|
+
moduleId: input.moduleId,
|
|
84
|
+
subject: subjectRow,
|
|
85
|
+
identifier: identifierRow,
|
|
86
|
+
credential: credentialRow
|
|
87
|
+
});
|
|
88
|
+
return yield* Schema.decodeEffect(EmailCredentialSnapshot)({
|
|
89
|
+
...decoded,
|
|
90
|
+
revision,
|
|
91
|
+
requirement: yield* s.decodeRequirement(subjectRow)
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
ensureEmail(targetRow === void 0 || targetRow[i.namespace] === input.identifier.namespace && targetRow[i.value] === input.identifier.value);
|
|
95
|
+
ensureEmail(targetFactor === void 0 || targetFactor[c.moduleId] === input.moduleId && targetFactor[c.identifierNamespace] === input.identifier.namespace && targetFactor[c.identifierValue] === input.identifier.value);
|
|
96
|
+
const now = Number(first.engine_now);
|
|
97
|
+
ensureEmail(Number.isSafeInteger(now));
|
|
98
|
+
return {
|
|
99
|
+
native,
|
|
100
|
+
subject: subjectRow,
|
|
101
|
+
revision,
|
|
102
|
+
targetIdentifier: targetRow,
|
|
103
|
+
sourceIdentifier: sourceRow,
|
|
104
|
+
targetCredential: targetFactor,
|
|
105
|
+
sourceCredential: sourceFactor,
|
|
106
|
+
sourceAuthority: selected(sourceAuthority, first, "email_source_authority_", a.credentialId),
|
|
107
|
+
targetSnapshot: yield* snapshot(targetRow, targetFactor, input.identifier),
|
|
108
|
+
sourceSnapshot: yield* snapshot(sourceRow, sourceFactor, source),
|
|
109
|
+
cardinalityConflict: Number(first.cardinality_conflict) === 1,
|
|
110
|
+
now
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
read,
|
|
115
|
+
lookup: Effect.fnUntraced(function* (input) {
|
|
116
|
+
const table = tables(i.table);
|
|
117
|
+
const rows = yield* sql`select ${table.fields("email_lookup_")} from ${table.name} where ${identifierKey(table, input.identifier)} limit 2`;
|
|
118
|
+
if (rows.length === 0) return Option.none();
|
|
119
|
+
ensureEmail(rows.length === 1);
|
|
120
|
+
const row = table.decode(rows[0], "email_lookup_");
|
|
121
|
+
ensureEmail(row[i.namespace] === input.identifier.namespace && row[i.value] === input.identifier.value);
|
|
122
|
+
if (!i.isCurrent(row) || row[i.verifiedAt] === null || row[i.verifiedAt] === void 0) return Option.none();
|
|
123
|
+
const subjectId = yield* mapping.subjectId.toSubject(row[i.subjectId]);
|
|
124
|
+
const result = yield* read({
|
|
125
|
+
...input,
|
|
126
|
+
subjectId
|
|
127
|
+
});
|
|
128
|
+
return Option.fromUndefinedOr(result?.targetSnapshot);
|
|
129
|
+
})
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
//#endregion
|
|
133
|
+
export { emailUnavailable, ensureEmail, makeNativeEmailReader };
|
|
134
|
+
|
|
135
|
+
//# sourceMappingURL=email-native-state.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-native-state.mjs","names":[],"sources":["../../src/internal/email-native-state.ts"],"sourcesContent":["import { EmailCredentialSnapshot, EmailUnavailable } from \"@yielded/auth/Email\";\nimport { LoginIdentifier } from \"@yielded/auth/Identity\";\nimport type { SubjectId } from \"@yielded/auth/Schema\";\nimport { AuthenticationRevision } from \"@yielded/auth/Sessions\";\nimport { Effect, Option, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { Fragment } from \"effect/sql/Statement\";\n\nimport type { AnyEmailSignInMapping } from \"./models/email-model\";\nimport type { NativeSqlTables, SqlTable } from \"./native-sql-table\";\nimport { exactSqlText } from \"./sql-change\";\n\nexport const emailUnavailable = () => EmailUnavailable.make({});\n\nexport const ensureEmail: (condition: unknown) => asserts condition = (condition) => {\n if (!condition) throw emailUnavailable();\n};\n\n/** Every role binds the decoded native subject through its own physical column codec. */\nexport const makeNativeEmailReader = Effect.fnUntraced(function* (\n tables: NativeSqlTables,\n mapping: AnyEmailSignInMapping,\n engineNow?: Fragment,\n) {\n const sql = (yield* SqlClient).withoutTransforms();\n\n const s = mapping.subject,\n i = mapping.identifier,\n c = mapping.credential,\n a = mapping.authorityCredential;\n\n const subject = tables(s.table).as(\"email_subject\"),\n targetIdentifier = tables(i.table).as(\"email_target_identifier\"),\n sourceIdentifier = tables(i.table).as(\"email_source_identifier\"),\n targetCredential = tables(c.table).as(\"email_target_credential\"),\n sourceCredential = tables(c.table).as(\"email_source_credential\"),\n authority = tables(a.table).as(\"email_authority\"),\n sourceAuthority = tables(a.table).as(\"email_source_authority\"),\n cardinality = tables(c.table).as(\"email_cardinality\");\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 identifierKey = (t: SqlTable, value: LoginIdentifier) =>\n sql.and([exact(t, i.namespace, value.namespace), exact(t, i.value, value.value)]);\n\n const credentialKey = (t: SqlTable, moduleId: string, value: LoginIdentifier) =>\n sql.and([\n exact(t, c.moduleId, moduleId),\n exact(t, c.identifierNamespace, value.namespace),\n exact(t, c.identifierValue, value.value),\n ]);\n\n const selected = (t: SqlTable, row: Record<string, unknown>, prefix: string, key: string) => {\n const decoded = t.decode(row, prefix);\n\n return decoded[key] === null || decoded[key] === undefined ? undefined : decoded;\n };\n\n const owned = Effect.fnUntraced(function* (\n row: Record<string, unknown> | undefined,\n key: string,\n subjectId: SubjectId,\n ) {\n return row !== undefined && (yield* mapping.subjectId.toSubject(row[key])) === subjectId;\n });\n\n const read = Effect.fnUntraced(function* (input: {\n readonly moduleId: string;\n readonly subjectId: SubjectId;\n readonly identifier: LoginIdentifier;\n readonly sourceCredentialId?: string;\n readonly sourceIdentifier?: LoginIdentifier;\n readonly single?: boolean;\n readonly validity?: Fragment;\n }) {\n const native = yield* mapping.subjectId.toNative(input.subjectId);\n let source = input.sourceIdentifier;\n\n if (input.sourceCredentialId !== undefined && source === undefined) {\n const table = tables(c.table);\n\n const rows =\n yield* sql`select ${table.fields(\"email_source_lookup_\")} from ${table.name} where ${exact(table, c.moduleId, input.moduleId)} and ${exact(table, c.credentialId, input.sourceCredentialId)} and ${id(table, c.subjectId, native)} limit 2`;\n\n if (rows.length !== 1) return undefined;\n const row = table.decode(rows[0]!, \"email_source_lookup_\");\n\n ensureEmail(row[c.credentialId] === input.sourceCredentialId);\n source = yield* Schema.decodeUnknownEffect(LoginIdentifier)({\n namespace: row[c.identifierNamespace],\n value: row[c.identifierValue],\n });\n }\n\n const rows =\n yield* sql`select ${subject.fields(\"email_subject_\")}, ${targetIdentifier.fields(\"email_target_identifier_\")}, ${sourceIdentifier.fields(\"email_source_identifier_\")}, ${targetCredential.fields(\"email_target_credential_\")}, ${sourceCredential.fields(\"email_source_credential_\")}, ${authority.fields(\"email_authority_\")}, ${sourceAuthority.fields(\"email_source_authority_\")}, ${engineNow ?? sql`0`} as engine_now, case when ${input.single === true && input.sourceCredentialId === undefined ? sql`exists(select 1 from ${cardinality.name} where ${id(cardinality, c.subjectId, native)} and ${exact(cardinality, c.moduleId, input.moduleId)} and ${id(cardinality, c.status, c.activeStatusValue)})` : sql`1 = 0`} then 1 else 0 end as cardinality_conflict\n from ${subject.name}\n left join ${targetIdentifier.name} on ${identifierKey(targetIdentifier, input.identifier)}\n left join ${sourceIdentifier.name} on ${source === undefined ? sql`1 = 0` : identifierKey(sourceIdentifier, source)}\n left join ${targetCredential.name} on ${credentialKey(targetCredential, input.moduleId, input.identifier)}\n left join ${sourceCredential.name} on ${input.sourceCredentialId === undefined ? sql`1 = 0` : sql.and([exact(sourceCredential, c.moduleId, input.moduleId), exact(sourceCredential, c.credentialId, input.sourceCredentialId)])}\n left join ${sourceAuthority.name} on ${input.sourceCredentialId === undefined ? sql`1 = 0` : sql.and([id(sourceAuthority, a.subjectId, native), exact(sourceAuthority, a.credentialId, input.sourceCredentialId)])}\n left join ${authority.name} on ${id(authority, a.subjectId, native)} and ${id(authority, a.status, a.activeStatusValue)}\n where ${id(subject, s.id, native)} and ${input.validity ?? sql`1 = 1`} limit 65`;\n\n ensureEmail(rows.length <= 64);\n const first = rows[0];\n\n if (first === undefined) return undefined;\n const subjectRow = subject.decode(first, \"email_subject_\");\n\n ensureEmail((yield* mapping.subjectId.toSubject(subjectRow[s.id])) === input.subjectId);\n if (!s.isActiveStatus(subjectRow[s.status])) return undefined;\n const factors: { readonly credentialId: unknown; readonly revision: unknown }[] = [];\n\n for (const row of rows) {\n const factor = selected(authority, row, \"email_authority_\", a.credentialId);\n\n if (factor === undefined) continue;\n ensureEmail(\n (yield* owned(factor, a.subjectId, input.subjectId)) && a.isActiveStatus(factor[a.status]),\n );\n ensureEmail(!factors.some((f) => f.credentialId === factor[a.credentialId]));\n factors.push({ credentialId: factor[a.credentialId], revision: factor[a.revision] });\n }\n\n const revision = yield* Schema.decodeUnknownEffect(AuthenticationRevision)({\n subjectId: input.subjectId,\n securityRevision: subjectRow[s.securityRevision],\n credentials: factors.sort((a, b) =>\n String(a.credentialId).localeCompare(String(b.credentialId)),\n ),\n });\n\n const targetRow = selected(targetIdentifier, first, \"email_target_identifier_\", i.namespace),\n sourceRow = selected(sourceIdentifier, first, \"email_source_identifier_\", i.namespace),\n targetFactor = selected(targetCredential, first, \"email_target_credential_\", c.credentialId),\n sourceFactor = selected(sourceCredential, first, \"email_source_credential_\", c.credentialId);\n\n const snapshot = Effect.fnUntraced(function* (\n identifierRow: Record<string, unknown> | undefined,\n credentialRow: Record<string, unknown> | undefined,\n value: LoginIdentifier | undefined,\n ) {\n if (\n identifierRow === undefined ||\n credentialRow === undefined ||\n value === undefined ||\n !i.isCurrent(identifierRow) ||\n identifierRow[i.verifiedAt] === null ||\n identifierRow[i.verifiedAt] === undefined ||\n !c.isActiveStatus(credentialRow[c.status]) ||\n !(yield* owned(identifierRow, i.subjectId, input.subjectId)) ||\n !(yield* owned(credentialRow, c.subjectId, input.subjectId))\n )\n return undefined;\n ensureEmail(\n identifierRow[i.namespace] === value.namespace &&\n identifierRow[i.value] === value.value &&\n credentialRow[c.moduleId] === input.moduleId &&\n credentialRow[c.identifierNamespace] === value.namespace &&\n credentialRow[c.identifierValue] === value.value,\n );\n if (\n !revision.credentials.some(\n (f) =>\n f.credentialId === credentialRow[c.credentialId] &&\n f.revision === credentialRow[c.credentialRevision],\n )\n )\n return undefined;\n\n const decoded = yield* c.decode({\n moduleId: input.moduleId,\n subject: subjectRow,\n identifier: identifierRow,\n credential: credentialRow,\n });\n\n return yield* Schema.decodeEffect(EmailCredentialSnapshot)({\n ...decoded,\n revision,\n requirement: yield* s.decodeRequirement(subjectRow),\n });\n });\n\n ensureEmail(\n targetRow === undefined ||\n (targetRow[i.namespace] === input.identifier.namespace &&\n targetRow[i.value] === input.identifier.value),\n );\n ensureEmail(\n targetFactor === undefined ||\n (targetFactor[c.moduleId] === input.moduleId &&\n targetFactor[c.identifierNamespace] === input.identifier.namespace &&\n targetFactor[c.identifierValue] === input.identifier.value),\n );\n const now = Number(first.engine_now);\n\n ensureEmail(Number.isSafeInteger(now));\n\n return {\n native,\n subject: subjectRow,\n revision,\n targetIdentifier: targetRow,\n sourceIdentifier: sourceRow,\n targetCredential: targetFactor,\n sourceCredential: sourceFactor,\n sourceAuthority: selected(sourceAuthority, first, \"email_source_authority_\", a.credentialId),\n targetSnapshot: yield* snapshot(targetRow, targetFactor, input.identifier),\n sourceSnapshot: yield* snapshot(sourceRow, sourceFactor, source),\n cardinalityConflict: Number(first.cardinality_conflict) === 1,\n now,\n };\n });\n\n const lookup = Effect.fnUntraced(function* (input: {\n readonly moduleId: string;\n readonly identifier: LoginIdentifier;\n }) {\n const table = tables(i.table);\n\n const rows =\n yield* sql`select ${table.fields(\"email_lookup_\")} from ${table.name} where ${identifierKey(table, input.identifier)} limit 2`;\n\n if (rows.length === 0) return Option.none();\n ensureEmail(rows.length === 1);\n const row = table.decode(rows[0]!, \"email_lookup_\");\n\n ensureEmail(\n row[i.namespace] === input.identifier.namespace && row[i.value] === input.identifier.value,\n );\n if (!i.isCurrent(row) || row[i.verifiedAt] === null || row[i.verifiedAt] === undefined)\n return Option.none();\n const subjectId = yield* mapping.subjectId.toSubject(row[i.subjectId]);\n const result = yield* read({ ...input, subjectId });\n\n return Option.fromUndefinedOr(result?.targetSnapshot);\n });\n\n return { read, lookup };\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnyProofPersistenceMapping } from "./models/proof-model.mjs";
|
|
2
|
+
import { AnyEmailAddressMapping, AnyEmailSignInMapping } from "./models/email-model.mjs";
|
|
3
|
+
import { NativeSqlTables } from "./native-sql-table.mjs";
|
|
4
|
+
import { SqlBatchCommit } from "./sql-commit.mjs";
|
|
5
|
+
import { Crypto, Effect } from "effect";
|
|
6
|
+
import * as E from "@yielded/auth/Email";
|
|
7
|
+
import { LifecycleHooks } from "@yielded/auth/Hooks";
|
|
8
|
+
import { SqlClient } from "effect/sql/SqlClient";
|
|
9
|
+
//#region src/internal/email-native.d.ts
|
|
10
|
+
export declare const makeNativeEmailSignInServices: (tables: NativeSqlTables, mapping: AnyEmailSignInMapping) => Effect.Effect<{
|
|
11
|
+
readonly emailSignInTargets: E.EmailSignInTargets["Service"];
|
|
12
|
+
}, never, LifecycleHooks | SqlClient>;
|
|
13
|
+
export declare const makeNativeEmailAddressServices: (tables: NativeSqlTables, mapping: AnyEmailAddressMapping, proofs?: AnyProofPersistenceMapping | undefined) => Effect.Effect<{
|
|
14
|
+
readonly emailAddressPersistence: E.EmailAddressPersistence["Service"];
|
|
15
|
+
}, never, Crypto.Crypto | LifecycleHooks | SqlBatchCommit | SqlClient>;
|
|
16
|
+
//#endregion
|
|
17
|
+
//# sourceMappingURL=email-native.d.mts.map
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { PersistenceMappingError } from "./mapping-error.mjs";
|
|
2
|
+
import { sqlBatchAssertion } from "./d1-planning.mjs";
|
|
3
|
+
import { exactSqlText, executeSqlChange } from "./sql-change.mjs";
|
|
4
|
+
import { emailUnavailable, ensureEmail, makeNativeEmailReader } from "./email-native-state.mjs";
|
|
5
|
+
import { passwordEvidenceSatisfiedAt } from "./password-policy.mjs";
|
|
6
|
+
import { allocateEmailSecurityRevision, allocateEmailValue, sameEmailRevision, snapshotEmailMutation, validateEmailMutation } from "./email-policy.mjs";
|
|
7
|
+
import { SqlBatchCommit, appendSqlBatchStatement, makeSqlCommitExecutor, registerSqlBatchPostcondition, registerSqlCommitReceipt, registerSqlPostcondition } from "./sql-commit.mjs";
|
|
8
|
+
import { makeNativeProofStore } from "./proof-native.mjs";
|
|
9
|
+
import { Crypto, DateTime, Effect, Schema } from "effect";
|
|
10
|
+
import * as E from "@yielded/auth/Email";
|
|
11
|
+
import { CurrentCommitJournal } from "@yielded/auth/Hooks";
|
|
12
|
+
import { ProofRedemptionInput } from "@yielded/auth/Proofs";
|
|
13
|
+
import { SecurityRevision } from "@yielded/auth/Sessions";
|
|
14
|
+
import { SqlClient } from "effect/sql/SqlClient";
|
|
15
|
+
//#region src/internal/email-native.ts
|
|
16
|
+
const makeNativeEmailSignInServices = Effect.fnUntraced(function* (tables, mapping) {
|
|
17
|
+
const executor = yield* makeSqlCommitExecutor(emailUnavailable);
|
|
18
|
+
const reader = yield* makeNativeEmailReader(tables, mapping);
|
|
19
|
+
return { emailSignInTargets: E.EmailSignInTargets.of({ lookup: (input) => executor.read(reader.lookup(input)) }) };
|
|
20
|
+
});
|
|
21
|
+
const makeNativeEmailAddressServices = Effect.fnUntraced(function* (tables, mapping, proofs) {
|
|
22
|
+
const batch = yield* SqlBatchCommit;
|
|
23
|
+
const sql = (yield* SqlClient).withoutTransforms(), executor = yield* makeSqlCommitExecutor(emailUnavailable), crypto = yield* Crypto.Crypto;
|
|
24
|
+
const now = tables.expression(mapping.clock.engineNowMillis);
|
|
25
|
+
const reader = yield* makeNativeEmailReader(tables, mapping, now);
|
|
26
|
+
const s = mapping.subject, i = mapping.identifier, c = mapping.credential, a = mapping.authorityCredential;
|
|
27
|
+
const subject = tables(s.table), identifier = tables(i.table), credential = tables(c.table), authority = tables(a.table);
|
|
28
|
+
const exact = (t, key, value) => exactSqlText(sql, t.column(key), t.value(key, value));
|
|
29
|
+
const id = (t, key, value) => sql`${t.column(key)} = ${t.value(key, value)}`;
|
|
30
|
+
const identifierKey = (value) => sql.and([exact(identifier, i.namespace, value.namespace), exact(identifier, i.value, value.value)]);
|
|
31
|
+
const activeSubject = id(subject, s.status, s.activeStatusValue), activeCredential = id(credential, c.status, c.activeStatusValue), activeAuthority = id(authority, a.status, a.activeStatusValue);
|
|
32
|
+
const lock = sql.onDialectOrElse({
|
|
33
|
+
sqlite: () => sql``,
|
|
34
|
+
orElse: () => sql`for update`
|
|
35
|
+
});
|
|
36
|
+
const mode = "interactive";
|
|
37
|
+
const run = (work) => batch === void 0 ? executor.run(work.pipe(Effect.provideService(Crypto.Crypto, crypto))) : executor.batch(work.pipe(Effect.provideService(Crypto.Crypto, crypto))).pipe(Effect.provideService(SqlBatchCommit, batch));
|
|
38
|
+
const stage = Effect.fnUntraced(function* (statement) {
|
|
39
|
+
if (batch === void 0) ensureEmail((yield* executeSqlChange(sql, statement)) === 1);
|
|
40
|
+
else {
|
|
41
|
+
yield* appendSqlBatchStatement(sql`${statement}`);
|
|
42
|
+
yield* appendSqlBatchStatement(sqlBatchAssertion(sql, sql`changes() = 1`));
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const prepare = (decision, project) => Effect.gen(function* () {
|
|
46
|
+
const receipt = project(decision, yield* CurrentCommitJournal);
|
|
47
|
+
yield* registerSqlCommitReceipt(receipt);
|
|
48
|
+
return receipt;
|
|
49
|
+
});
|
|
50
|
+
const target = Effect.fnUntraced(function* (input, sourceIdentifier) {
|
|
51
|
+
const state = yield* reader.read({
|
|
52
|
+
moduleId: input.moduleId,
|
|
53
|
+
subjectId: input.subjectId,
|
|
54
|
+
identifier: input.target,
|
|
55
|
+
...input.sourceCredentialId === void 0 ? {} : { sourceCredentialId: input.sourceCredentialId },
|
|
56
|
+
...sourceIdentifier === void 0 ? {} : { sourceIdentifier },
|
|
57
|
+
single: mapping.addressCardinality === "single"
|
|
58
|
+
});
|
|
59
|
+
if (state === void 0) return void 0;
|
|
60
|
+
const mutable = state.targetIdentifier !== void 0 && (yield* mapping.subjectId.toSubject(state.targetIdentifier[i.subjectId])) === input.subjectId && mapping.identifier.isMutableTarget(state.targetIdentifier) && (state.targetCredential === void 0 || !c.isActiveStatus(state.targetCredential[c.status]) && (yield* mapping.subjectId.toSubject(state.targetCredential[c.subjectId])) === input.subjectId);
|
|
61
|
+
const source = state.sourceSnapshot;
|
|
62
|
+
const eligible = (state.targetIdentifier === void 0 ? state.targetCredential === void 0 : mutable) && (input.sourceCredentialId === void 0 || source !== void 0) && (source === void 0 || source.identifier.namespace !== input.target.namespace || source.identifier.value !== input.target.value) && !state.cardinalityConflict;
|
|
63
|
+
const captured = {
|
|
64
|
+
revision: state.revision,
|
|
65
|
+
eligible,
|
|
66
|
+
...source === void 0 ? {} : { source },
|
|
67
|
+
...mutable ? { targetIdentifierRevision: yield* Schema.decodeUnknownEffect(SecurityRevision)(state.targetIdentifier[i.bindingRevision]) } : {}
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
...state,
|
|
71
|
+
target: captured
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
const mutate = (original, action, project) => run(Effect.gen(function* () {
|
|
75
|
+
const input = yield* snapshotEmailMutation(original);
|
|
76
|
+
const redemption = yield* Schema.decodeEffect(Schema.toCodecIso(ProofRedemptionInput))(yield* Schema.encodeEffect(Schema.toCodecIso(ProofRedemptionInput))(original.redemption.input));
|
|
77
|
+
const native = yield* mapping.subjectId.toNative(input.captured.revision.subjectId);
|
|
78
|
+
const locked = yield* sql`select ${subject.fields("email_locked_")} from ${subject.name} where ${id(subject, s.id, native)} limit 2 ${batch === void 0 ? lock : sql``}`;
|
|
79
|
+
if (locked.length !== 1) return yield* prepare("rejected", project);
|
|
80
|
+
ensureEmail((yield* mapping.subjectId.toSubject(subject.decode(locked[0], "email_locked_")[s.id])) === input.captured.revision.subjectId);
|
|
81
|
+
const current = yield* target({
|
|
82
|
+
moduleId: input.moduleId,
|
|
83
|
+
subjectId: input.captured.revision.subjectId,
|
|
84
|
+
target: input.target,
|
|
85
|
+
...input.captured.source === void 0 ? {} : { sourceCredentialId: input.captured.source.credentialId }
|
|
86
|
+
}, input.captured.source?.identifier);
|
|
87
|
+
if (current === void 0 || proofs === void 0) return yield* prepare("rejected", project);
|
|
88
|
+
const requirement = yield* s.decodeActionRequirement(current.subject, action);
|
|
89
|
+
if (!(yield* validateEmailMutation(mapping, {
|
|
90
|
+
...input,
|
|
91
|
+
redemption: {
|
|
92
|
+
input: redemption,
|
|
93
|
+
prepare: original.redemption.prepare
|
|
94
|
+
}
|
|
95
|
+
}, action, {
|
|
96
|
+
target: current.target,
|
|
97
|
+
requirement: Effect.succeed(requirement)
|
|
98
|
+
}, current.now))) return yield* prepare("rejected", project);
|
|
99
|
+
const requirements = [input.authorization.requirement, requirement];
|
|
100
|
+
const deadline = [...new Set(input.authorization.evidence.proofs.flatMap((proof) => requirements.map((r) => DateTime.toEpochMillis(proof.verifiedAt) + r.maximumAgeMillis)))].filter((time) => time > current.now).sort((a, b) => a - b).find((time) => requirements.some((r) => !passwordEvidenceSatisfiedAt(input.authorization.evidence, r, time)));
|
|
101
|
+
ensureEmail(deadline !== void 0);
|
|
102
|
+
const freshness = sql`${now} >= ${current.now} and ${now} < ${deadline}`;
|
|
103
|
+
const factorCondition = (revision) => sql.and([sql`(select count(*) from ${authority.name} where ${id(authority, a.subjectId, native)} and ${activeAuthority}) = ${revision.credentials.length}`, ...revision.credentials.map((f) => sql`exists(select 1 from ${authority.name} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, f.credentialId)} and ${exact(authority, a.revision, f.revision)} and ${activeAuthority})`)]);
|
|
104
|
+
if (batch !== void 0) {
|
|
105
|
+
yield* appendSqlBatchStatement(sqlBatchAssertion(sql, sql.and([
|
|
106
|
+
sql`exists(select 1 from ${subject.name} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, current.revision.securityRevision)} and ${activeSubject})`,
|
|
107
|
+
factorCondition(current.revision),
|
|
108
|
+
freshness
|
|
109
|
+
])));
|
|
110
|
+
if (current.targetIdentifier !== void 0) {
|
|
111
|
+
ensureEmail(i.d1MutableTargetCondition !== void 0);
|
|
112
|
+
yield* appendSqlBatchStatement(sqlBatchAssertion(sql, sql`exists(select 1 from ${identifier.name} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${tables.expression(i.d1MutableTargetCondition({
|
|
113
|
+
identifier: input.target,
|
|
114
|
+
nativeSubjectId: native
|
|
115
|
+
}))})`));
|
|
116
|
+
}
|
|
117
|
+
if (current.target.source !== void 0) {
|
|
118
|
+
ensureEmail(i.d1CurrentCondition !== void 0);
|
|
119
|
+
yield* appendSqlBatchStatement(sqlBatchAssertion(sql, sql`exists(select 1 from ${identifier.name} where ${identifierKey(current.target.source.identifier)} and ${id(identifier, i.subjectId, native)} and ${tables.expression(i.d1CurrentCondition({
|
|
120
|
+
identifier: current.target.source.identifier,
|
|
121
|
+
nativeSubjectId: native,
|
|
122
|
+
bindingRevision: current.target.source.identifierRevision
|
|
123
|
+
}))})`));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const redeemed = yield* (yield* makeNativeProofStore(tables, proofs, batch !== void 0)).redeemLocked(redemption);
|
|
127
|
+
yield* registerSqlCommitReceipt(original.redemption.prepare(redeemed.decision, yield* CurrentCommitJournal, (value) => value));
|
|
128
|
+
if (redeemed.decision !== "redeemed") return yield* prepare("rejected", project);
|
|
129
|
+
const allocate = () => allocateEmailValue(mode, mapping.allocateRevision, mapping.allocateRevisionSync);
|
|
130
|
+
const targetIdentifierRevision = yield* allocate(), targetCredentialRevision = yield* allocate(), sourceIdentifierRevision = yield* allocate(), sourceCredentialRevision = yield* allocate();
|
|
131
|
+
const confirms = action === "verify-address" && current.target.targetIdentifierRevision !== void 0;
|
|
132
|
+
const nextSecurityRevision = confirms ? current.revision.securityRevision : yield* allocateEmailSecurityRevision(mapping, mode, current.revision.securityRevision);
|
|
133
|
+
ensureEmail(confirms || nextSecurityRevision !== current.revision.securityRevision);
|
|
134
|
+
const targetCredentialId = current.targetCredential === void 0 ? yield* allocateEmailValue(mode, mapping.allocateCredentialId, mapping.allocateCredentialIdSync) : yield* Schema.decodeUnknownEffect(Schema.String)(current.targetCredential[c.credentialId]);
|
|
135
|
+
const source = current.target.source;
|
|
136
|
+
if (action === "change-address") {
|
|
137
|
+
ensureEmail(source !== void 0);
|
|
138
|
+
yield* stage(sql`${identifier.update(i.encodeRetirement({
|
|
139
|
+
source: source.identifier,
|
|
140
|
+
bindingRevision: sourceIdentifierRevision
|
|
141
|
+
}))} where ${identifierKey(source.identifier)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, source.identifierRevision)}`);
|
|
142
|
+
yield* stage(sql`${credential.update(c.encodeRetirement({
|
|
143
|
+
source: source.identifier,
|
|
144
|
+
credentialRevision: sourceCredentialRevision
|
|
145
|
+
}))} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, source.credentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, source.credentialRevision)} and ${activeCredential}`);
|
|
146
|
+
yield* stage(sql`${authority.update(a.encodeRetirement(sourceCredentialRevision))} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, source.credentialId)} and ${exact(authority, a.revision, source.credentialRevision)} and ${activeAuthority}`);
|
|
147
|
+
}
|
|
148
|
+
if (current.targetIdentifier === void 0) yield* stage(identifier.insert(i.encodeVerifiedInsert({
|
|
149
|
+
identifier: input.target,
|
|
150
|
+
subjectId: native,
|
|
151
|
+
verifiedAtMillis: current.now,
|
|
152
|
+
bindingRevision: targetIdentifierRevision
|
|
153
|
+
})));
|
|
154
|
+
else yield* stage(sql`${identifier.update(i.encodeVerification({
|
|
155
|
+
verifiedAtMillis: current.now,
|
|
156
|
+
bindingRevision: targetIdentifierRevision
|
|
157
|
+
}))} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, current.targetIdentifier[i.bindingRevision])} and ${identifier.column(i.verifiedAt)} is null`);
|
|
158
|
+
if (current.targetCredential === void 0) {
|
|
159
|
+
yield* stage(credential.insert(c.encodeVerifiedInsert({
|
|
160
|
+
moduleId: input.moduleId,
|
|
161
|
+
subjectId: native,
|
|
162
|
+
credentialId: targetCredentialId,
|
|
163
|
+
identifier: input.target,
|
|
164
|
+
credentialRevision: targetCredentialRevision
|
|
165
|
+
})));
|
|
166
|
+
yield* stage(authority.insert(a.encodeInsert({
|
|
167
|
+
subjectId: native,
|
|
168
|
+
credentialId: targetCredentialId,
|
|
169
|
+
revision: targetCredentialRevision
|
|
170
|
+
})));
|
|
171
|
+
} else {
|
|
172
|
+
const old = current.targetCredential[c.credentialRevision];
|
|
173
|
+
yield* stage(sql`${credential.update(c.encodeActivation({
|
|
174
|
+
identifier: input.target,
|
|
175
|
+
credentialRevision: targetCredentialRevision
|
|
176
|
+
}))} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, targetCredentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, old)}`);
|
|
177
|
+
yield* stage(sql`${authority.update(a.encodeActivation(targetCredentialRevision))} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, targetCredentialId)} and ${exact(authority, a.revision, old)}`);
|
|
178
|
+
}
|
|
179
|
+
if (!confirms) yield* stage(sql`${subject.update({ [s.securityRevision]: nextSecurityRevision })} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, current.revision.securityRevision)} and ${activeSubject} and ${freshness}`);
|
|
180
|
+
const revision = {
|
|
181
|
+
subjectId: current.revision.subjectId,
|
|
182
|
+
securityRevision: nextSecurityRevision,
|
|
183
|
+
credentials: [...current.revision.credentials.filter((f) => f.credentialId !== targetCredentialId && f.credentialId !== source?.credentialId), {
|
|
184
|
+
credentialId: targetCredentialId,
|
|
185
|
+
revision: targetCredentialRevision
|
|
186
|
+
}].sort((a, b) => a.credentialId.localeCompare(b.credentialId))
|
|
187
|
+
};
|
|
188
|
+
if (batch !== void 0) {
|
|
189
|
+
ensureEmail(i.d1CurrentCondition !== void 0);
|
|
190
|
+
const conditions = [
|
|
191
|
+
redeemed.validUntil,
|
|
192
|
+
freshness,
|
|
193
|
+
factorCondition(revision),
|
|
194
|
+
sql`exists(select 1 from ${subject.name} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, nextSecurityRevision)} and ${activeSubject})`,
|
|
195
|
+
sql`exists(select 1 from ${identifier.name} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${tables.expression(i.d1CurrentCondition({
|
|
196
|
+
identifier: input.target,
|
|
197
|
+
nativeSubjectId: native,
|
|
198
|
+
bindingRevision: targetIdentifierRevision
|
|
199
|
+
}))})`,
|
|
200
|
+
sql`exists(select 1 from ${identifier.name} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, targetIdentifierRevision)} and ${id(identifier, i.verifiedAt, mapping.clock.encodeInstant(current.now))})`,
|
|
201
|
+
sql`exists(select 1 from ${credential.name} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, targetCredentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, targetCredentialRevision)} and ${exact(credential, c.identifierNamespace, input.target.namespace)} and ${exact(credential, c.identifierValue, input.target.value)} and ${activeCredential})`
|
|
202
|
+
];
|
|
203
|
+
if (source !== void 0) conditions.push(sql`exists(select 1 from ${identifier.name} where ${identifierKey(source.identifier)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, sourceIdentifierRevision)} and not (${tables.expression(i.d1CurrentCondition({
|
|
204
|
+
identifier: source.identifier,
|
|
205
|
+
nativeSubjectId: native,
|
|
206
|
+
bindingRevision: sourceIdentifierRevision
|
|
207
|
+
}))}))`, sql`exists(select 1 from ${credential.name} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, source.credentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, sourceCredentialRevision)} and not (${activeCredential}))`, sql`exists(select 1 from ${authority.name} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, source.credentialId)} and ${exact(authority, a.revision, sourceCredentialRevision)} and not (${activeAuthority}))`);
|
|
208
|
+
yield* registerSqlBatchPostcondition({
|
|
209
|
+
name: "email-address-authority",
|
|
210
|
+
statement: sqlBatchAssertion(sql, sql.and(conditions))
|
|
211
|
+
});
|
|
212
|
+
} else yield* registerSqlPostcondition({
|
|
213
|
+
name: "email-address-authority",
|
|
214
|
+
check: Effect.gen(function* () {
|
|
215
|
+
const final = yield* reader.read({
|
|
216
|
+
validity: redeemed.validUntil,
|
|
217
|
+
moduleId: input.moduleId,
|
|
218
|
+
subjectId: revision.subjectId,
|
|
219
|
+
identifier: input.target,
|
|
220
|
+
...source === void 0 ? {} : {
|
|
221
|
+
sourceCredentialId: source.credentialId,
|
|
222
|
+
sourceIdentifier: source.identifier
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
ensureEmail(final !== void 0 && sameEmailRevision(final.revision, revision) && final.now >= current.now && final.now < deadline && final.targetSnapshot !== void 0 && final.targetSnapshot.credentialId === targetCredentialId && final.targetSnapshot.credentialRevision === targetCredentialRevision && final.targetSnapshot.identifierRevision === targetIdentifierRevision && (yield* mapping.decodeInstant(final.targetIdentifier[i.verifiedAt])) === current.now);
|
|
226
|
+
const policy = yield* s.decodeActionRequirement(final.subject, action);
|
|
227
|
+
ensureEmail(passwordEvidenceSatisfiedAt(input.authorization.evidence, policy, final.now));
|
|
228
|
+
if (source !== void 0) ensureEmail(final.sourceIdentifier !== void 0 && final.sourceCredential !== void 0 && final.sourceAuthority !== void 0 && (yield* mapping.subjectId.toSubject(final.sourceAuthority[a.subjectId])) === revision.subjectId && final.sourceAuthority[a.credentialId] === source.credentialId && final.sourceAuthority[a.revision] === sourceCredentialRevision && !a.isActiveStatus(final.sourceAuthority[a.status]) && (yield* mapping.subjectId.toSubject(final.sourceIdentifier[i.subjectId])) === revision.subjectId && final.sourceIdentifier[i.bindingRevision] === sourceIdentifierRevision && !i.isCurrent(final.sourceIdentifier) && final.sourceCredential[c.credentialRevision] === sourceCredentialRevision && !c.isActiveStatus(final.sourceCredential[c.status]));
|
|
229
|
+
}).pipe(Effect.mapError((cause) => PersistenceMappingError.make({
|
|
230
|
+
operation: "decode",
|
|
231
|
+
cause
|
|
232
|
+
})))
|
|
233
|
+
});
|
|
234
|
+
return yield* prepare("changed", project);
|
|
235
|
+
}));
|
|
236
|
+
return { emailAddressPersistence: E.EmailAddressPersistence.of({
|
|
237
|
+
target: (input) => executor.read(Effect.flatMap(target(input), (value) => value === void 0 ? Effect.fail(emailUnavailable()) : Effect.succeed(value.target))),
|
|
238
|
+
verifyWithProof: (input, project) => mutate(input, "verify-address", project),
|
|
239
|
+
changeWithProof: (input, project) => mutate(input, "change-address", project)
|
|
240
|
+
}) };
|
|
241
|
+
});
|
|
242
|
+
//#endregion
|
|
243
|
+
export { makeNativeEmailAddressServices, makeNativeEmailSignInServices };
|
|
244
|
+
|
|
245
|
+
//# sourceMappingURL=email-native.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-native.mjs","names":["unavailable"],"sources":["../../src/internal/email-native.ts"],"sourcesContent":["import * as E from \"@yielded/auth/Email\";\nimport { CurrentCommitJournal, type LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport { ProofRedemptionInput } from \"@yielded/auth/Proofs\";\nimport type { AuthenticationRevision } from \"@yielded/auth/Sessions\";\nimport { SecurityRevision } from \"@yielded/auth/Sessions\";\nimport { Crypto, DateTime, Effect, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { Fragment } from \"effect/sql/Statement\";\n\nimport { sqlBatchAssertion } from \"./d1-planning\";\nimport {\n makeNativeEmailReader,\n emailUnavailable as unavailable,\n ensureEmail as ensure,\n} from \"./email-native-state\";\nimport {\n allocateEmailValue,\n allocateEmailSecurityRevision,\n snapshotEmailMutation,\n validateEmailMutation,\n sameEmailRevision,\n} from \"./email-policy\";\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { AnyEmailAddressMapping, AnyEmailSignInMapping } from \"./models/email-model\";\nimport type { AnyProofPersistenceMapping } from \"./models/proof-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 makeSqlCommitExecutor,\n registerSqlBatchPostcondition,\n registerSqlCommitReceipt,\n registerSqlPostcondition,\n SqlBatchCommit,\n} from \"./sql-commit\";\n\nexport const makeNativeEmailSignInServices = Effect.fnUntraced(function* (\n tables: NativeSqlTables,\n mapping: AnyEmailSignInMapping,\n): Effect.fn.Return<\n { readonly emailSignInTargets: E.EmailSignInTargets[\"Service\"] },\n never,\n SqlClient | LifecycleHooks\n> {\n const executor = yield* makeSqlCommitExecutor(unavailable);\n const reader = yield* makeNativeEmailReader(tables, mapping);\n\n return {\n emailSignInTargets: E.EmailSignInTargets.of({\n lookup: (input) => executor.read(reader.lookup(input)),\n }),\n };\n});\n\nexport const makeNativeEmailAddressServices = Effect.fnUntraced(function* (\n tables: NativeSqlTables,\n mapping: AnyEmailAddressMapping,\n proofs?: AnyProofPersistenceMapping,\n): Effect.fn.Return<\n { readonly emailAddressPersistence: E.EmailAddressPersistence[\"Service\"] },\n never,\n SqlClient | LifecycleHooks | Crypto.Crypto | SqlBatchCommit\n> {\n const batch = yield* SqlBatchCommit;\n\n const sql = (yield* SqlClient).withoutTransforms(),\n executor = yield* makeSqlCommitExecutor(unavailable),\n crypto = yield* Crypto.Crypto;\n\n const now = tables.expression(mapping.clock.engineNowMillis);\n const reader = yield* makeNativeEmailReader(tables, mapping, now);\n\n const s = mapping.subject,\n i = mapping.identifier,\n c = mapping.credential,\n a = mapping.authorityCredential;\n\n const subject = tables(s.table),\n identifier = tables(i.table),\n credential = tables(c.table),\n authority = tables(a.table);\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 identifierKey = (value: { readonly namespace: string; readonly value: string }) =>\n sql.and([\n exact(identifier, i.namespace, value.namespace),\n exact(identifier, i.value, value.value),\n ]);\n\n const activeSubject = id(subject, s.status, s.activeStatusValue),\n activeCredential = id(credential, c.status, c.activeStatusValue),\n activeAuthority = id(authority, a.status, a.activeStatusValue);\n\n const lock = sql.onDialectOrElse({ sqlite: () => sql``, orElse: () => sql`for update` });\n const mode = \"interactive\";\n\n const run = <A, X, R>(work: Effect.Effect<A, X, R>) =>\n batch === undefined\n ? executor.run(work.pipe(Effect.provideService(Crypto.Crypto, crypto)))\n : executor\n .batch(work.pipe(Effect.provideService(Crypto.Crypto, crypto)))\n .pipe(Effect.provideService(SqlBatchCommit, batch));\n\n const stage = Effect.fnUntraced(function* (statement: Fragment) {\n if (batch === undefined) ensure((yield* executeSqlChange(sql, statement)) === 1);\n else {\n yield* appendSqlBatchStatement(sql`${statement}`);\n yield* appendSqlBatchStatement(sqlBatchAssertion(sql, sql`changes() = 1`));\n }\n });\n\n const prepare = <A>(\n decision: E.EmailAddressDecision,\n project: E.PrepareEmailCommit<E.EmailAddressDecision, A>,\n ) =>\n Effect.gen(function* () {\n const receipt = project(decision, yield* CurrentCommitJournal);\n\n yield* registerSqlCommitReceipt(receipt);\n\n return receipt;\n });\n\n const target = Effect.fnUntraced(function* (\n input: Parameters<E.EmailAddressPersistence[\"Service\"][\"target\"]>[0],\n sourceIdentifier?: { readonly namespace: string; readonly value: string },\n ) {\n const state = yield* reader.read({\n moduleId: input.moduleId,\n subjectId: input.subjectId,\n identifier: input.target,\n ...(input.sourceCredentialId === undefined\n ? {}\n : { sourceCredentialId: input.sourceCredentialId }),\n ...(sourceIdentifier === undefined ? {} : { sourceIdentifier }),\n single: mapping.addressCardinality === \"single\",\n });\n\n if (state === undefined) return undefined;\n\n const owned =\n state.targetIdentifier !== undefined &&\n (yield* mapping.subjectId.toSubject(state.targetIdentifier[i.subjectId])) === input.subjectId;\n\n const mutable =\n owned &&\n mapping.identifier.isMutableTarget(state.targetIdentifier!) &&\n (state.targetCredential === undefined ||\n (!c.isActiveStatus(state.targetCredential[c.status]) &&\n (yield* mapping.subjectId.toSubject(state.targetCredential[c.subjectId])) ===\n input.subjectId));\n\n const source = state.sourceSnapshot;\n\n const eligible =\n (state.targetIdentifier === undefined ? state.targetCredential === undefined : mutable) &&\n (input.sourceCredentialId === undefined || source !== undefined) &&\n (source === undefined ||\n source.identifier.namespace !== input.target.namespace ||\n source.identifier.value !== input.target.value) &&\n !state.cardinalityConflict;\n\n const captured: E.EmailAddressTarget = {\n revision: state.revision,\n eligible,\n ...(source === undefined ? {} : { source }),\n ...(mutable\n ? {\n targetIdentifierRevision: yield* Schema.decodeUnknownEffect(SecurityRevision)(\n state.targetIdentifier![i.bindingRevision],\n ),\n }\n : {}),\n };\n\n return { ...state, target: captured };\n });\n\n const mutate = <A>(\n original: E.EmailAddressMutation,\n action: E.EmailAction,\n project: E.PrepareEmailCommit<E.EmailAddressDecision, A>,\n ) =>\n run(\n Effect.gen(function* () {\n const input = yield* snapshotEmailMutation(original);\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 native = yield* mapping.subjectId.toNative(input.captured.revision.subjectId);\n\n const locked =\n yield* sql`select ${subject.fields(\"email_locked_\")} from ${subject.name} where ${id(subject, s.id, native)} limit 2 ${batch === undefined ? lock : sql``}`;\n\n if (locked.length !== 1) return yield* prepare(\"rejected\", project);\n ensure(\n (yield* mapping.subjectId.toSubject(\n subject.decode(locked[0]!, \"email_locked_\")[s.id],\n )) === input.captured.revision.subjectId,\n );\n\n const current = yield* target(\n {\n moduleId: input.moduleId,\n subjectId: input.captured.revision.subjectId,\n target: input.target,\n ...(input.captured.source === undefined\n ? {}\n : { sourceCredentialId: input.captured.source.credentialId }),\n },\n input.captured.source?.identifier,\n );\n\n if (current === undefined || proofs === undefined)\n return yield* prepare(\"rejected\", project);\n const requirement = yield* s.decodeActionRequirement(current.subject, action);\n\n if (\n !(yield* validateEmailMutation(\n mapping,\n { ...input, redemption: { input: redemption, prepare: original.redemption.prepare } },\n action,\n { target: current.target, requirement: Effect.succeed(requirement) },\n current.now,\n ))\n )\n return yield* prepare(\"rejected\", project);\n const requirements = [input.authorization.requirement, requirement];\n\n const boundaries = [\n ...new Set(\n input.authorization.evidence.proofs.flatMap((proof) =>\n requirements.map(\n (r) => DateTime.toEpochMillis(proof.verifiedAt) + r.maximumAgeMillis,\n ),\n ),\n ),\n ]\n .filter((time) => time > current.now)\n .sort((a, b) => a - b);\n\n const deadline = boundaries.find((time) =>\n requirements.some(\n (r) => !passwordEvidenceSatisfiedAt(input.authorization.evidence, r, time),\n ),\n );\n\n ensure(deadline !== undefined);\n const freshness = sql`${now} >= ${current.now} and ${now} < ${deadline}`;\n\n const factorCondition = (revision: AuthenticationRevision) =>\n sql.and([\n sql`(select count(*) from ${authority.name} where ${id(authority, a.subjectId, native)} and ${activeAuthority}) = ${revision.credentials.length}`,\n ...revision.credentials.map(\n (f) =>\n sql`exists(select 1 from ${authority.name} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, f.credentialId)} and ${exact(authority, a.revision, f.revision)} and ${activeAuthority})`,\n ),\n ]);\n\n if (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, current.revision.securityRevision)} and ${activeSubject})`,\n factorCondition(current.revision),\n freshness,\n ]),\n ),\n );\n if (current.targetIdentifier !== undefined) {\n ensure(i.d1MutableTargetCondition !== undefined);\n yield* appendSqlBatchStatement(\n sqlBatchAssertion(\n sql,\n sql`exists(select 1 from ${identifier.name} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${tables.expression(i.d1MutableTargetCondition({ identifier: input.target, nativeSubjectId: native }))})`,\n ),\n );\n }\n if (current.target.source !== undefined) {\n ensure(i.d1CurrentCondition !== undefined);\n yield* appendSqlBatchStatement(\n sqlBatchAssertion(\n sql,\n sql`exists(select 1 from ${identifier.name} where ${identifierKey(current.target.source.identifier)} and ${id(identifier, i.subjectId, native)} and ${tables.expression(i.d1CurrentCondition({ identifier: current.target.source.identifier, nativeSubjectId: native, bindingRevision: current.target.source.identifierRevision }))})`,\n ),\n );\n }\n }\n\n const proof = yield* makeNativeProofStore(tables, proofs, batch !== undefined),\n redeemed = yield* proof.redeemLocked(redemption);\n\n yield* registerSqlCommitReceipt(\n original.redemption.prepare(\n redeemed.decision,\n yield* CurrentCommitJournal,\n (value) => value,\n ),\n );\n if (redeemed.decision !== \"redeemed\") return yield* prepare(\"rejected\", project);\n\n const allocate = () =>\n allocateEmailValue(mode, mapping.allocateRevision, mapping.allocateRevisionSync);\n\n const targetIdentifierRevision = yield* allocate(),\n targetCredentialRevision = yield* allocate(),\n sourceIdentifierRevision = yield* allocate(),\n sourceCredentialRevision = yield* allocate();\n\n const confirms =\n action === \"verify-address\" && current.target.targetIdentifierRevision !== undefined;\n\n const nextSecurityRevision = confirms\n ? current.revision.securityRevision\n : yield* allocateEmailSecurityRevision(mapping, mode, current.revision.securityRevision);\n\n ensure(confirms || nextSecurityRevision !== current.revision.securityRevision);\n\n const targetCredentialId =\n current.targetCredential === undefined\n ? yield* allocateEmailValue(\n mode,\n mapping.allocateCredentialId,\n mapping.allocateCredentialIdSync,\n )\n : yield* Schema.decodeUnknownEffect(Schema.String)(\n current.targetCredential[c.credentialId],\n );\n\n const source = current.target.source;\n\n if (action === \"change-address\") {\n ensure(source !== undefined);\n yield* stage(\n sql`${identifier.update(i.encodeRetirement({ source: source.identifier, bindingRevision: sourceIdentifierRevision }))} where ${identifierKey(source.identifier)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, source.identifierRevision)}`,\n );\n yield* stage(\n sql`${credential.update(c.encodeRetirement({ source: source.identifier, credentialRevision: sourceCredentialRevision }))} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, source.credentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, source.credentialRevision)} and ${activeCredential}`,\n );\n yield* stage(\n sql`${authority.update(a.encodeRetirement(sourceCredentialRevision))} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, source.credentialId)} and ${exact(authority, a.revision, source.credentialRevision)} and ${activeAuthority}`,\n );\n }\n if (current.targetIdentifier === undefined)\n yield* stage(\n identifier.insert(\n i.encodeVerifiedInsert({\n identifier: input.target,\n subjectId: native,\n verifiedAtMillis: current.now,\n bindingRevision: targetIdentifierRevision,\n }),\n ),\n );\n else\n yield* stage(\n sql`${identifier.update(i.encodeVerification({ verifiedAtMillis: current.now, bindingRevision: targetIdentifierRevision }))} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, current.targetIdentifier[i.bindingRevision])} and ${identifier.column(i.verifiedAt)} is null`,\n );\n if (current.targetCredential === undefined) {\n yield* stage(\n credential.insert(\n c.encodeVerifiedInsert({\n moduleId: input.moduleId,\n subjectId: native,\n credentialId: targetCredentialId,\n identifier: input.target,\n credentialRevision: targetCredentialRevision,\n }),\n ),\n );\n yield* stage(\n authority.insert(\n a.encodeInsert({\n subjectId: native,\n credentialId: targetCredentialId,\n revision: targetCredentialRevision,\n }),\n ),\n );\n } else {\n const old = current.targetCredential[c.credentialRevision];\n\n yield* stage(\n sql`${credential.update(c.encodeActivation({ identifier: input.target, credentialRevision: targetCredentialRevision }))} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, targetCredentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, old)}`,\n );\n yield* stage(\n sql`${authority.update(a.encodeActivation(targetCredentialRevision))} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, targetCredentialId)} and ${exact(authority, a.revision, old)}`,\n );\n }\n if (!confirms)\n yield* stage(\n sql`${subject.update({ [s.securityRevision]: nextSecurityRevision })} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, current.revision.securityRevision)} and ${activeSubject} and ${freshness}`,\n );\n\n const revision: AuthenticationRevision = {\n subjectId: current.revision.subjectId,\n securityRevision: nextSecurityRevision,\n credentials: [\n ...current.revision.credentials.filter(\n (f) =>\n f.credentialId !== targetCredentialId && f.credentialId !== source?.credentialId,\n ),\n { credentialId: targetCredentialId, revision: targetCredentialRevision },\n ].sort((a, b) => a.credentialId.localeCompare(b.credentialId)),\n };\n\n if (batch !== undefined) {\n ensure(i.d1CurrentCondition !== undefined);\n\n const conditions = [\n redeemed.validUntil,\n freshness,\n factorCondition(revision),\n sql`exists(select 1 from ${subject.name} where ${id(subject, s.id, native)} and ${exact(subject, s.securityRevision, nextSecurityRevision)} and ${activeSubject})`,\n sql`exists(select 1 from ${identifier.name} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${tables.expression(i.d1CurrentCondition({ identifier: input.target, nativeSubjectId: native, bindingRevision: targetIdentifierRevision }))})`,\n sql`exists(select 1 from ${identifier.name} where ${identifierKey(input.target)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, targetIdentifierRevision)} and ${id(identifier, i.verifiedAt, mapping.clock.encodeInstant(current.now))})`,\n sql`exists(select 1 from ${credential.name} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, targetCredentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, targetCredentialRevision)} and ${exact(credential, c.identifierNamespace, input.target.namespace)} and ${exact(credential, c.identifierValue, input.target.value)} and ${activeCredential})`,\n ];\n\n if (source !== undefined)\n conditions.push(\n sql`exists(select 1 from ${identifier.name} where ${identifierKey(source.identifier)} and ${id(identifier, i.subjectId, native)} and ${exact(identifier, i.bindingRevision, sourceIdentifierRevision)} and not (${tables.expression(i.d1CurrentCondition({ identifier: source.identifier, nativeSubjectId: native, bindingRevision: sourceIdentifierRevision }))}))`,\n sql`exists(select 1 from ${credential.name} where ${exact(credential, c.moduleId, input.moduleId)} and ${exact(credential, c.credentialId, source.credentialId)} and ${id(credential, c.subjectId, native)} and ${exact(credential, c.credentialRevision, sourceCredentialRevision)} and not (${activeCredential}))`,\n sql`exists(select 1 from ${authority.name} where ${id(authority, a.subjectId, native)} and ${exact(authority, a.credentialId, source.credentialId)} and ${exact(authority, a.revision, sourceCredentialRevision)} and not (${activeAuthority}))`,\n );\n yield* registerSqlBatchPostcondition({\n name: \"email-address-authority\",\n statement: sqlBatchAssertion(sql, sql.and(conditions)),\n });\n } else\n yield* registerSqlPostcondition({\n name: \"email-address-authority\",\n check: Effect.gen(function* () {\n const final = yield* reader.read({\n validity: redeemed.validUntil,\n moduleId: input.moduleId,\n subjectId: revision.subjectId,\n identifier: input.target,\n ...(source === undefined\n ? {}\n : {\n sourceCredentialId: source.credentialId,\n sourceIdentifier: source.identifier,\n }),\n });\n\n ensure(\n final !== undefined &&\n sameEmailRevision(final.revision, revision) &&\n final.now >= current.now &&\n final.now < deadline &&\n final.targetSnapshot !== undefined &&\n final.targetSnapshot.credentialId === targetCredentialId &&\n final.targetSnapshot.credentialRevision === targetCredentialRevision &&\n final.targetSnapshot.identifierRevision === targetIdentifierRevision &&\n (yield* mapping.decodeInstant(final.targetIdentifier![i.verifiedAt])) ===\n current.now,\n );\n const policy = yield* s.decodeActionRequirement(final.subject, action);\n\n ensure(passwordEvidenceSatisfiedAt(input.authorization.evidence, policy, final.now));\n if (source !== undefined)\n ensure(\n final.sourceIdentifier !== undefined &&\n final.sourceCredential !== undefined &&\n final.sourceAuthority !== undefined &&\n (yield* mapping.subjectId.toSubject(final.sourceAuthority[a.subjectId])) ===\n revision.subjectId &&\n final.sourceAuthority[a.credentialId] === source.credentialId &&\n final.sourceAuthority[a.revision] === sourceCredentialRevision &&\n !a.isActiveStatus(final.sourceAuthority[a.status]) &&\n (yield* mapping.subjectId.toSubject(final.sourceIdentifier[i.subjectId])) ===\n revision.subjectId &&\n final.sourceIdentifier[i.bindingRevision] === sourceIdentifierRevision &&\n !i.isCurrent(final.sourceIdentifier) &&\n final.sourceCredential[c.credentialRevision] === sourceCredentialRevision &&\n !c.isActiveStatus(final.sourceCredential[c.status]),\n );\n }).pipe(\n Effect.mapError((cause) =>\n PersistenceMappingError.make({ operation: \"decode\", cause }),\n ),\n ),\n });\n\n return yield* prepare(\"changed\", project);\n }),\n );\n\n return {\n emailAddressPersistence: E.EmailAddressPersistence.of({\n target: (input) =>\n executor.read(\n Effect.flatMap(target(input), (value) =>\n value === undefined ? Effect.fail(unavailable()) : Effect.succeed(value.target),\n ),\n ),\n verifyWithProof: (input, project) => mutate(input, \"verify-address\", project),\n changeWithProof: (input, project) => mutate(input, \"change-address\", project),\n }),\n };\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { PersistenceMappingError } from "./mapping-error.mjs";
|
|
2
|
+
import { passwordEvidenceSatisfiedAt } from "./password-policy.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import { EmailUnavailable, snapshotEmailCredential, snapshotEmailRequirement, snapshotEmailRevision } from "@yielded/auth/Email";
|
|
5
|
+
import { snapshotAuthenticationEvidence } from "@yielded/auth/Sessions";
|
|
6
|
+
//#region src/internal/email-policy.ts
|
|
7
|
+
const unavailable = () => EmailUnavailable.make({});
|
|
8
|
+
const sameIdentifier = (left, right) => left.namespace === right.namespace && left.value === right.value;
|
|
9
|
+
const sameEmailRevision = (left, right) => {
|
|
10
|
+
if (left.subjectId !== right.subjectId || left.securityRevision !== right.securityRevision || left.credentials.length !== right.credentials.length) return false;
|
|
11
|
+
const expected = [...left.credentials].sort((a, b) => a.credentialId.localeCompare(b.credentialId));
|
|
12
|
+
const actual = [...right.credentials].sort((a, b) => a.credentialId.localeCompare(b.credentialId));
|
|
13
|
+
return expected.every((item, index) => item.credentialId === actual[index].credentialId && item.revision === actual[index].revision);
|
|
14
|
+
};
|
|
15
|
+
const emailActionModule = (moduleId, action) => `${moduleId}/${action === "verify-address" ? "verify-address" : "change-address"}`;
|
|
16
|
+
const emailActionPurpose = (action) => action === "verify-address" ? "email-address-verification" : "email-address-change";
|
|
17
|
+
const emailRedemptionMatches = (input, action) => {
|
|
18
|
+
const completion = input.redemption.input;
|
|
19
|
+
const binding = completion.binding;
|
|
20
|
+
return completion.moduleId === emailActionModule(input.moduleId, action) && completion.purpose === emailActionPurpose(action) && binding._tag === "IdentifierChange" && sameIdentifier(binding.identifier, input.target) && sameEmailRevision(binding.revision, input.captured.revision);
|
|
21
|
+
};
|
|
22
|
+
const snapshotEmailMutation = Effect.fn("EmailAddressPersistence.snapshotMutation")(function* (input) {
|
|
23
|
+
const evidence = yield* snapshotAuthenticationEvidence(input.authorization.evidence).pipe(Effect.mapError(unavailable));
|
|
24
|
+
const requirement = yield* snapshotEmailRequirement(input.authorization.requirement);
|
|
25
|
+
const source = input.captured.source === void 0 ? void 0 : yield* snapshotEmailCredential(input.captured.source);
|
|
26
|
+
return Object.freeze({
|
|
27
|
+
...input,
|
|
28
|
+
target: Object.freeze({ ...input.target }),
|
|
29
|
+
...input.invalidation === void 0 ? {} : { invalidation: Object.freeze({ ...input.invalidation }) },
|
|
30
|
+
captured: Object.freeze({
|
|
31
|
+
eligible: input.captured.eligible,
|
|
32
|
+
revision: snapshotEmailRevision(input.captured.revision),
|
|
33
|
+
...input.captured.targetIdentifierRevision === void 0 ? {} : { targetIdentifierRevision: input.captured.targetIdentifierRevision },
|
|
34
|
+
...source === void 0 ? {} : { source }
|
|
35
|
+
}),
|
|
36
|
+
authorization: Object.freeze({
|
|
37
|
+
challenge: Object.freeze({
|
|
38
|
+
...input.authorization.challenge,
|
|
39
|
+
target: Object.freeze({ ...input.authorization.challenge.target }),
|
|
40
|
+
revision: snapshotEmailRevision(input.authorization.challenge.revision)
|
|
41
|
+
}),
|
|
42
|
+
evidence,
|
|
43
|
+
requirement
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
const validateEmailMutation = Effect.fn("EmailAddressPersistence.validateAuthority")(function* (policy, input, action, current, now) {
|
|
48
|
+
const confirmsExisting = action === "verify-address" && input.captured.targetIdentifierRevision !== void 0;
|
|
49
|
+
if (!input.captured.eligible || !emailRedemptionMatches(input, action) || input.authorization.challenge.moduleId !== input.moduleId || input.authorization.challenge.action !== action || input.authorization.challenge.commandId !== input.commandId || !sameIdentifier(input.authorization.challenge.target, input.target) || input.authorization.challenge.sourceCredentialId !== input.captured.source?.credentialId || !sameEmailRevision(input.authorization.challenge.revision, input.captured.revision) || input.authorization.challenge.targetIdentifierRevision !== input.captured.targetIdentifierRevision || input.authorization.evidence.flowId !== input.commandId || input.authorization.evidence.bindingDigest !== input.authorization.challenge.bindingDigest || !sameEmailRevision(input.authorization.evidence.revision, input.captured.revision) || action === "verify-address" && input.captured.source !== void 0 || action === "change-address" && input.captured.source === void 0 || confirmsExisting !== (input.invalidation === void 0) || input.invalidation?.existingSessions === "immediate" && policy.sessionInvalidation !== "same-authority-immediate") return false;
|
|
50
|
+
if (current === void 0 || !current.target.eligible || !sameEmailRevision(current.target.revision, input.captured.revision) || current.target.targetIdentifierRevision !== input.captured.targetIdentifierRevision || input.captured.source !== void 0 && (current.target.source === void 0 || current.target.source.identifierRevision !== input.captured.source.identifierRevision || current.target.source.credentialRevision !== input.captured.source.credentialRevision || !sameIdentifier(current.target.source.identifier, input.captured.source.identifier))) return false;
|
|
51
|
+
const currentRequirement = yield* current.requirement;
|
|
52
|
+
return passwordEvidenceSatisfiedAt(input.authorization.evidence, input.authorization.requirement, now) && passwordEvidenceSatisfiedAt(input.authorization.evidence, currentRequirement, now);
|
|
53
|
+
});
|
|
54
|
+
const allocateEmailValue = (mode, asynchronous, synchronous) => {
|
|
55
|
+
if (mode === "synchronous") return synchronous === void 0 ? Effect.fail(unavailable()) : Effect.try({
|
|
56
|
+
try: synchronous,
|
|
57
|
+
catch: (cause) => PersistenceMappingError.make({
|
|
58
|
+
operation: "mapping",
|
|
59
|
+
cause
|
|
60
|
+
})
|
|
61
|
+
});
|
|
62
|
+
if (asynchronous !== void 0) return asynchronous;
|
|
63
|
+
return synchronous === void 0 ? Effect.fail(unavailable()) : Effect.try({
|
|
64
|
+
try: synchronous,
|
|
65
|
+
catch: (cause) => PersistenceMappingError.make({
|
|
66
|
+
operation: "mapping",
|
|
67
|
+
cause
|
|
68
|
+
})
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
const allocateEmailSecurityRevision = (mapping, mode, current) => {
|
|
72
|
+
if (mode === "synchronous") return mapping.subject.nextSecurityRevisionSync === void 0 ? Effect.fail(unavailable()) : Effect.try({
|
|
73
|
+
try: () => mapping.subject.nextSecurityRevisionSync(current),
|
|
74
|
+
catch: (cause) => PersistenceMappingError.make({
|
|
75
|
+
operation: "mapping",
|
|
76
|
+
cause
|
|
77
|
+
})
|
|
78
|
+
});
|
|
79
|
+
if (mapping.subject.nextSecurityRevision !== void 0) return mapping.subject.nextSecurityRevision(current);
|
|
80
|
+
if (mapping.subject.nextSecurityRevisionSync !== void 0) return Effect.try({
|
|
81
|
+
try: () => mapping.subject.nextSecurityRevisionSync(current),
|
|
82
|
+
catch: (cause) => PersistenceMappingError.make({
|
|
83
|
+
operation: "mapping",
|
|
84
|
+
cause
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
return Effect.fail(unavailable());
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
export { allocateEmailSecurityRevision, allocateEmailValue, emailActionModule, emailActionPurpose, emailRedemptionMatches, sameEmailRevision, snapshotEmailMutation, validateEmailMutation };
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=email-policy.mjs.map
|