@effect-auth/core 0.1.0-alpha.16 → 0.1.0-alpha.18
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/LICENSE +21 -0
- package/README.md +308 -133
- package/dist/AbuseProtection.d.ts +100 -0
- package/dist/AbuseProtection.d.ts.map +1 -0
- package/dist/AbuseProtection.js +71 -0
- package/dist/AbuseProtection.js.map +1 -0
- package/dist/AccessGrant.d.ts +344 -0
- package/dist/AccessGrant.d.ts.map +1 -0
- package/dist/AccessGrant.js +687 -0
- package/dist/AccessGrant.js.map +1 -0
- package/dist/ApiKey.d.ts +0 -12
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +36 -27
- package/dist/ApiKey.js.map +1 -1
- package/dist/Assurance.d.ts +415 -0
- package/dist/Assurance.d.ts.map +1 -0
- package/dist/Assurance.js +764 -0
- package/dist/Assurance.js.map +1 -0
- package/dist/AtomicPlanExecutor.d.ts +28 -0
- package/dist/AtomicPlanExecutor.d.ts.map +1 -0
- package/dist/AtomicPlanExecutor.js +5 -0
- package/dist/AtomicPlanExecutor.js.map +1 -0
- package/dist/AuditLog.d.ts +2314 -52
- package/dist/AuditLog.d.ts.map +1 -1
- package/dist/AuditLog.js +511 -33
- package/dist/AuditLog.js.map +1 -1
- package/dist/AuthFlow.d.ts +128 -38
- package/dist/AuthFlow.d.ts.map +1 -1
- package/dist/AuthFlow.js +611 -263
- package/dist/AuthFlow.js.map +1 -1
- package/dist/AuthRateLimit.d.ts +96 -0
- package/dist/AuthRateLimit.d.ts.map +1 -0
- package/dist/AuthRateLimit.js +212 -0
- package/dist/AuthRateLimit.js.map +1 -0
- package/dist/Challenge.d.ts +0 -3
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +1 -4
- package/dist/Challenge.js.map +1 -1
- package/dist/Client.d.ts +205 -10
- package/dist/Client.d.ts.map +1 -1
- package/dist/Client.js +397 -16
- package/dist/Client.js.map +1 -1
- package/dist/CloudflareTurnstile.d.ts +28 -0
- package/dist/CloudflareTurnstile.d.ts.map +1 -0
- package/dist/CloudflareTurnstile.js +205 -0
- package/dist/CloudflareTurnstile.js.map +1 -0
- package/dist/Crypto.d.ts +0 -3
- package/dist/Crypto.d.ts.map +1 -1
- package/dist/Crypto.js +1 -4
- package/dist/Crypto.js.map +1 -1
- package/dist/DelegatedAccessStorageMigrations.d.ts +7 -0
- package/dist/DelegatedAccessStorageMigrations.d.ts.map +1 -0
- package/dist/DelegatedAccessStorageMigrations.js +159 -0
- package/dist/DelegatedAccessStorageMigrations.js.map +1 -0
- package/dist/DisposableEmailDomains.d.ts +19 -0
- package/dist/DisposableEmailDomains.d.ts.map +1 -0
- package/dist/DisposableEmailDomains.js +85 -0
- package/dist/DisposableEmailDomains.js.map +1 -0
- package/dist/DomainVerification.d.ts +0 -9
- package/dist/DomainVerification.d.ts.map +1 -1
- package/dist/DomainVerification.js +36 -22
- package/dist/DomainVerification.js.map +1 -1
- package/dist/DrizzleBunSqliteStorage.d.ts +18 -0
- package/dist/DrizzleBunSqliteStorage.d.ts.map +1 -0
- package/dist/DrizzleBunSqliteStorage.js +11 -0
- package/dist/DrizzleBunSqliteStorage.js.map +1 -0
- package/dist/DrizzleD1SqliteStorage.d.ts +4 -4
- package/dist/DrizzleD1SqliteStorage.d.ts.map +1 -1
- package/dist/DrizzleD1SqliteStorage.js +5 -5
- package/dist/DrizzleD1SqliteStorage.js.map +1 -1
- package/dist/DrizzleDurableObjectSqliteStorage.d.ts +19 -0
- package/dist/DrizzleDurableObjectSqliteStorage.d.ts.map +1 -0
- package/dist/DrizzleDurableObjectSqliteStorage.js +14 -0
- package/dist/DrizzleDurableObjectSqliteStorage.js.map +1 -0
- package/dist/DrizzleEffectSqliteStorage.d.ts +13 -4
- package/dist/DrizzleEffectSqliteStorage.d.ts.map +1 -1
- package/dist/DrizzleEffectSqliteStorage.js +71 -4
- package/dist/DrizzleEffectSqliteStorage.js.map +1 -1
- package/dist/DrizzleNodeSqliteStorage.d.ts +18 -0
- package/dist/DrizzleNodeSqliteStorage.d.ts.map +1 -0
- package/dist/DrizzleNodeSqliteStorage.js +11 -0
- package/dist/DrizzleNodeSqliteStorage.js.map +1 -0
- package/dist/DrizzleWasmSqliteStorage.d.ts +23 -0
- package/dist/DrizzleWasmSqliteStorage.d.ts.map +1 -0
- package/dist/DrizzleWasmSqliteStorage.js +15 -0
- package/dist/DrizzleWasmSqliteStorage.js.map +1 -0
- package/dist/EffectQbPostgresDelegatedAccessStorage.d.ts +34 -0
- package/dist/EffectQbPostgresDelegatedAccessStorage.d.ts.map +1 -0
- package/dist/EffectQbPostgresDelegatedAccessStorage.js +499 -0
- package/dist/EffectQbPostgresDelegatedAccessStorage.js.map +1 -0
- package/dist/EffectQbPostgresStorage.d.ts +171 -0
- package/dist/EffectQbPostgresStorage.d.ts.map +1 -0
- package/dist/EffectQbPostgresStorage.js +4280 -0
- package/dist/EffectQbPostgresStorage.js.map +1 -0
- package/dist/EffectQbSqliteDelegatedAccessStorage.d.ts +112 -0
- package/dist/EffectQbSqliteDelegatedAccessStorage.d.ts.map +1 -0
- package/dist/EffectQbSqliteDelegatedAccessStorage.js +602 -0
- package/dist/EffectQbSqliteDelegatedAccessStorage.js.map +1 -0
- package/dist/EffectQbSqliteStorage.d.ts +181 -23
- package/dist/EffectQbSqliteStorage.d.ts.map +1 -1
- package/dist/EffectQbSqliteStorage.js +1728 -135
- package/dist/EffectQbSqliteStorage.js.map +1 -1
- package/dist/EmailAuth.d.ts +65 -0
- package/dist/EmailAuth.d.ts.map +1 -0
- package/dist/EmailAuth.js +171 -0
- package/dist/EmailAuth.js.map +1 -0
- package/dist/EmailIdentityAuth.d.ts +30 -0
- package/dist/EmailIdentityAuth.d.ts.map +1 -0
- package/dist/EmailIdentityAuth.js +142 -0
- package/dist/EmailIdentityAuth.js.map +1 -0
- package/dist/EmailOtp.d.ts +10 -11
- package/dist/EmailOtp.d.ts.map +1 -1
- package/dist/EmailOtp.js +44 -81
- package/dist/EmailOtp.js.map +1 -1
- package/dist/EmailRisk.d.ts +48 -0
- package/dist/EmailRisk.d.ts.map +1 -0
- package/dist/EmailRisk.js +33 -0
- package/dist/EmailRisk.js.map +1 -0
- package/dist/EmailVerification.d.ts +10 -16
- package/dist/EmailVerification.d.ts.map +1 -1
- package/dist/EmailVerification.js +85 -42
- package/dist/EmailVerification.js.map +1 -1
- package/dist/Guard.d.ts +11 -0
- package/dist/Guard.d.ts.map +1 -0
- package/dist/Guard.js +11 -0
- package/dist/Guard.js.map +1 -0
- package/dist/HibpPwnedPasswords.d.ts +56 -0
- package/dist/HibpPwnedPasswords.d.ts.map +1 -0
- package/dist/HibpPwnedPasswords.js +232 -0
- package/dist/HibpPwnedPasswords.js.map +1 -0
- package/dist/HttpApi/AdminPermissionDefinition.d.ts +4 -0
- package/dist/HttpApi/AdminPermissionDefinition.d.ts.map +1 -0
- package/dist/HttpApi/AdminPermissionDefinition.js +4 -0
- package/dist/HttpApi/AdminPermissionDefinition.js.map +1 -0
- package/dist/HttpApi/AdminSecurityTimeline.d.ts +4 -0
- package/dist/HttpApi/AdminSecurityTimeline.d.ts.map +1 -0
- package/dist/HttpApi/AdminSecurityTimeline.js +4 -0
- package/dist/HttpApi/AdminSecurityTimeline.js.map +1 -0
- package/dist/HttpApi/AdminSession.d.ts +4 -0
- package/dist/HttpApi/AdminSession.d.ts.map +1 -0
- package/dist/HttpApi/AdminSession.js +4 -0
- package/dist/HttpApi/AdminSession.js.map +1 -0
- package/dist/HttpApi/AdminTrustedDevice.d.ts +4 -0
- package/dist/HttpApi/AdminTrustedDevice.d.ts.map +1 -0
- package/dist/HttpApi/AdminTrustedDevice.js +4 -0
- package/dist/HttpApi/AdminTrustedDevice.js.map +1 -0
- package/dist/HttpApi/Api.d.ts +879 -877
- package/dist/HttpApi/Api.d.ts.map +1 -1
- package/dist/HttpApi/Api.js +2160 -896
- package/dist/HttpApi/Api.js.map +1 -1
- package/dist/HttpApi/ApiKey.d.ts +4 -0
- package/dist/HttpApi/ApiKey.d.ts.map +1 -0
- package/dist/HttpApi/ApiKey.js +4 -0
- package/dist/HttpApi/ApiKey.js.map +1 -0
- package/dist/HttpApi/Audit.d.ts +6 -0
- package/dist/HttpApi/Audit.d.ts.map +1 -0
- package/dist/HttpApi/Audit.js +10 -0
- package/dist/HttpApi/Audit.js.map +1 -0
- package/dist/HttpApi/ClientApi.d.ts +917 -0
- package/dist/HttpApi/ClientApi.d.ts.map +1 -0
- package/dist/HttpApi/ClientApi.js +101 -0
- package/dist/HttpApi/ClientApi.js.map +1 -0
- package/dist/HttpApi/EmailAuth.d.ts +6 -0
- package/dist/HttpApi/EmailAuth.d.ts.map +1 -0
- package/dist/HttpApi/EmailAuth.js +6 -0
- package/dist/HttpApi/EmailAuth.js.map +1 -0
- package/dist/HttpApi/EmailGuards.d.ts +115 -0
- package/dist/HttpApi/EmailGuards.d.ts.map +1 -0
- package/dist/HttpApi/EmailGuards.js +191 -0
- package/dist/HttpApi/EmailGuards.js.map +1 -0
- package/dist/HttpApi/EmailOtp.d.ts +6 -0
- package/dist/HttpApi/EmailOtp.d.ts.map +1 -0
- package/dist/HttpApi/EmailOtp.js +6 -0
- package/dist/HttpApi/EmailOtp.js.map +1 -0
- package/dist/HttpApi/EmailVerification.d.ts +6 -0
- package/dist/HttpApi/EmailVerification.d.ts.map +1 -0
- package/dist/HttpApi/EmailVerification.js +6 -0
- package/dist/HttpApi/EmailVerification.js.map +1 -0
- package/dist/HttpApi/Endpoints.d.ts +629 -301
- package/dist/HttpApi/Endpoints.d.ts.map +1 -1
- package/dist/HttpApi/Endpoints.js +178 -120
- package/dist/HttpApi/Endpoints.js.map +1 -1
- package/dist/HttpApi/Errors.d.ts +26 -7
- package/dist/HttpApi/Errors.d.ts.map +1 -1
- package/dist/HttpApi/Errors.js +26 -4
- package/dist/HttpApi/Errors.js.map +1 -1
- package/dist/HttpApi/Identity.d.ts +6 -0
- package/dist/HttpApi/Identity.d.ts.map +1 -0
- package/dist/HttpApi/Identity.js +6 -0
- package/dist/HttpApi/Identity.js.map +1 -0
- package/dist/HttpApi/IdentityGuards.d.ts +31 -0
- package/dist/HttpApi/IdentityGuards.d.ts.map +1 -0
- package/dist/HttpApi/IdentityGuards.js +33 -0
- package/dist/HttpApi/IdentityGuards.js.map +1 -0
- package/dist/HttpApi/Jwt.d.ts +4 -0
- package/dist/HttpApi/Jwt.d.ts.map +1 -0
- package/dist/HttpApi/Jwt.js +4 -0
- package/dist/HttpApi/Jwt.js.map +1 -0
- package/dist/HttpApi/JwtDiscovery.d.ts +4 -0
- package/dist/HttpApi/JwtDiscovery.d.ts.map +1 -0
- package/dist/HttpApi/JwtDiscovery.js +4 -0
- package/dist/HttpApi/JwtDiscovery.js.map +1 -0
- package/dist/HttpApi/LoginApproval.d.ts +5 -0
- package/dist/HttpApi/LoginApproval.d.ts.map +1 -0
- package/dist/HttpApi/LoginApproval.js +5 -0
- package/dist/HttpApi/LoginApproval.js.map +1 -0
- package/dist/HttpApi/LoginNotification.d.ts +5 -0
- package/dist/HttpApi/LoginNotification.d.ts.map +1 -0
- package/dist/HttpApi/LoginNotification.js +5 -0
- package/dist/HttpApi/LoginNotification.js.map +1 -0
- package/dist/HttpApi/MagicLink.d.ts +6 -0
- package/dist/HttpApi/MagicLink.d.ts.map +1 -0
- package/dist/HttpApi/MagicLink.js +6 -0
- package/dist/HttpApi/MagicLink.js.map +1 -0
- package/dist/HttpApi/Mfa.d.ts +5 -0
- package/dist/HttpApi/Mfa.d.ts.map +1 -0
- package/dist/HttpApi/Mfa.js +5 -0
- package/dist/HttpApi/Mfa.js.map +1 -0
- package/dist/HttpApi/Middleware.d.ts +14 -0
- package/dist/HttpApi/Middleware.d.ts.map +1 -0
- package/dist/HttpApi/Middleware.js +5 -0
- package/dist/HttpApi/Middleware.js.map +1 -0
- package/dist/HttpApi/OAuth.d.ts +4 -0
- package/dist/HttpApi/OAuth.d.ts.map +1 -0
- package/dist/HttpApi/OAuth.js +4 -0
- package/dist/HttpApi/OAuth.js.map +1 -0
- package/dist/HttpApi/OAuthProviderAuthorization.d.ts +4 -0
- package/dist/HttpApi/OAuthProviderAuthorization.d.ts.map +1 -0
- package/dist/HttpApi/OAuthProviderAuthorization.js +4 -0
- package/dist/HttpApi/OAuthProviderAuthorization.js.map +1 -0
- package/dist/HttpApi/OAuthToken.d.ts +4 -0
- package/dist/HttpApi/OAuthToken.d.ts.map +1 -0
- package/dist/HttpApi/OAuthToken.js +4 -0
- package/dist/HttpApi/OAuthToken.js.map +1 -0
- package/dist/HttpApi/OidcDiscovery.d.ts +4 -0
- package/dist/HttpApi/OidcDiscovery.d.ts.map +1 -0
- package/dist/HttpApi/OidcDiscovery.js +4 -0
- package/dist/HttpApi/OidcDiscovery.js.map +1 -0
- package/dist/HttpApi/Operations/AdminPermissionDefinition.d.ts +28 -0
- package/dist/HttpApi/Operations/AdminPermissionDefinition.d.ts.map +1 -0
- package/dist/HttpApi/Operations/AdminPermissionDefinition.js +5 -0
- package/dist/HttpApi/Operations/AdminPermissionDefinition.js.map +1 -0
- package/dist/HttpApi/Operations/AdminSession.d.ts +16 -0
- package/dist/HttpApi/Operations/AdminSession.d.ts.map +1 -0
- package/dist/HttpApi/Operations/AdminSession.js +5 -0
- package/dist/HttpApi/Operations/AdminSession.js.map +1 -0
- package/dist/HttpApi/Operations/ApiKey.d.ts +16 -0
- package/dist/HttpApi/Operations/ApiKey.d.ts.map +1 -0
- package/dist/HttpApi/Operations/ApiKey.js +5 -0
- package/dist/HttpApi/Operations/ApiKey.js.map +1 -0
- package/dist/HttpApi/Operations/Discovery.d.ts +19 -0
- package/dist/HttpApi/Operations/Discovery.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Discovery.js +7 -0
- package/dist/HttpApi/Operations/Discovery.js.map +1 -0
- package/dist/HttpApi/Operations/EmailAuth.d.ts +12 -0
- package/dist/HttpApi/Operations/EmailAuth.d.ts.map +1 -0
- package/dist/HttpApi/Operations/EmailAuth.js +5 -0
- package/dist/HttpApi/Operations/EmailAuth.js.map +1 -0
- package/dist/HttpApi/Operations/EmailOtp.d.ts +14 -0
- package/dist/HttpApi/Operations/EmailOtp.d.ts.map +1 -0
- package/dist/HttpApi/Operations/EmailOtp.js +5 -0
- package/dist/HttpApi/Operations/EmailOtp.js.map +1 -0
- package/dist/HttpApi/Operations/EmailVerification.d.ts +14 -0
- package/dist/HttpApi/Operations/EmailVerification.d.ts.map +1 -0
- package/dist/HttpApi/Operations/EmailVerification.js +5 -0
- package/dist/HttpApi/Operations/EmailVerification.js.map +1 -0
- package/dist/HttpApi/Operations/HttpOperation.d.ts +4 -0
- package/dist/HttpApi/Operations/HttpOperation.d.ts.map +1 -0
- package/dist/HttpApi/Operations/HttpOperation.js +2 -0
- package/dist/HttpApi/Operations/HttpOperation.js.map +1 -0
- package/dist/HttpApi/Operations/Identity.d.ts +22 -0
- package/dist/HttpApi/Operations/Identity.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Identity.js +5 -0
- package/dist/HttpApi/Operations/Identity.js.map +1 -0
- package/dist/HttpApi/Operations/Jwt.d.ts +14 -0
- package/dist/HttpApi/Operations/Jwt.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Jwt.js +5 -0
- package/dist/HttpApi/Operations/Jwt.js.map +1 -0
- package/dist/HttpApi/Operations/LoginApproval.d.ts +16 -0
- package/dist/HttpApi/Operations/LoginApproval.d.ts.map +1 -0
- package/dist/HttpApi/Operations/LoginApproval.js +5 -0
- package/dist/HttpApi/Operations/LoginApproval.js.map +1 -0
- package/dist/HttpApi/Operations/MagicLink.d.ts +14 -0
- package/dist/HttpApi/Operations/MagicLink.d.ts.map +1 -0
- package/dist/HttpApi/Operations/MagicLink.js +5 -0
- package/dist/HttpApi/Operations/MagicLink.js.map +1 -0
- package/dist/HttpApi/Operations/Mfa.d.ts +24 -0
- package/dist/HttpApi/Operations/Mfa.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Mfa.js +5 -0
- package/dist/HttpApi/Operations/Mfa.js.map +1 -0
- package/dist/HttpApi/Operations/OAuth.d.ts +20 -0
- package/dist/HttpApi/Operations/OAuth.d.ts.map +1 -0
- package/dist/HttpApi/Operations/OAuth.js +5 -0
- package/dist/HttpApi/Operations/OAuth.js.map +1 -0
- package/dist/HttpApi/Operations/OAuthProviderAuthorization.d.ts +12 -0
- package/dist/HttpApi/Operations/OAuthProviderAuthorization.d.ts.map +1 -0
- package/dist/HttpApi/Operations/OAuthProviderAuthorization.js +5 -0
- package/dist/HttpApi/Operations/OAuthProviderAuthorization.js.map +1 -0
- package/dist/HttpApi/Operations/OAuthToken.d.ts +16 -0
- package/dist/HttpApi/Operations/OAuthToken.d.ts.map +1 -0
- package/dist/HttpApi/Operations/OAuthToken.js +5 -0
- package/dist/HttpApi/Operations/OAuthToken.js.map +1 -0
- package/dist/HttpApi/Operations/Passkey.d.ts +22 -0
- package/dist/HttpApi/Operations/Passkey.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Passkey.js +5 -0
- package/dist/HttpApi/Operations/Passkey.js.map +1 -0
- package/dist/HttpApi/Operations/Password.d.ts +22 -0
- package/dist/HttpApi/Operations/Password.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Password.js +5 -0
- package/dist/HttpApi/Operations/Password.js.map +1 -0
- package/dist/HttpApi/Operations/RecoveryCodes.d.ts +20 -0
- package/dist/HttpApi/Operations/RecoveryCodes.d.ts.map +1 -0
- package/dist/HttpApi/Operations/RecoveryCodes.js +5 -0
- package/dist/HttpApi/Operations/RecoveryCodes.js.map +1 -0
- package/dist/HttpApi/Operations/RefreshToken.d.ts +12 -0
- package/dist/HttpApi/Operations/RefreshToken.d.ts.map +1 -0
- package/dist/HttpApi/Operations/RefreshToken.js +5 -0
- package/dist/HttpApi/Operations/RefreshToken.js.map +1 -0
- package/dist/HttpApi/Operations/Security.d.ts +12 -0
- package/dist/HttpApi/Operations/Security.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Security.js +5 -0
- package/dist/HttpApi/Operations/Security.js.map +1 -0
- package/dist/HttpApi/Operations/SecurityTimeline.d.ts +19 -0
- package/dist/HttpApi/Operations/SecurityTimeline.d.ts.map +1 -0
- package/dist/HttpApi/Operations/SecurityTimeline.js +7 -0
- package/dist/HttpApi/Operations/SecurityTimeline.js.map +1 -0
- package/dist/HttpApi/Operations/Session.d.ts +22 -0
- package/dist/HttpApi/Operations/Session.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Session.js +5 -0
- package/dist/HttpApi/Operations/Session.js.map +1 -0
- package/dist/HttpApi/Operations/StepUp.d.ts +22 -0
- package/dist/HttpApi/Operations/StepUp.d.ts.map +1 -0
- package/dist/HttpApi/Operations/StepUp.js +5 -0
- package/dist/HttpApi/Operations/StepUp.js.map +1 -0
- package/dist/HttpApi/Operations/Totp.d.ts +20 -0
- package/dist/HttpApi/Operations/Totp.d.ts.map +1 -0
- package/dist/HttpApi/Operations/Totp.js +5 -0
- package/dist/HttpApi/Operations/Totp.js.map +1 -0
- package/dist/HttpApi/Operations/TrustedDevice.d.ts +23 -0
- package/dist/HttpApi/Operations/TrustedDevice.d.ts.map +1 -0
- package/dist/HttpApi/Operations/TrustedDevice.js +7 -0
- package/dist/HttpApi/Operations/TrustedDevice.js.map +1 -0
- package/dist/HttpApi/Operations/index.d.ts +27 -0
- package/dist/HttpApi/Operations/index.d.ts.map +1 -0
- package/dist/HttpApi/Operations/index.js +27 -0
- package/dist/HttpApi/Operations/index.js.map +1 -0
- package/dist/HttpApi/Passkey.d.ts +5 -0
- package/dist/HttpApi/Passkey.d.ts.map +1 -0
- package/dist/HttpApi/Passkey.js +5 -0
- package/dist/HttpApi/Passkey.js.map +1 -0
- package/dist/HttpApi/Password.d.ts +220 -0
- package/dist/HttpApi/Password.d.ts.map +1 -0
- package/dist/HttpApi/Password.js +237 -0
- package/dist/HttpApi/Password.js.map +1 -0
- package/dist/HttpApi/PasswordContract.d.ts +307 -0
- package/dist/HttpApi/PasswordContract.d.ts.map +1 -0
- package/dist/HttpApi/PasswordContract.js +63 -0
- package/dist/HttpApi/PasswordContract.js.map +1 -0
- package/dist/HttpApi/PasswordGuards.d.ts +82 -0
- package/dist/HttpApi/PasswordGuards.d.ts.map +1 -0
- package/dist/HttpApi/PasswordGuards.js +179 -0
- package/dist/HttpApi/PasswordGuards.js.map +1 -0
- package/dist/HttpApi/RecoveryCodes.d.ts +5 -0
- package/dist/HttpApi/RecoveryCodes.d.ts.map +1 -0
- package/dist/HttpApi/RecoveryCodes.js +5 -0
- package/dist/HttpApi/RecoveryCodes.js.map +1 -0
- package/dist/HttpApi/RefreshToken.d.ts +4 -0
- package/dist/HttpApi/RefreshToken.d.ts.map +1 -0
- package/dist/HttpApi/RefreshToken.js +4 -0
- package/dist/HttpApi/RefreshToken.js.map +1 -0
- package/dist/HttpApi/RequestGuards.d.ts +42 -0
- package/dist/HttpApi/RequestGuards.d.ts.map +1 -0
- package/dist/HttpApi/RequestGuards.js +194 -0
- package/dist/HttpApi/RequestGuards.js.map +1 -0
- package/dist/HttpApi/Schemas.d.ts +361 -84
- package/dist/HttpApi/Schemas.d.ts.map +1 -1
- package/dist/HttpApi/Schemas.js +190 -27
- package/dist/HttpApi/Schemas.js.map +1 -1
- package/dist/HttpApi/Security.d.ts +12 -93
- package/dist/HttpApi/Security.d.ts.map +1 -1
- package/dist/HttpApi/Security.js +65 -356
- package/dist/HttpApi/Security.js.map +1 -1
- package/dist/HttpApi/SecurityTimeline.d.ts +4 -0
- package/dist/HttpApi/SecurityTimeline.d.ts.map +1 -0
- package/dist/HttpApi/SecurityTimeline.js +4 -0
- package/dist/HttpApi/SecurityTimeline.js.map +1 -0
- package/dist/HttpApi/Session.d.ts +5 -0
- package/dist/HttpApi/Session.d.ts.map +1 -0
- package/dist/HttpApi/Session.js +5 -0
- package/dist/HttpApi/Session.js.map +1 -0
- package/dist/HttpApi/SessionGuards.d.ts +15 -0
- package/dist/HttpApi/SessionGuards.d.ts.map +1 -0
- package/dist/HttpApi/SessionGuards.js +37 -0
- package/dist/HttpApi/SessionGuards.js.map +1 -0
- package/dist/HttpApi/StepUp.d.ts +5 -0
- package/dist/HttpApi/StepUp.d.ts.map +1 -0
- package/dist/HttpApi/StepUp.js +5 -0
- package/dist/HttpApi/StepUp.js.map +1 -0
- package/dist/HttpApi/Totp.d.ts +5 -0
- package/dist/HttpApi/Totp.d.ts.map +1 -0
- package/dist/HttpApi/Totp.js +5 -0
- package/dist/HttpApi/Totp.js.map +1 -0
- package/dist/HttpApi/Transport.d.ts +4 -6
- package/dist/HttpApi/Transport.d.ts.map +1 -1
- package/dist/HttpApi/Transport.js +62 -36
- package/dist/HttpApi/Transport.js.map +1 -1
- package/dist/HttpApi/TrustedDevice.d.ts +4 -0
- package/dist/HttpApi/TrustedDevice.d.ts.map +1 -0
- package/dist/HttpApi/TrustedDevice.js +4 -0
- package/dist/HttpApi/TrustedDevice.js.map +1 -0
- package/dist/HttpApi/index.d.ts +9 -3
- package/dist/HttpApi/index.d.ts.map +1 -1
- package/dist/HttpApi/index.js +8 -2
- package/dist/HttpApi/index.js.map +1 -1
- package/dist/Identity.d.ts +138 -0
- package/dist/Identity.d.ts.map +1 -0
- package/dist/Identity.js +105 -0
- package/dist/Identity.js.map +1 -0
- package/dist/IdentityManagement.d.ts +189 -0
- package/dist/IdentityManagement.d.ts.map +1 -0
- package/dist/IdentityManagement.js +317 -0
- package/dist/IdentityManagement.js.map +1 -0
- package/dist/IncidentAction.d.ts +1 -4
- package/dist/IncidentAction.d.ts.map +1 -1
- package/dist/IncidentAction.js +15 -9
- package/dist/IncidentAction.js.map +1 -1
- package/dist/Internal.d.ts +2 -0
- package/dist/Internal.d.ts.map +1 -1
- package/dist/Internal.js +30 -0
- package/dist/Internal.js.map +1 -1
- package/dist/Invitation.d.ts +362 -0
- package/dist/Invitation.d.ts.map +1 -0
- package/dist/Invitation.js +633 -0
- package/dist/Invitation.js.map +1 -0
- package/dist/IpQualityScore.d.ts +38 -0
- package/dist/IpQualityScore.d.ts.map +1 -0
- package/dist/IpQualityScore.js +215 -0
- package/dist/IpQualityScore.js.map +1 -0
- package/dist/Jwt.d.ts +8 -29
- package/dist/Jwt.d.ts.map +1 -1
- package/dist/Jwt.js +67 -56
- package/dist/Jwt.js.map +1 -1
- package/dist/LoginApproval.d.ts +15 -30
- package/dist/LoginApproval.d.ts.map +1 -1
- package/dist/LoginApproval.js +47 -41
- package/dist/LoginApproval.js.map +1 -1
- package/dist/LoginNotification.d.ts +7 -11
- package/dist/LoginNotification.d.ts.map +1 -1
- package/dist/LoginNotification.js +30 -17
- package/dist/LoginNotification.js.map +1 -1
- package/dist/LoginRisk.d.ts +11 -13
- package/dist/LoginRisk.d.ts.map +1 -1
- package/dist/LoginRisk.js +66 -26
- package/dist/LoginRisk.js.map +1 -1
- package/dist/LoginRiskEnrichment.d.ts +145 -0
- package/dist/LoginRiskEnrichment.d.ts.map +1 -0
- package/dist/LoginRiskEnrichment.js +220 -0
- package/dist/LoginRiskEnrichment.js.map +1 -0
- package/dist/MagicLink.d.ts +9 -8
- package/dist/MagicLink.d.ts.map +1 -1
- package/dist/MagicLink.js +40 -73
- package/dist/MagicLink.js.map +1 -1
- package/dist/Mailer.d.ts +19 -12
- package/dist/Mailer.d.ts.map +1 -1
- package/dist/Mailer.js +10 -12
- package/dist/Mailer.js.map +1 -1
- package/dist/OAuth.d.ts +93 -96
- package/dist/OAuth.d.ts.map +1 -1
- package/dist/OAuth.js +404 -217
- package/dist/OAuth.js.map +1 -1
- package/dist/Passkey.d.ts +15 -17
- package/dist/Passkey.d.ts.map +1 -1
- package/dist/Passkey.js +86 -39
- package/dist/Passkey.js.map +1 -1
- package/dist/PasskeyBrowser.d.ts +39 -0
- package/dist/PasskeyBrowser.d.ts.map +1 -0
- package/dist/PasskeyBrowser.js +206 -0
- package/dist/PasskeyBrowser.js.map +1 -0
- package/dist/PasskeySimpleWebAuthn.d.ts.map +1 -1
- package/dist/PasskeySimpleWebAuthn.js +19 -7
- package/dist/PasskeySimpleWebAuthn.js.map +1 -1
- package/dist/Password.d.ts +71 -37
- package/dist/Password.d.ts.map +1 -1
- package/dist/Password.js +295 -81
- package/dist/Password.js.map +1 -1
- package/dist/PasswordRisk.d.ts +63 -0
- package/dist/PasswordRisk.d.ts.map +1 -0
- package/dist/PasswordRisk.js +37 -0
- package/dist/PasswordRisk.js.map +1 -0
- package/dist/Permission.d.ts +308 -0
- package/dist/Permission.d.ts.map +1 -0
- package/dist/Permission.js +827 -0
- package/dist/Permission.js.map +1 -0
- package/dist/Policy.d.ts +31 -18
- package/dist/Policy.d.ts.map +1 -1
- package/dist/Policy.js +58 -14
- package/dist/Policy.js.map +1 -1
- package/dist/PostgresDelegatedAccessStorageMigrations.d.ts +7 -0
- package/dist/PostgresDelegatedAccessStorageMigrations.d.ts.map +1 -0
- package/dist/PostgresDelegatedAccessStorageMigrations.js +119 -0
- package/dist/PostgresDelegatedAccessStorageMigrations.js.map +1 -0
- package/dist/PostgresStorageMigrations.d.ts +15 -0
- package/dist/PostgresStorageMigrations.d.ts.map +1 -0
- package/dist/PostgresStorageMigrations.js +620 -0
- package/dist/PostgresStorageMigrations.js.map +1 -0
- package/dist/Privacy.d.ts +0 -3
- package/dist/Privacy.d.ts.map +1 -1
- package/dist/Privacy.js +2 -5
- package/dist/Privacy.js.map +1 -1
- package/dist/RateLimiter.d.ts +0 -3
- package/dist/RateLimiter.d.ts.map +1 -1
- package/dist/RateLimiter.js +1 -4
- package/dist/RateLimiter.js.map +1 -1
- package/dist/RecoveryCode.d.ts +83 -11
- package/dist/RecoveryCode.d.ts.map +1 -1
- package/dist/RecoveryCode.js +273 -75
- package/dist/RecoveryCode.js.map +1 -1
- package/dist/RecoveryPolicy.d.ts +81 -0
- package/dist/RecoveryPolicy.d.ts.map +1 -0
- package/dist/RecoveryPolicy.js +119 -0
- package/dist/RecoveryPolicy.js.map +1 -0
- package/dist/RefreshToken.d.ts +0 -9
- package/dist/RefreshToken.d.ts.map +1 -1
- package/dist/RefreshToken.js +31 -22
- package/dist/RefreshToken.js.map +1 -1
- package/dist/SecurityTimeline.d.ts +1 -4
- package/dist/SecurityTimeline.d.ts.map +1 -1
- package/dist/SecurityTimeline.js +110 -17
- package/dist/SecurityTimeline.js.map +1 -1
- package/dist/Sessions.d.ts +124 -29
- package/dist/Sessions.d.ts.map +1 -1
- package/dist/Sessions.js +626 -94
- package/dist/Sessions.js.map +1 -1
- package/dist/StepUp.d.ts +132 -11
- package/dist/StepUp.d.ts.map +1 -1
- package/dist/StepUp.js +387 -19
- package/dist/StepUp.js.map +1 -1
- package/dist/Storage.d.ts +89 -23
- package/dist/Storage.d.ts.map +1 -1
- package/dist/Storage.js +10 -12
- package/dist/Storage.js.map +1 -1
- package/dist/StorageMigrations.d.ts +6 -1
- package/dist/StorageMigrations.d.ts.map +1 -1
- package/dist/StorageMigrations.js +224 -0
- package/dist/StorageMigrations.js.map +1 -1
- package/dist/StorageSchemaGenerator.d.ts +486 -0
- package/dist/StorageSchemaGenerator.d.ts.map +1 -0
- package/dist/StorageSchemaGenerator.js +1022 -0
- package/dist/StorageSchemaGenerator.js.map +1 -0
- package/dist/StrongFactor.d.ts +64 -0
- package/dist/StrongFactor.d.ts.map +1 -0
- package/dist/StrongFactor.js +100 -0
- package/dist/StrongFactor.js.map +1 -0
- package/dist/Testing.js +2 -2
- package/dist/Testing.js.map +1 -1
- package/dist/Totp.d.ts +88 -13
- package/dist/Totp.d.ts.map +1 -1
- package/dist/Totp.js +192 -34
- package/dist/Totp.js.map +1 -1
- package/dist/TrustedDevice.d.ts +0 -9
- package/dist/TrustedDevice.d.ts.map +1 -1
- package/dist/TrustedDevice.js +15 -17
- package/dist/TrustedDevice.js.map +1 -1
- package/dist/WaitUntil.d.ts +0 -3
- package/dist/WaitUntil.d.ts.map +1 -1
- package/dist/WaitUntil.js +1 -4
- package/dist/WaitUntil.js.map +1 -1
- package/dist/Webhook.d.ts +42 -12
- package/dist/Webhook.d.ts.map +1 -1
- package/dist/Webhook.js +165 -26
- package/dist/Webhook.js.map +1 -1
- package/dist/alchemy/cloudflare/Email.d.ts.map +1 -1
- package/dist/alchemy/cloudflare/Email.js +9 -4
- package/dist/alchemy/cloudflare/Email.js.map +1 -1
- package/dist/cloudflare/Email.js +1 -1
- package/dist/cloudflare/Email.js.map +1 -1
- package/dist/cloudflare/RequestMetadata.d.ts +49 -0
- package/dist/cloudflare/RequestMetadata.d.ts.map +1 -0
- package/dist/cloudflare/RequestMetadata.js +71 -0
- package/dist/cloudflare/RequestMetadata.js.map +1 -0
- package/dist/index.d.ts +0 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -35
- package/dist/index.js.map +1 -1
- package/dist/internal/AuthFlowFinalizer.d.ts +31 -0
- package/dist/internal/AuthFlowFinalizer.d.ts.map +1 -0
- package/dist/internal/AuthFlowFinalizer.js +182 -0
- package/dist/internal/AuthFlowFinalizer.js.map +1 -0
- package/migrations/0001_auth_storage.sql +1 -0
- package/migrations/0006_auth_totp_factor.sql +1 -0
- package/migrations/0024_auth_permission.sql +39 -0
- package/migrations/0025_auth_permission_definition.sql +19 -0
- package/migrations/0026_auth_user_identity.sql +59 -0
- package/migrations/0027_auth_audit_log_storage_order.sql +46 -0
- package/migrations/0028_auth_oauth_client_secret_key.sql +39 -0
- package/migrations/delegated-access/0001_auth_delegated_access.sql +152 -0
- package/migrations/postgres/0001_auth_core.sql +77 -0
- package/migrations/postgres/0002_auth_security_oauth.sql +65 -0
- package/migrations/postgres/0003_auth_credentials_tokens.sql +43 -0
- package/migrations/postgres/0004_auth_security_history.sql +103 -0
- package/migrations/postgres/0005_auth_webhooks.sql +29 -0
- package/migrations/postgres/0006_auth_domain_timeline.sql +50 -0
- package/migrations/postgres/0007_auth_oauth_clients.sql +85 -0
- package/migrations/postgres/0008_auth_oauth_tokens.sql +63 -0
- package/migrations/postgres/0009_auth_permissions.sql +66 -0
- package/migrations/postgres/delegated-access/0001_auth_delegated_access.sql +112 -0
- package/package.json +301 -2
package/dist/AuthFlow.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
// oxlint-disable complexity
|
|
2
2
|
import { Context, Data, Duration, Effect, Layer, Option, Redacted, } from "effect";
|
|
3
|
+
import { parseAuthenticationEvents } from "./Assurance.js";
|
|
3
4
|
import { AuthEmailVerificationSessionPolicyConfig } from "./AuthConfig.js";
|
|
4
5
|
import { Challenge } from "./Challenge.js";
|
|
5
6
|
import { Crypto } from "./Crypto.js";
|
|
6
|
-
import { AuthFlowId, ChallengeId,
|
|
7
|
+
import { AuthFlowId, ChallengeId, UnixMillis, UserId } from "./Identifiers.js";
|
|
7
8
|
import { currentUnixMillis } from "./Internal.js";
|
|
9
|
+
import { AuthFlowFinalizer, AuthFlowFinalizerLive, makeAuthFlowTerminal, } from "./internal/AuthFlowFinalizer.js";
|
|
8
10
|
import { LoginApprovalFlow, LoginApprovalPolicy, LoginApprovalReview, makeLoginApprovalPolicy, unknownLoginDeviceContext, } from "./LoginApproval.js";
|
|
9
11
|
import { LoginNotification } from "./LoginNotification.js";
|
|
10
12
|
import { LoginRiskEngine, defaultLoginRiskContext, makeLoginRiskEngineNoop, } from "./LoginRisk.js";
|
|
13
|
+
import { PasskeyCredentialManagement } from "./Passkey.js";
|
|
14
|
+
import { RecoveryCodeManagement } from "./RecoveryCode.js";
|
|
15
|
+
import { RecoveryRequirementPolicy } from "./RecoveryPolicy.js";
|
|
11
16
|
import { Sessions, sessionRequestMetadataKey } from "./Sessions.js";
|
|
17
|
+
import { TotpFactorManagement } from "./Totp.js";
|
|
12
18
|
import { TrustedDevice } from "./TrustedDevice.js";
|
|
13
19
|
export const defaultLoginApprovalSameDeviceSecretBytes = 32;
|
|
14
20
|
export class EmailVerificationSessionPolicy extends Context.Service()("auth/EmailVerificationSessionPolicy") {
|
|
15
21
|
}
|
|
16
|
-
(function (EmailVerificationSessionPolicy) {
|
|
17
|
-
EmailVerificationSessionPolicy.make = (service) => EmailVerificationSessionPolicy.of(service);
|
|
18
|
-
})(EmailVerificationSessionPolicy || (EmailVerificationSessionPolicy = {}));
|
|
19
22
|
const addEmailVerificationRequirement = (requirements) => requirements?.includes("email_verification") === true
|
|
20
23
|
? requirements
|
|
21
24
|
: [...(requirements ?? []), "email_verification"];
|
|
@@ -23,40 +26,40 @@ const removeEmailVerificationRequirement = (requirements) => {
|
|
|
23
26
|
const filtered = requirements?.filter((requirement) => requirement !== "email_verification");
|
|
24
27
|
return filtered?.length === 0 ? undefined : filtered;
|
|
25
28
|
};
|
|
26
|
-
const
|
|
29
|
+
const withVerifiedIdentityKind = (claims, kind) => {
|
|
27
30
|
const { requirements: _requirements, ...rest } = claims ?? {};
|
|
28
|
-
const requirements =
|
|
31
|
+
const requirements = kind === "email"
|
|
29
32
|
? removeEmailVerificationRequirement(claims?.requirements)
|
|
30
33
|
: claims?.requirements;
|
|
34
|
+
const verifiedIdentityKinds = claims?.verifiedIdentityKinds?.includes(kind)
|
|
35
|
+
? claims.verifiedIdentityKinds
|
|
36
|
+
: [...(claims?.verifiedIdentityKinds ?? []), kind];
|
|
31
37
|
return {
|
|
32
38
|
...rest,
|
|
33
|
-
|
|
39
|
+
verifiedIdentityKinds,
|
|
34
40
|
...(requirements === undefined ? {} : { requirements }),
|
|
35
41
|
};
|
|
36
42
|
};
|
|
37
43
|
const withEmailVerificationRequirement = (claims) => ({
|
|
38
44
|
...claims,
|
|
39
|
-
emailVerified: false,
|
|
40
45
|
requirements: addEmailVerificationRequirement(claims?.requirements),
|
|
41
46
|
});
|
|
42
47
|
export const makeEmailVerificationSessionPolicy = (options = {}) => {
|
|
43
48
|
const mode = options.mode ?? "allow-unverified";
|
|
44
|
-
return EmailVerificationSessionPolicy.
|
|
49
|
+
return EmailVerificationSessionPolicy.of({
|
|
45
50
|
decide: Effect.fn("auth.email_verification_session_policy.decide")(function* (input) {
|
|
46
|
-
const emailVerified = input.claims?.
|
|
47
|
-
if (emailVerified
|
|
51
|
+
const emailVerified = input.claims?.verifiedIdentityKinds?.includes("email");
|
|
52
|
+
if (emailVerified === true) {
|
|
48
53
|
return {
|
|
49
54
|
_tag: "CreateSession",
|
|
50
|
-
claims:
|
|
51
|
-
? withEmailVerified(input.claims, true)
|
|
52
|
-
: input.claims,
|
|
55
|
+
claims: withVerifiedIdentityKind(input.claims, "email"),
|
|
53
56
|
};
|
|
54
57
|
}
|
|
55
58
|
switch (mode) {
|
|
56
59
|
case "allow-unverified": {
|
|
57
60
|
return {
|
|
58
61
|
_tag: "CreateSession",
|
|
59
|
-
claims:
|
|
62
|
+
claims: input.claims,
|
|
60
63
|
};
|
|
61
64
|
}
|
|
62
65
|
case "limited-session": {
|
|
@@ -70,35 +73,119 @@ export const makeEmailVerificationSessionPolicy = (options = {}) => {
|
|
|
70
73
|
});
|
|
71
74
|
};
|
|
72
75
|
export const EmailVerificationSessionPolicyLive = (options) => Layer.succeed(EmailVerificationSessionPolicy)(makeEmailVerificationSessionPolicy(options));
|
|
76
|
+
export class MfaRequirementPolicy extends Context.Service()("auth/MfaRequirementPolicy") {
|
|
77
|
+
}
|
|
78
|
+
export const defaultMfaRequirementMethods = [
|
|
79
|
+
"password",
|
|
80
|
+
"email-otp",
|
|
81
|
+
"magic-link",
|
|
82
|
+
"oauth",
|
|
83
|
+
];
|
|
84
|
+
export const makeMfaRequirementPolicy = (options = {}) => {
|
|
85
|
+
const mode = options.mode ?? "when-factors-present";
|
|
86
|
+
const methods = new Set(options.methods ?? defaultMfaRequirementMethods);
|
|
87
|
+
return MfaRequirementPolicy.of({
|
|
88
|
+
decide: Effect.fn("auth.mfa_requirement_policy.decide")(function* (input) {
|
|
89
|
+
if (mode === "disabled" ||
|
|
90
|
+
input.intent === "sign-up" ||
|
|
91
|
+
!methods.has(input.method) ||
|
|
92
|
+
input.factors.length === 0) {
|
|
93
|
+
return { _tag: "Continue" };
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
_tag: "RequireMfa",
|
|
97
|
+
factors: input.factors,
|
|
98
|
+
};
|
|
99
|
+
}),
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
export const MfaRequirementPolicyLive = (options) => Layer.succeed(MfaRequirementPolicy)(makeMfaRequirementPolicy(options));
|
|
103
|
+
export class AuthFlowPipeline extends Context.Service()("auth/AuthFlowPipeline") {
|
|
104
|
+
}
|
|
105
|
+
(function (AuthFlowPipeline) {
|
|
106
|
+
AuthFlowPipeline.continueWith = () => ({
|
|
107
|
+
_tag: "Continue",
|
|
108
|
+
});
|
|
109
|
+
AuthFlowPipeline.deny = (reason) => ({
|
|
110
|
+
_tag: "PolicyDenied",
|
|
111
|
+
...(reason === undefined ? {} : { reason }),
|
|
112
|
+
});
|
|
113
|
+
})(AuthFlowPipeline || (AuthFlowPipeline = {}));
|
|
114
|
+
export const makeAuthFlowPipeline = (stages = []) => AuthFlowPipeline.of({
|
|
115
|
+
advance: (initial) => Effect.gen(function* () {
|
|
116
|
+
for (const stage of stages) {
|
|
117
|
+
if (stage.phases !== undefined &&
|
|
118
|
+
!stage.phases.includes(initial.phase)) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const decision = yield* stage.run(initial);
|
|
122
|
+
if (decision._tag === "PolicyDenied") {
|
|
123
|
+
return decision;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return AuthFlowPipeline.continueWith();
|
|
127
|
+
}),
|
|
128
|
+
});
|
|
129
|
+
export const AuthFlowPipelineLive = (stages = []) => Layer.succeed(AuthFlowPipeline)(makeAuthFlowPipeline(stages));
|
|
73
130
|
export const AuthResult = Data.taggedEnum();
|
|
74
131
|
export class AuthFlowStateError extends Data.TaggedError("AuthFlowStateError") {
|
|
75
132
|
}
|
|
76
133
|
export class AuthFlowState extends Context.Service()("auth/AuthFlowState") {
|
|
77
134
|
}
|
|
78
|
-
(function (AuthFlowState) {
|
|
79
|
-
AuthFlowState.make = (service) => AuthFlowState.of(service);
|
|
80
|
-
})(AuthFlowState || (AuthFlowState = {}));
|
|
81
135
|
export const defaultAuthFlowStateTtl = Duration.minutes(10);
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
136
|
+
const mfaFactorsMetadataKey = "__authMfaFactors";
|
|
137
|
+
const applicationFlowStateMetadata = (metadata) => {
|
|
138
|
+
if (metadata === undefined) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
const { method: _method, evidence: _evidence, identity: _identity, emailDestination: _emailDestination, intent: _intent, deviceStatus: _deviceStatus, deviceKey: _deviceKey, locationKey: _locationKey, claims: _claims, [sessionRequestMetadataKey]: _request, [mfaFactorsMetadataKey]: _mfaFactors, ...rest } = metadata;
|
|
142
|
+
return Object.keys(rest).length === 0 ? undefined : rest;
|
|
143
|
+
};
|
|
144
|
+
const flowStateMetadata = (input) => {
|
|
145
|
+
const metadata = applicationFlowStateMetadata(input.metadata);
|
|
146
|
+
return {
|
|
147
|
+
...metadata,
|
|
148
|
+
...(input.request === undefined
|
|
149
|
+
? {}
|
|
150
|
+
: { [sessionRequestMetadataKey]: input.request }),
|
|
151
|
+
method: input.method,
|
|
152
|
+
evidence: input.evidence,
|
|
153
|
+
...(input.identity === undefined ? {} : { identity: input.identity }),
|
|
154
|
+
...(input.emailDestination === undefined
|
|
155
|
+
? {}
|
|
156
|
+
: { emailDestination: input.emailDestination }),
|
|
157
|
+
...(input.intent === undefined ? {} : { intent: input.intent }),
|
|
158
|
+
...(input.device === undefined
|
|
159
|
+
? {}
|
|
160
|
+
: { deviceStatus: input.device.status }),
|
|
161
|
+
...(input.deviceKey === undefined ? {} : { deviceKey: input.deviceKey }),
|
|
162
|
+
...(input.locationKey === undefined
|
|
163
|
+
? {}
|
|
164
|
+
: { locationKey: input.locationKey }),
|
|
165
|
+
...(input.claims === undefined ? {} : { claims: input.claims }),
|
|
166
|
+
...(input.factors === undefined
|
|
167
|
+
? {}
|
|
168
|
+
: { [mfaFactorsMetadataKey]: input.factors }),
|
|
169
|
+
};
|
|
170
|
+
};
|
|
92
171
|
const metadataString = (metadata, key) => {
|
|
93
172
|
const value = metadata?.[key];
|
|
94
173
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
95
174
|
};
|
|
96
|
-
const
|
|
97
|
-
const value = metadata?.[
|
|
98
|
-
return
|
|
175
|
+
const loginRequestContextFromMetadata = (metadata) => {
|
|
176
|
+
const value = metadata?.[sessionRequestMetadataKey];
|
|
177
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
99
178
|
? value
|
|
100
179
|
: undefined;
|
|
101
180
|
};
|
|
181
|
+
const metadataEvidence = (metadata) => {
|
|
182
|
+
try {
|
|
183
|
+
return parseAuthenticationEvents(metadata?.evidence);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
102
189
|
const metadataClaims = (metadata) => {
|
|
103
190
|
const value = metadata?.claims;
|
|
104
191
|
if (value === undefined) {
|
|
@@ -109,8 +196,18 @@ const metadataClaims = (metadata) => {
|
|
|
109
196
|
}
|
|
110
197
|
const shape = value;
|
|
111
198
|
const { requirements } = shape;
|
|
112
|
-
if (shape.
|
|
113
|
-
|
|
199
|
+
if (shape.verifiedIdentityKinds !== undefined &&
|
|
200
|
+
(!Array.isArray(shape.verifiedIdentityKinds) ||
|
|
201
|
+
!shape.verifiedIdentityKinds.every((item) => typeof item === "string"))) {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
const recoveryEnrollment = shape.recoveryEnrollment;
|
|
205
|
+
if (recoveryEnrollment !== undefined &&
|
|
206
|
+
(typeof recoveryEnrollment !== "object" ||
|
|
207
|
+
recoveryEnrollment === null ||
|
|
208
|
+
!Array.isArray(recoveryEnrollment.allowed) ||
|
|
209
|
+
recoveryEnrollment.allowed.length === 0 ||
|
|
210
|
+
!recoveryEnrollment.allowed.every((item) => typeof item === "string"))) {
|
|
114
211
|
return undefined;
|
|
115
212
|
}
|
|
116
213
|
if (requirements !== undefined &&
|
|
@@ -119,16 +216,49 @@ const metadataClaims = (metadata) => {
|
|
|
119
216
|
return undefined;
|
|
120
217
|
}
|
|
121
218
|
return {
|
|
122
|
-
...(shape.
|
|
219
|
+
...(shape.verifiedIdentityKinds === undefined
|
|
123
220
|
? {}
|
|
124
|
-
: {
|
|
221
|
+
: {
|
|
222
|
+
verifiedIdentityKinds: shape.verifiedIdentityKinds,
|
|
223
|
+
}),
|
|
125
224
|
...(requirements === undefined ? {} : { requirements }),
|
|
225
|
+
...(recoveryEnrollment === undefined
|
|
226
|
+
? {}
|
|
227
|
+
: {
|
|
228
|
+
recoveryEnrollment: {
|
|
229
|
+
allowed: recoveryEnrollment.allowed,
|
|
230
|
+
},
|
|
231
|
+
}),
|
|
126
232
|
};
|
|
127
233
|
};
|
|
128
|
-
const
|
|
129
|
-
const value =
|
|
130
|
-
|
|
131
|
-
|
|
234
|
+
const metadataIdentity = (metadata) => {
|
|
235
|
+
const value = metadata?.identity;
|
|
236
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
const identity = value;
|
|
240
|
+
return typeof identity.identityId === "string" &&
|
|
241
|
+
typeof identity.kind === "string" &&
|
|
242
|
+
typeof identity.verified === "boolean"
|
|
243
|
+
? {
|
|
244
|
+
identityId: identity.identityId,
|
|
245
|
+
kind: identity.kind,
|
|
246
|
+
verified: identity.verified,
|
|
247
|
+
}
|
|
248
|
+
: undefined;
|
|
249
|
+
};
|
|
250
|
+
const metadataEmailDestination = (metadata) => {
|
|
251
|
+
const value = metadata?.emailDestination;
|
|
252
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
const destination = value;
|
|
256
|
+
return typeof destination.identityId === "string" &&
|
|
257
|
+
typeof destination.email === "string"
|
|
258
|
+
? {
|
|
259
|
+
identityId: destination.identityId,
|
|
260
|
+
email: destination.email,
|
|
261
|
+
}
|
|
132
262
|
: undefined;
|
|
133
263
|
};
|
|
134
264
|
const metadataIntent = (metadata) => {
|
|
@@ -141,34 +271,45 @@ const metadataDevice = (metadata) => {
|
|
|
141
271
|
? { status: value }
|
|
142
272
|
: undefined;
|
|
143
273
|
};
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
return undefined;
|
|
147
|
-
}
|
|
148
|
-
const { method: _method, amr: _amr, aal: _aal, email: _email, intent: _intent, deviceStatus: _deviceStatus, claims: _claims, ...rest } = metadata;
|
|
149
|
-
return Object.keys(rest).length === 0 ? undefined : rest;
|
|
150
|
-
};
|
|
274
|
+
const metadataKey = (metadata, key) => metadataString(metadata, key);
|
|
275
|
+
const appMetadata = applicationFlowStateMetadata;
|
|
151
276
|
const authFlowStateFromChallenge = (flowId, verified) => Effect.gen(function* () {
|
|
152
277
|
const method = metadataString(verified.metadata, "method");
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
const
|
|
278
|
+
const evidence = metadataEvidence(verified.metadata);
|
|
279
|
+
const identity = metadataIdentity(verified.metadata);
|
|
280
|
+
const emailDestination = metadataEmailDestination(verified.metadata);
|
|
156
281
|
const intent = metadataIntent(verified.metadata);
|
|
157
282
|
const device = metadataDevice(verified.metadata);
|
|
283
|
+
const deviceKey = metadataKey(verified.metadata, "deviceKey");
|
|
284
|
+
const locationKey = metadataKey(verified.metadata, "locationKey");
|
|
158
285
|
const claims = metadataClaims(verified.metadata);
|
|
286
|
+
const request = loginRequestContextFromMetadata(verified.metadata);
|
|
287
|
+
const rawFactors = verified.metadata?.[mfaFactorsMetadataKey];
|
|
288
|
+
let factors;
|
|
289
|
+
if (rawFactors !== undefined) {
|
|
290
|
+
if (!Array.isArray(rawFactors) ||
|
|
291
|
+
rawFactors.length === 0 ||
|
|
292
|
+
!rawFactors.every((factor) => typeof factor === "object" &&
|
|
293
|
+
factor !== null &&
|
|
294
|
+
!Array.isArray(factor) &&
|
|
295
|
+
typeof factor.type === "string" &&
|
|
296
|
+
factor.type.length > 0)) {
|
|
297
|
+
return yield* new AuthFlowStateError({
|
|
298
|
+
message: "Auth flow state has invalid MFA factor metadata",
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
factors = rawFactors.map((factor) => ({
|
|
302
|
+
type: factor.type,
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
159
305
|
if (method === undefined) {
|
|
160
306
|
return yield* new AuthFlowStateError({
|
|
161
307
|
message: "Auth flow state is missing method metadata",
|
|
162
308
|
});
|
|
163
309
|
}
|
|
164
|
-
if (
|
|
165
|
-
return yield* new AuthFlowStateError({
|
|
166
|
-
message: "Auth flow state is missing AMR metadata",
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
if (aal === undefined) {
|
|
310
|
+
if (evidence === undefined) {
|
|
170
311
|
return yield* new AuthFlowStateError({
|
|
171
|
-
message: "Auth flow state
|
|
312
|
+
message: "Auth flow state has invalid evidence metadata",
|
|
172
313
|
});
|
|
173
314
|
}
|
|
174
315
|
if (verified.metadata?.claims !== undefined && claims === undefined) {
|
|
@@ -179,19 +320,23 @@ const authFlowStateFromChallenge = (flowId, verified) => Effect.gen(function* ()
|
|
|
179
320
|
return {
|
|
180
321
|
flowId,
|
|
181
322
|
userId: UserId(verified.subject),
|
|
182
|
-
...(
|
|
323
|
+
...(identity === undefined ? {} : { identity }),
|
|
324
|
+
...(emailDestination === undefined ? {} : { emailDestination }),
|
|
183
325
|
...(intent === undefined ? {} : { intent }),
|
|
184
326
|
method,
|
|
185
|
-
|
|
186
|
-
aal,
|
|
327
|
+
evidence,
|
|
187
328
|
...(device === undefined ? {} : { device }),
|
|
329
|
+
...(deviceKey === undefined ? {} : { deviceKey }),
|
|
330
|
+
...(locationKey === undefined ? {} : { locationKey }),
|
|
188
331
|
...(claims === undefined ? {} : { claims }),
|
|
332
|
+
...(request === undefined ? {} : { request }),
|
|
333
|
+
...(factors === undefined ? {} : { factors }),
|
|
189
334
|
metadata: appMetadata(verified.metadata),
|
|
190
335
|
};
|
|
191
336
|
});
|
|
192
337
|
export const makeAuthFlowState = (dependencies) => {
|
|
193
338
|
const ttl = dependencies.ttl ?? defaultAuthFlowStateTtl;
|
|
194
|
-
return AuthFlowState.
|
|
339
|
+
return AuthFlowState.of({
|
|
195
340
|
start: Effect.fn("auth.auth_flow_state.start")(function* (input) {
|
|
196
341
|
const issued = yield* dependencies.challenge
|
|
197
342
|
.issue({
|
|
@@ -252,16 +397,10 @@ export const AuthFlowStateLive = (options) => Layer.effect(AuthFlowState)(Effect
|
|
|
252
397
|
}));
|
|
253
398
|
export class AuthFlow extends Context.Service()("auth/AuthFlow") {
|
|
254
399
|
}
|
|
255
|
-
(function (AuthFlow) {
|
|
256
|
-
AuthFlow.make = (service) => AuthFlow.of(service);
|
|
257
|
-
})(AuthFlow || (AuthFlow = {}));
|
|
258
400
|
export class LoginApprovalFinalize extends Context.Service()("auth/LoginApprovalFinalize") {
|
|
259
401
|
}
|
|
260
|
-
(function (LoginApprovalFinalize) {
|
|
261
|
-
LoginApprovalFinalize.make = (service) => LoginApprovalFinalize.of(service);
|
|
262
|
-
})(LoginApprovalFinalize || (LoginApprovalFinalize = {}));
|
|
263
402
|
const loginApprovalFinalizeDenied = (reason) => AuthResult.PolicyDenied({ reason });
|
|
264
|
-
export const makeLoginApprovalFinalize = (dependencies) => LoginApprovalFinalize.
|
|
403
|
+
export const makeLoginApprovalFinalize = (dependencies) => LoginApprovalFinalize.of({
|
|
265
404
|
complete: Effect.fn("auth.login_approval_finalize.complete")(function* (input) {
|
|
266
405
|
const recordOption = yield* dependencies.loginApprovalReview.status({
|
|
267
406
|
approvalChallengeId: input.approvalChallengeId,
|
|
@@ -287,19 +426,19 @@ export const makeLoginApprovalFinalize = (dependencies) => LoginApprovalFinalize
|
|
|
287
426
|
if (consumed.userId !== record.userId) {
|
|
288
427
|
return loginApprovalFinalizeDenied("Invalid login approval review");
|
|
289
428
|
}
|
|
290
|
-
return yield* dependencies.
|
|
429
|
+
return yield* dependencies.finalizeAuthFlow(consumed);
|
|
291
430
|
}),
|
|
292
431
|
});
|
|
293
|
-
export const LoginApprovalFinalizeLive = Layer.effect(LoginApprovalFinalize
|
|
432
|
+
export const LoginApprovalFinalizeLive = Layer.effect(LoginApprovalFinalize, Effect.gen(function* () {
|
|
294
433
|
const loginApprovalReview = yield* LoginApprovalReview;
|
|
295
434
|
const authFlowState = yield* AuthFlowState;
|
|
296
|
-
const
|
|
435
|
+
const authFlowFinalizer = yield* AuthFlowFinalizer;
|
|
297
436
|
return makeLoginApprovalFinalize({
|
|
298
437
|
loginApprovalReview,
|
|
299
438
|
authFlowState,
|
|
300
|
-
|
|
439
|
+
finalizeAuthFlow: authFlowFinalizer.complete,
|
|
301
440
|
});
|
|
302
|
-
}));
|
|
441
|
+
})).pipe(Layer.provide(AuthFlowFinalizerLive));
|
|
303
442
|
const loginApprovalFlowIdMetadata = (flowId, metadata) => ({
|
|
304
443
|
...metadata,
|
|
305
444
|
flowId,
|
|
@@ -319,61 +458,15 @@ const mergeMetadata = (left, right) => {
|
|
|
319
458
|
}
|
|
320
459
|
return { ...left, ...right };
|
|
321
460
|
};
|
|
322
|
-
const aalRank = {
|
|
323
|
-
aal1: 1,
|
|
324
|
-
aal2: 2,
|
|
325
|
-
aal3: 3,
|
|
326
|
-
};
|
|
327
|
-
const strongerAal = (left, right) => (aalRank[left] >= aalRank[right] ? left : right);
|
|
328
|
-
const authMethodReference = (method) => {
|
|
329
|
-
switch (method) {
|
|
330
|
-
case "password": {
|
|
331
|
-
return "pwd";
|
|
332
|
-
}
|
|
333
|
-
case "email-otp": {
|
|
334
|
-
return "otp";
|
|
335
|
-
}
|
|
336
|
-
case "magic-link": {
|
|
337
|
-
return "magic_link";
|
|
338
|
-
}
|
|
339
|
-
case "backup-code": {
|
|
340
|
-
return "backup_code";
|
|
341
|
-
}
|
|
342
|
-
default: {
|
|
343
|
-
return method;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
const appendAuthMethods = (current, methods) => {
|
|
348
|
-
const next = [...current];
|
|
349
|
-
for (const method of methods) {
|
|
350
|
-
if (!next.includes(method)) {
|
|
351
|
-
next.push(method);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
return next;
|
|
355
|
-
};
|
|
356
|
-
const loginNotificationSession = (session) => ({
|
|
357
|
-
sessionId: session.sessionId,
|
|
358
|
-
userId: session.userId,
|
|
359
|
-
authTime: session.authTime,
|
|
360
|
-
expiresAt: session.expiresAt,
|
|
361
|
-
aal: session.aal,
|
|
362
|
-
amr: session.amr,
|
|
363
|
-
...(session.claims === undefined ? {} : { claims: session.claims }),
|
|
364
|
-
});
|
|
365
|
-
const loginRequestContextFromMetadata = (metadata) => {
|
|
366
|
-
const value = metadata?.[sessionRequestMetadataKey];
|
|
367
|
-
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
368
|
-
? value
|
|
369
|
-
: undefined;
|
|
370
|
-
};
|
|
371
461
|
const loginApprovalNotConfigured = () => AuthResult.PolicyDenied({
|
|
372
462
|
reason: "Login approval is not configured",
|
|
373
463
|
});
|
|
374
464
|
const loginApprovalEmailMissing = () => AuthResult.PolicyDenied({
|
|
375
465
|
reason: "Login approval requires an email address",
|
|
376
466
|
});
|
|
467
|
+
const loginApprovalIdentityNotBound = () => AuthResult.PolicyDenied({
|
|
468
|
+
reason: "Login approval identity verification is not bound to an email identity",
|
|
469
|
+
});
|
|
377
470
|
const loginApprovalSameDeviceNotConfigured = () => AuthResult.PolicyDenied({
|
|
378
471
|
reason: "Login approval same-device binding is not configured",
|
|
379
472
|
});
|
|
@@ -386,7 +479,39 @@ const mfaFlowStateNotConfigured = () => AuthResult.PolicyDenied({
|
|
|
386
479
|
const mfaFlowUserMismatch = () => AuthResult.PolicyDenied({
|
|
387
480
|
reason: "MFA flow user mismatch",
|
|
388
481
|
});
|
|
482
|
+
const mfaFlowFactorNotAllowed = () => AuthResult.PolicyDenied({
|
|
483
|
+
reason: "MFA factor is not allowed for this flow",
|
|
484
|
+
});
|
|
485
|
+
const completedMfaFactorType = (input) => {
|
|
486
|
+
if (input.method === "totp") {
|
|
487
|
+
return input.evidence.type === "totp" ? "totp" : undefined;
|
|
488
|
+
}
|
|
489
|
+
if (input.method === "backup-code") {
|
|
490
|
+
return input.evidence.type === "recovery_code" ? "backup-code" : undefined;
|
|
491
|
+
}
|
|
492
|
+
if (input.method === "passkey") {
|
|
493
|
+
return input.evidence.type === "passkey" &&
|
|
494
|
+
input.evidence.userVerification === "verified"
|
|
495
|
+
? "passkey"
|
|
496
|
+
: undefined;
|
|
497
|
+
}
|
|
498
|
+
return undefined;
|
|
499
|
+
};
|
|
500
|
+
const authFlowStateAllowsMfa = (state, input) => {
|
|
501
|
+
const factorType = completedMfaFactorType(input);
|
|
502
|
+
return (factorType !== undefined &&
|
|
503
|
+
state.factors?.some((factor) => factor.type === factorType) === true);
|
|
504
|
+
};
|
|
505
|
+
const primaryFactorNotEstablished = () => AuthResult.PolicyDenied({
|
|
506
|
+
reason: "Authentication evidence did not establish a primary factor",
|
|
507
|
+
});
|
|
389
508
|
const optionalLoginApprovalDependencies = Effect.gen(function* () {
|
|
509
|
+
const pipeline = yield* Effect.serviceOption(AuthFlowPipeline);
|
|
510
|
+
const emailVerificationSessionPolicy = yield* Effect.serviceOption(EmailVerificationSessionPolicy);
|
|
511
|
+
const mfaRequirementPolicy = yield* Effect.serviceOption(MfaRequirementPolicy);
|
|
512
|
+
const totpFactorManagement = yield* Effect.serviceOption(TotpFactorManagement);
|
|
513
|
+
const recoveryCodeManagement = yield* Effect.serviceOption(RecoveryCodeManagement);
|
|
514
|
+
const passkeyCredentialManagement = yield* Effect.serviceOption(PasskeyCredentialManagement);
|
|
390
515
|
const loginApprovalPolicy = yield* Effect.serviceOption(LoginApprovalPolicy);
|
|
391
516
|
const loginApprovalFlow = yield* Effect.serviceOption(LoginApprovalFlow);
|
|
392
517
|
const authFlowState = yield* Effect.serviceOption(AuthFlowState);
|
|
@@ -395,7 +520,24 @@ const optionalLoginApprovalDependencies = Effect.gen(function* () {
|
|
|
395
520
|
const loginRiskEngine = yield* Effect.serviceOption(LoginRiskEngine);
|
|
396
521
|
const loginApprovalReview = yield* Effect.serviceOption(LoginApprovalReview);
|
|
397
522
|
const loginNotification = yield* Effect.serviceOption(LoginNotification);
|
|
523
|
+
const recoveryRequirementPolicy = yield* Effect.serviceOption(RecoveryRequirementPolicy);
|
|
398
524
|
return {
|
|
525
|
+
...(Option.isSome(pipeline) ? { pipeline: pipeline.value } : {}),
|
|
526
|
+
...(Option.isSome(emailVerificationSessionPolicy)
|
|
527
|
+
? { emailVerificationSessionPolicy: emailVerificationSessionPolicy.value }
|
|
528
|
+
: {}),
|
|
529
|
+
...(Option.isSome(mfaRequirementPolicy)
|
|
530
|
+
? { mfaRequirementPolicy: mfaRequirementPolicy.value }
|
|
531
|
+
: {}),
|
|
532
|
+
...(Option.isSome(totpFactorManagement)
|
|
533
|
+
? { totpFactorManagement: totpFactorManagement.value }
|
|
534
|
+
: {}),
|
|
535
|
+
...(Option.isSome(recoveryCodeManagement)
|
|
536
|
+
? { recoveryCodeManagement: recoveryCodeManagement.value }
|
|
537
|
+
: {}),
|
|
538
|
+
...(Option.isSome(passkeyCredentialManagement)
|
|
539
|
+
? { passkeyCredentialManagement: passkeyCredentialManagement.value }
|
|
540
|
+
: {}),
|
|
399
541
|
...(Option.isSome(loginApprovalPolicy)
|
|
400
542
|
? { loginApprovalPolicy: loginApprovalPolicy.value }
|
|
401
543
|
: {}),
|
|
@@ -418,15 +560,22 @@ const optionalLoginApprovalDependencies = Effect.gen(function* () {
|
|
|
418
560
|
...(Option.isSome(loginNotification)
|
|
419
561
|
? { loginNotification: loginNotification.value }
|
|
420
562
|
: {}),
|
|
563
|
+
...(Option.isSome(recoveryRequirementPolicy)
|
|
564
|
+
? { recoveryRequirementPolicy: recoveryRequirementPolicy.value }
|
|
565
|
+
: {}),
|
|
421
566
|
};
|
|
422
567
|
});
|
|
423
568
|
export const makeAuthFlow = (dependencies) => {
|
|
424
569
|
const emailVerificationSessionPolicy = dependencies.emailVerificationSessionPolicy ??
|
|
425
570
|
makeEmailVerificationSessionPolicy();
|
|
571
|
+
const mfaRequirementPolicy = dependencies.mfaRequirementPolicy ?? makeMfaRequirementPolicy();
|
|
426
572
|
const loginApprovalPolicy = dependencies.loginApprovalPolicy ?? makeLoginApprovalPolicy();
|
|
427
573
|
const loginRiskEngine = dependencies.loginRiskEngine ?? makeLoginRiskEngineNoop();
|
|
574
|
+
const pipeline = dependencies.pipeline ?? makeAuthFlowPipeline();
|
|
428
575
|
const loginApprovalSameDeviceSecretBytes = dependencies.loginApprovalSameDeviceSecretBytes ??
|
|
429
576
|
defaultLoginApprovalSameDeviceSecretBytes;
|
|
577
|
+
const flowTerminal = makeAuthFlowTerminal(dependencies);
|
|
578
|
+
const deriveFlowInput = flowTerminal.derive;
|
|
430
579
|
const resolveDevice = (input) => {
|
|
431
580
|
if (input.device !== undefined) {
|
|
432
581
|
return Effect.succeed(input.device);
|
|
@@ -439,79 +588,223 @@ export const makeAuthFlow = (dependencies) => {
|
|
|
439
588
|
token: input.trustedDeviceToken,
|
|
440
589
|
});
|
|
441
590
|
};
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
.
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
591
|
+
const detectMfaFactors = (input) => Effect.gen(function* () {
|
|
592
|
+
const factors = [];
|
|
593
|
+
if (dependencies.totpFactorManagement !== undefined &&
|
|
594
|
+
!input.amr.includes("totp")) {
|
|
595
|
+
const totpFactors = yield* dependencies.totpFactorManagement.listForUser({
|
|
596
|
+
userId: input.userId,
|
|
597
|
+
});
|
|
598
|
+
if (totpFactors.length > 0) {
|
|
599
|
+
factors.push({ type: "totp" });
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (dependencies.recoveryCodeManagement !== undefined &&
|
|
603
|
+
!input.amr.includes("recovery_code")) {
|
|
604
|
+
const recoveryCodes = yield* dependencies.recoveryCodeManagement.listForUser({
|
|
605
|
+
userId: input.userId,
|
|
606
|
+
});
|
|
607
|
+
if (recoveryCodes.length > 0) {
|
|
608
|
+
factors.push({ type: "backup-code" });
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
if (dependencies.passkeyCredentialManagement !== undefined &&
|
|
612
|
+
!input.amr.includes("passkey")) {
|
|
613
|
+
const credentials = yield* dependencies.passkeyCredentialManagement.listForUser({
|
|
614
|
+
userId: input.userId,
|
|
615
|
+
});
|
|
616
|
+
if (credentials.length > 0) {
|
|
617
|
+
factors.push({ type: "passkey" });
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return factors;
|
|
621
|
+
});
|
|
622
|
+
const requireMfaIfNeeded = (input) => Effect.gen(function* () {
|
|
623
|
+
const factors = yield* detectMfaFactors(input);
|
|
624
|
+
const decision = yield* mfaRequirementPolicy.decide({
|
|
625
|
+
...input,
|
|
626
|
+
factors,
|
|
464
627
|
});
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
628
|
+
return decision._tag === "RequireMfa"
|
|
629
|
+
? Option.some(yield* requireMfa({
|
|
630
|
+
...input,
|
|
631
|
+
factors: decision.factors,
|
|
632
|
+
}))
|
|
633
|
+
: Option.none();
|
|
634
|
+
});
|
|
635
|
+
const requireMfa = Effect.fn("auth.auth_flow.require_mfa")(function* (input) {
|
|
636
|
+
if (dependencies.authFlowState === undefined) {
|
|
637
|
+
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
638
|
+
return mfaFlowStateNotConfigured();
|
|
639
|
+
}
|
|
640
|
+
const derived = yield* deriveFlowInput(input);
|
|
641
|
+
if (!derived.primaryEstablished) {
|
|
642
|
+
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
643
|
+
return primaryFactorNotEstablished();
|
|
644
|
+
}
|
|
645
|
+
const emailVerificationDecision = yield* emailVerificationSessionPolicy.decide({
|
|
646
|
+
claims: derived.claims,
|
|
647
|
+
});
|
|
648
|
+
const metadata = sessionMetadata(applicationFlowStateMetadata(derived.metadata), derived.request);
|
|
649
|
+
const device = yield* resolveDevice(derived);
|
|
650
|
+
const flowState = yield* dependencies.authFlowState.start({
|
|
651
|
+
userId: derived.userId,
|
|
652
|
+
method: derived.method,
|
|
653
|
+
evidence: derived.evidence,
|
|
654
|
+
...(derived.identity === undefined ? {} : { identity: derived.identity }),
|
|
655
|
+
...(derived.emailDestination === undefined
|
|
472
656
|
? {}
|
|
473
|
-
: {
|
|
474
|
-
|
|
657
|
+
: { emailDestination: derived.emailDestination }),
|
|
658
|
+
...(derived.intent === undefined ? {} : { intent: derived.intent }),
|
|
659
|
+
device,
|
|
660
|
+
...(derived.deviceKey === undefined
|
|
661
|
+
? {}
|
|
662
|
+
: { deviceKey: derived.deviceKey }),
|
|
663
|
+
...(derived.locationKey === undefined
|
|
664
|
+
? {}
|
|
665
|
+
: { locationKey: derived.locationKey }),
|
|
666
|
+
...(derived.request === undefined ? {} : { request: derived.request }),
|
|
667
|
+
claims: emailVerificationDecision.claims,
|
|
668
|
+
...(input.secret === undefined ? {} : { secret: input.secret }),
|
|
669
|
+
...(input.ttl === undefined ? {} : { ttl: input.ttl }),
|
|
670
|
+
factors: input.factors,
|
|
671
|
+
...(metadata === undefined ? {} : { metadata }),
|
|
672
|
+
});
|
|
673
|
+
yield* Effect.annotateCurrentSpan({
|
|
674
|
+
"auth.result": "RequiresMfa",
|
|
675
|
+
"auth.mfa.factor_count": input.factors.length,
|
|
676
|
+
});
|
|
677
|
+
return AuthResult.RequiresMfa({
|
|
678
|
+
flowId: flowState.flowId,
|
|
679
|
+
factors: input.factors,
|
|
475
680
|
});
|
|
476
|
-
yield* notifyLogin(input, session);
|
|
477
|
-
yield* Effect.annotateCurrentSpan("auth.result", "Authenticated");
|
|
478
|
-
return AuthResult.Authenticated({ session });
|
|
479
681
|
});
|
|
480
|
-
const
|
|
682
|
+
const advance = Effect.fn("auth.auth_flow.advance")(function* (initial, mfaSatisfied, terminal, handleLoginApproval, mfaMethod) {
|
|
683
|
+
let input = yield* deriveFlowInput(initial);
|
|
684
|
+
if (!input.primaryEstablished) {
|
|
685
|
+
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
686
|
+
return primaryFactorNotEstablished();
|
|
687
|
+
}
|
|
688
|
+
if (mfaMethod !== undefined) {
|
|
689
|
+
yield* Effect.annotateCurrentSpan({
|
|
690
|
+
"auth.mfa.method": mfaMethod,
|
|
691
|
+
"auth.mfa.aal": input.aal,
|
|
692
|
+
"auth.mfa.amr_count": input.amr.length,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
481
695
|
const emailVerificationDecision = yield* emailVerificationSessionPolicy.decide({
|
|
482
696
|
claims: input.claims,
|
|
483
697
|
});
|
|
484
|
-
const metadata = sessionMetadata(input.metadata, input.request);
|
|
698
|
+
const metadata = sessionMetadata(applicationFlowStateMetadata(input.metadata), input.request);
|
|
485
699
|
const device = yield* resolveDevice(input);
|
|
700
|
+
input = {
|
|
701
|
+
...input,
|
|
702
|
+
claims: emailVerificationDecision.claims,
|
|
703
|
+
device,
|
|
704
|
+
...(input.request === undefined && metadata !== undefined
|
|
705
|
+
? { request: loginRequestContextFromMetadata(metadata) }
|
|
706
|
+
: {}),
|
|
707
|
+
...(metadata === undefined ? {} : { metadata }),
|
|
708
|
+
};
|
|
709
|
+
const beforeRisk = yield* pipeline.advance({
|
|
710
|
+
phase: "before-risk",
|
|
711
|
+
input,
|
|
712
|
+
mfaSatisfied,
|
|
713
|
+
});
|
|
714
|
+
if (beforeRisk._tag === "PolicyDenied") {
|
|
715
|
+
return AuthResult.PolicyDenied({ reason: beforeRisk.reason });
|
|
716
|
+
}
|
|
486
717
|
const risk = yield* loginRiskEngine.assess({
|
|
487
718
|
userId: input.userId,
|
|
488
|
-
...(input.
|
|
489
|
-
|
|
719
|
+
...(input.identity === undefined ? {} : { identity: input.identity }),
|
|
720
|
+
...(input.emailDestination === undefined
|
|
721
|
+
? {}
|
|
722
|
+
: { emailDestination: input.emailDestination }),
|
|
490
723
|
method: input.method,
|
|
491
724
|
amr: input.amr,
|
|
492
725
|
aal: input.aal,
|
|
493
|
-
device,
|
|
726
|
+
device: input.device ?? unknownLoginDeviceContext,
|
|
727
|
+
...(input.deviceKey === undefined ? {} : { deviceKey: input.deviceKey }),
|
|
728
|
+
...(input.locationKey === undefined
|
|
729
|
+
? {}
|
|
730
|
+
: { locationKey: input.locationKey }),
|
|
494
731
|
...(input.request === undefined ? {} : { request: input.request }),
|
|
495
|
-
...(metadata === undefined ? {} : { metadata }),
|
|
732
|
+
...(input.metadata === undefined ? {} : { metadata: input.metadata }),
|
|
733
|
+
});
|
|
734
|
+
input = { ...input, risk };
|
|
735
|
+
const afterRisk = yield* pipeline.advance({
|
|
736
|
+
phase: "after-risk",
|
|
737
|
+
input,
|
|
738
|
+
mfaSatisfied,
|
|
739
|
+
});
|
|
740
|
+
if (afterRisk._tag === "PolicyDenied") {
|
|
741
|
+
return AuthResult.PolicyDenied({ reason: afterRisk.reason });
|
|
742
|
+
}
|
|
743
|
+
const beforeMfa = yield* pipeline.advance({
|
|
744
|
+
phase: "before-mfa",
|
|
745
|
+
input,
|
|
746
|
+
mfaSatisfied,
|
|
747
|
+
});
|
|
748
|
+
if (beforeMfa._tag === "PolicyDenied") {
|
|
749
|
+
return AuthResult.PolicyDenied({ reason: beforeMfa.reason });
|
|
750
|
+
}
|
|
751
|
+
if (!mfaSatisfied) {
|
|
752
|
+
const mfaResult = yield* requireMfaIfNeeded({
|
|
753
|
+
...input,
|
|
754
|
+
claims: input.claims,
|
|
755
|
+
device: input.device,
|
|
756
|
+
risk: input.risk,
|
|
757
|
+
metadata: input.metadata,
|
|
758
|
+
});
|
|
759
|
+
if (Option.isSome(mfaResult)) {
|
|
760
|
+
return mfaResult.value;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
const afterMfa = yield* pipeline.advance({
|
|
764
|
+
phase: "after-mfa",
|
|
765
|
+
input,
|
|
766
|
+
mfaSatisfied,
|
|
496
767
|
});
|
|
768
|
+
if (afterMfa._tag === "PolicyDenied") {
|
|
769
|
+
return AuthResult.PolicyDenied({ reason: afterMfa.reason });
|
|
770
|
+
}
|
|
771
|
+
const beforeLoginApproval = yield* pipeline.advance({
|
|
772
|
+
phase: "before-login-approval",
|
|
773
|
+
input,
|
|
774
|
+
mfaSatisfied,
|
|
775
|
+
});
|
|
776
|
+
if (beforeLoginApproval._tag === "PolicyDenied") {
|
|
777
|
+
return AuthResult.PolicyDenied({ reason: beforeLoginApproval.reason });
|
|
778
|
+
}
|
|
497
779
|
const loginApprovalDecision = yield* loginApprovalPolicy.decide({
|
|
498
780
|
...(input.intent === undefined ? {} : { intent: input.intent }),
|
|
499
781
|
userId: input.userId,
|
|
500
|
-
...(input.
|
|
501
|
-
|
|
782
|
+
...(input.identity === undefined ? {} : { identity: input.identity }),
|
|
783
|
+
...(input.emailDestination === undefined
|
|
784
|
+
? {}
|
|
785
|
+
: { emailDestination: input.emailDestination }),
|
|
502
786
|
method: input.method,
|
|
503
787
|
amr: input.amr,
|
|
504
788
|
aal: input.aal,
|
|
505
|
-
device,
|
|
506
|
-
risk,
|
|
507
|
-
...(metadata === undefined ? {} : { metadata }),
|
|
789
|
+
device: input.device ?? unknownLoginDeviceContext,
|
|
790
|
+
risk: input.risk ?? defaultLoginRiskContext,
|
|
791
|
+
...(input.metadata === undefined ? {} : { metadata: input.metadata }),
|
|
508
792
|
});
|
|
509
793
|
if (loginApprovalDecision._tag === "RequiresApproval") {
|
|
510
794
|
if (loginApprovalDecision.channel === "email" &&
|
|
511
|
-
input.
|
|
795
|
+
input.emailDestination === undefined) {
|
|
512
796
|
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
513
797
|
return loginApprovalEmailMissing();
|
|
514
798
|
}
|
|
799
|
+
if (loginApprovalDecision.markIdentityVerified === true &&
|
|
800
|
+
(loginApprovalDecision.channel !== "email" ||
|
|
801
|
+
loginApprovalDecision.sessionBinding === "none" ||
|
|
802
|
+
input.identity?.kind !== "email" ||
|
|
803
|
+
input.emailDestination === undefined ||
|
|
804
|
+
input.identity.identityId !== input.emailDestination.identityId)) {
|
|
805
|
+
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
806
|
+
return loginApprovalIdentityNotBound();
|
|
807
|
+
}
|
|
515
808
|
if (dependencies.authFlowState === undefined ||
|
|
516
809
|
dependencies.loginApprovalFlow === undefined) {
|
|
517
810
|
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
@@ -523,124 +816,179 @@ export const makeAuthFlow = (dependencies) => {
|
|
|
523
816
|
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
524
817
|
return loginApprovalReviewNotConfigured();
|
|
525
818
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
return loginApprovalSameDeviceNotConfigured();
|
|
531
|
-
}
|
|
532
|
-
sameDeviceSecret = Redacted.make(yield* dependencies.crypto
|
|
533
|
-
.randomToken(loginApprovalSameDeviceSecretBytes)
|
|
534
|
-
.pipe(Effect.mapError((cause) => new AuthFlowStateError({
|
|
535
|
-
message: "Failed to create login approval same-device binding",
|
|
536
|
-
cause,
|
|
537
|
-
}))));
|
|
819
|
+
if (loginApprovalDecision.sameDeviceRequired &&
|
|
820
|
+
dependencies.crypto === undefined) {
|
|
821
|
+
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
822
|
+
return loginApprovalSameDeviceNotConfigured();
|
|
538
823
|
}
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
claims
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
824
|
+
const approvalInput = input;
|
|
825
|
+
const completeLoginApproval = Effect.gen(function* () {
|
|
826
|
+
let sameDeviceSecret;
|
|
827
|
+
if (loginApprovalDecision.sameDeviceRequired) {
|
|
828
|
+
sameDeviceSecret = Redacted.make(yield* dependencies
|
|
829
|
+
.crypto.randomToken(loginApprovalSameDeviceSecretBytes)
|
|
830
|
+
.pipe(Effect.mapError((cause) => new AuthFlowStateError({
|
|
831
|
+
message: "Failed to create login approval same-device binding",
|
|
832
|
+
cause,
|
|
833
|
+
}))));
|
|
834
|
+
}
|
|
835
|
+
const claims = loginApprovalDecision.markIdentityVerified === true
|
|
836
|
+
? withVerifiedIdentityKind(approvalInput.claims, "email")
|
|
837
|
+
: approvalInput.claims;
|
|
838
|
+
const flowState = yield* dependencies.authFlowState.start({
|
|
839
|
+
userId: approvalInput.userId,
|
|
840
|
+
method: approvalInput.method,
|
|
841
|
+
evidence: approvalInput.evidence,
|
|
842
|
+
...(approvalInput.identity === undefined
|
|
843
|
+
? {}
|
|
844
|
+
: { identity: approvalInput.identity }),
|
|
845
|
+
...(approvalInput.emailDestination === undefined
|
|
846
|
+
? {}
|
|
847
|
+
: { emailDestination: approvalInput.emailDestination }),
|
|
848
|
+
...(approvalInput.intent === undefined
|
|
849
|
+
? {}
|
|
850
|
+
: { intent: approvalInput.intent }),
|
|
851
|
+
device: approvalInput.device,
|
|
852
|
+
...(approvalInput.deviceKey === undefined
|
|
853
|
+
? {}
|
|
854
|
+
: { deviceKey: approvalInput.deviceKey }),
|
|
855
|
+
...(approvalInput.locationKey === undefined
|
|
856
|
+
? {}
|
|
857
|
+
: { locationKey: approvalInput.locationKey }),
|
|
858
|
+
...(approvalInput.request === undefined
|
|
859
|
+
? {}
|
|
860
|
+
: { request: approvalInput.request }),
|
|
861
|
+
claims,
|
|
862
|
+
secret: sameDeviceSecret,
|
|
863
|
+
...(approvalInput.metadata === undefined
|
|
864
|
+
? {}
|
|
865
|
+
: { metadata: approvalInput.metadata }),
|
|
866
|
+
});
|
|
867
|
+
const approval = yield* dependencies.loginApprovalFlow.start({
|
|
868
|
+
userId: approvalInput.userId,
|
|
869
|
+
...(approvalInput.emailDestination === undefined
|
|
870
|
+
? {}
|
|
871
|
+
: { emailDestination: approvalInput.emailDestination }),
|
|
872
|
+
channel: loginApprovalDecision.channel,
|
|
873
|
+
reason: loginApprovalDecision.reason,
|
|
874
|
+
sessionBinding: loginApprovalDecision.sessionBinding,
|
|
875
|
+
sameDeviceRequired: loginApprovalDecision.sameDeviceRequired,
|
|
876
|
+
...(loginApprovalDecision.markIdentityVerified === true
|
|
877
|
+
? { markIdentityVerified: true }
|
|
878
|
+
: {}),
|
|
879
|
+
risk: approvalInput.risk ?? defaultLoginRiskContext,
|
|
880
|
+
metadata: loginApprovalFlowIdMetadata(flowState.flowId, approvalInput.metadata),
|
|
881
|
+
});
|
|
882
|
+
if (approval.sessionBinding === "none" &&
|
|
883
|
+
loginApprovalReview !== undefined) {
|
|
884
|
+
yield* loginApprovalReview.start({
|
|
885
|
+
approval,
|
|
886
|
+
flowId: flowState.flowId,
|
|
887
|
+
metadata: approvalInput.metadata,
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
yield* Effect.annotateCurrentSpan({
|
|
891
|
+
"auth.result": "RequiresLoginApproval",
|
|
892
|
+
"auth.login_approval.reason": approval.reason,
|
|
893
|
+
"auth.login_approval.session_binding": approval.sessionBinding,
|
|
894
|
+
"auth.login_approval.same_device_required": approval.sameDeviceRequired,
|
|
895
|
+
});
|
|
896
|
+
return AuthResult.RequiresLoginApproval({
|
|
571
897
|
flowId: flowState.flowId,
|
|
572
|
-
|
|
898
|
+
approvalChallengeId: approval.challengeId,
|
|
899
|
+
channel: approval.channel,
|
|
900
|
+
sessionBinding: approval.sessionBinding,
|
|
901
|
+
sameDeviceRequired: approval.sameDeviceRequired,
|
|
902
|
+
reason: approval.reason,
|
|
903
|
+
expiresAt: flowState.expiresAt,
|
|
904
|
+
...(sameDeviceSecret === undefined ? {} : { sameDeviceSecret }),
|
|
573
905
|
});
|
|
574
|
-
}
|
|
575
|
-
yield* Effect.annotateCurrentSpan({
|
|
576
|
-
"auth.result": "RequiresLoginApproval",
|
|
577
|
-
"auth.login_approval.reason": approval.reason,
|
|
578
|
-
"auth.login_approval.session_binding": approval.sessionBinding,
|
|
579
|
-
"auth.login_approval.same_device_required": approval.sameDeviceRequired,
|
|
580
|
-
});
|
|
581
|
-
return AuthResult.RequiresLoginApproval({
|
|
582
|
-
flowId: flowState.flowId,
|
|
583
|
-
approvalChallengeId: approval.challengeId,
|
|
584
|
-
channel: approval.channel,
|
|
585
|
-
sessionBinding: approval.sessionBinding,
|
|
586
|
-
sameDeviceRequired: approval.sameDeviceRequired,
|
|
587
|
-
reason: approval.reason,
|
|
588
|
-
expiresAt: flowState.expiresAt,
|
|
589
|
-
...(sameDeviceSecret === undefined ? {} : { sameDeviceSecret }),
|
|
590
906
|
});
|
|
907
|
+
return yield* handleLoginApproval(completeLoginApproval);
|
|
591
908
|
}
|
|
592
|
-
return yield*
|
|
593
|
-
userId: input.userId,
|
|
594
|
-
...(input.email === undefined ? {} : { email: input.email }),
|
|
595
|
-
...(input.intent === undefined ? {} : { intent: input.intent }),
|
|
596
|
-
method: input.method,
|
|
597
|
-
amr: input.amr,
|
|
598
|
-
aal: input.aal,
|
|
599
|
-
device,
|
|
600
|
-
...(input.request === undefined ? {} : { request: input.request }),
|
|
601
|
-
risk,
|
|
602
|
-
claims: emailVerificationDecision.claims,
|
|
603
|
-
metadata,
|
|
604
|
-
});
|
|
909
|
+
return yield* terminal(input);
|
|
605
910
|
});
|
|
911
|
+
const completePrimaryFactor = Effect.fn("auth.auth_flow.complete_primary_factor")((input) => advance(input, false, flowTerminal.complete, (complete) => complete));
|
|
606
912
|
const completeMfa = Effect.fn("auth.auth_flow.complete_mfa")(function* (input) {
|
|
607
913
|
if (dependencies.authFlowState === undefined) {
|
|
608
914
|
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
609
915
|
return mfaFlowStateNotConfigured();
|
|
610
916
|
}
|
|
611
|
-
const
|
|
612
|
-
if (input.userId !== undefined &&
|
|
917
|
+
const pending = yield* dependencies.authFlowState.inspect(input.flowId, input.secret);
|
|
918
|
+
if (input.userId !== undefined && pending.userId !== input.userId) {
|
|
613
919
|
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
614
920
|
return mfaFlowUserMismatch();
|
|
615
921
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
yield*
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
"auth.
|
|
624
|
-
|
|
625
|
-
}
|
|
626
|
-
|
|
922
|
+
if (!authFlowStateAllowsMfa(pending, input)) {
|
|
923
|
+
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
924
|
+
return mfaFlowFactorNotAllowed();
|
|
925
|
+
}
|
|
926
|
+
const consumed = yield* dependencies.authFlowState.consume(input.flowId, input.secret);
|
|
927
|
+
if (consumed.userId !== pending.userId ||
|
|
928
|
+
!authFlowStateAllowsMfa(consumed, input)) {
|
|
929
|
+
yield* Effect.annotateCurrentSpan("auth.result", "PolicyDenied");
|
|
930
|
+
return mfaFlowFactorNotAllowed();
|
|
931
|
+
}
|
|
932
|
+
const evidence = [...consumed.evidence, input.evidence];
|
|
933
|
+
const metadata = mergeMetadata(consumed.metadata, applicationFlowStateMetadata(input.metadata));
|
|
934
|
+
const result = yield* advance({
|
|
627
935
|
userId: consumed.userId,
|
|
628
|
-
...(consumed.
|
|
936
|
+
...(consumed.identity === undefined
|
|
937
|
+
? {}
|
|
938
|
+
: { identity: consumed.identity }),
|
|
939
|
+
...(consumed.emailDestination === undefined
|
|
940
|
+
? {}
|
|
941
|
+
: { emailDestination: consumed.emailDestination }),
|
|
629
942
|
...(consumed.intent === undefined ? {} : { intent: consumed.intent }),
|
|
630
943
|
method: consumed.method,
|
|
631
|
-
|
|
632
|
-
aal,
|
|
944
|
+
evidence,
|
|
633
945
|
...(consumed.device === undefined ? {} : { device: consumed.device }),
|
|
946
|
+
...(consumed.deviceKey === undefined
|
|
947
|
+
? {}
|
|
948
|
+
: { deviceKey: consumed.deviceKey }),
|
|
949
|
+
...(consumed.locationKey === undefined
|
|
950
|
+
? {}
|
|
951
|
+
: { locationKey: consumed.locationKey }),
|
|
952
|
+
...(consumed.request === undefined
|
|
953
|
+
? {}
|
|
954
|
+
: { request: consumed.request }),
|
|
634
955
|
claims: consumed.claims,
|
|
635
|
-
mfaVerifiedAt,
|
|
636
956
|
metadata,
|
|
637
|
-
});
|
|
957
|
+
}, true, flowTerminal.complete, (complete) => complete, input.method);
|
|
958
|
+
return result._tag === "RequiresMfa"
|
|
959
|
+
? AuthResult.PolicyDenied({ reason: "MFA is already satisfied" })
|
|
960
|
+
: result;
|
|
638
961
|
});
|
|
639
|
-
|
|
962
|
+
const prepareMfa = Effect.fn("auth.auth_flow.prepare_mfa")(function* (input) {
|
|
963
|
+
if (dependencies.authFlowState === undefined) {
|
|
964
|
+
return mfaFlowStateNotConfigured();
|
|
965
|
+
}
|
|
966
|
+
const inspected = yield* dependencies.authFlowState.inspect(input.flowId, input.secret);
|
|
967
|
+
if (input.userId !== undefined && inspected.userId !== input.userId) {
|
|
968
|
+
return mfaFlowUserMismatch();
|
|
969
|
+
}
|
|
970
|
+
if (!authFlowStateAllowsMfa(inspected, input)) {
|
|
971
|
+
return mfaFlowFactorNotAllowed();
|
|
972
|
+
}
|
|
973
|
+
const evidence = [...inspected.evidence, input.evidence];
|
|
974
|
+
const result = yield* advance({
|
|
975
|
+
...inspected,
|
|
976
|
+
evidence,
|
|
977
|
+
metadata: mergeMetadata(inspected.metadata, applicationFlowStateMetadata(input.metadata)),
|
|
978
|
+
}, true, flowTerminal.prepare, (complete) => Effect.succeed({
|
|
979
|
+
_tag: "PreparedLoginApproval",
|
|
980
|
+
complete,
|
|
981
|
+
}), input.method);
|
|
982
|
+
return result._tag === "RequiresMfa"
|
|
983
|
+
? AuthResult.PolicyDenied({ reason: "MFA is already satisfied" })
|
|
984
|
+
: result;
|
|
985
|
+
});
|
|
986
|
+
return AuthFlow.of({
|
|
640
987
|
startPrimaryFactor: completePrimaryFactor,
|
|
988
|
+
requireMfa,
|
|
641
989
|
completePrimaryFactor,
|
|
642
990
|
completeMfa,
|
|
643
|
-
|
|
991
|
+
prepareMfa,
|
|
644
992
|
});
|
|
645
993
|
};
|
|
646
994
|
export const AuthFlowLive = Layer.effect(AuthFlow)(Effect.gen(function* () {
|
|
@@ -653,13 +1001,13 @@ export const AuthFlowLive = Layer.effect(AuthFlow)(Effect.gen(function* () {
|
|
|
653
1001
|
...loginApprovalDependencies,
|
|
654
1002
|
});
|
|
655
1003
|
}));
|
|
656
|
-
export const
|
|
1004
|
+
export const AuthFlowWithEmailVerificationPolicyLive = (options) => Layer.effect(AuthFlow)(Effect.gen(function* () {
|
|
657
1005
|
const sessions = yield* Sessions;
|
|
658
1006
|
const loginApprovalDependencies = yield* optionalLoginApprovalDependencies;
|
|
659
1007
|
return makeAuthFlow({
|
|
660
1008
|
sessions,
|
|
661
|
-
emailVerificationSessionPolicy: makeEmailVerificationSessionPolicy(options),
|
|
662
1009
|
...loginApprovalDependencies,
|
|
1010
|
+
emailVerificationSessionPolicy: makeEmailVerificationSessionPolicy(options),
|
|
663
1011
|
});
|
|
664
1012
|
}));
|
|
665
1013
|
//# sourceMappingURL=AuthFlow.js.map
|