@effect-auth/core 0.1.0-alpha.16 → 0.1.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +307 -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/DevEmail.d.ts +44 -0
- package/dist/DevEmail.d.ts.map +1 -0
- package/dist/DevEmail.js +115 -0
- package/dist/DevEmail.js.map +1 -0
- package/dist/DevelopmentSeed.d.ts +47 -0
- package/dist/DevelopmentSeed.d.ts.map +1 -0
- package/dist/DevelopmentSeed.js +337 -0
- package/dist/DevelopmentSeed.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/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/DrizzlePostgresStorage.d.ts +26 -0
- package/dist/DrizzlePostgresStorage.d.ts.map +1 -0
- package/dist/DrizzlePostgresStorage.js +14 -0
- package/dist/DrizzlePostgresStorage.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 +178 -0
- package/dist/EffectQbPostgresStorage.d.ts.map +1 -0
- package/dist/EffectQbPostgresStorage.js +4637 -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 +221 -23
- package/dist/EffectQbSqliteStorage.d.ts.map +1 -1
- package/dist/EffectQbSqliteStorage.js +2064 -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 +939 -884
- package/dist/HttpApi/Api.d.ts.map +1 -1
- package/dist/HttpApi/Api.js +2254 -940
- 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 +661 -301
- package/dist/HttpApi/Endpoints.d.ts.map +1 -1
- package/dist/HttpApi/Endpoints.js +207 -120
- package/dist/HttpApi/Endpoints.js.map +1 -1
- package/dist/HttpApi/Errors.d.ts +37 -10
- package/dist/HttpApi/Errors.d.ts.map +1 -1
- package/dist/HttpApi/Errors.js +42 -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 +26 -0
- package/dist/HttpApi/Middleware.d.ts.map +1 -0
- package/dist/HttpApi/Middleware.js +13 -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/OAuthDeviceAuthorization.d.ts +106 -0
- package/dist/HttpApi/OAuthDeviceAuthorization.d.ts.map +1 -0
- package/dist/HttpApi/OAuthDeviceAuthorization.js +415 -0
- package/dist/HttpApi/OAuthDeviceAuthorization.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/OAuthDeviceAuthorization.d.ts +23 -0
- package/dist/HttpApi/Operations/OAuthDeviceAuthorization.d.ts.map +1 -0
- package/dist/HttpApi/Operations/OAuthDeviceAuthorization.js +7 -0
- package/dist/HttpApi/Operations/OAuthDeviceAuthorization.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 +26 -0
- package/dist/HttpApi/Operations/OAuthToken.d.ts.map +1 -0
- package/dist/HttpApi/Operations/OAuthToken.js +9 -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 +28 -0
- package/dist/HttpApi/Operations/index.d.ts.map +1 -0
- package/dist/HttpApi/Operations/index.js +28 -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 +399 -84
- package/dist/HttpApi/Schemas.d.ts.map +1 -1
- package/dist/HttpApi/Schemas.js +225 -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 +11 -3
- package/dist/HttpApi/index.d.ts.map +1 -1
- package/dist/HttpApi/index.js +10 -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 +138 -96
- package/dist/OAuth.d.ts.map +1 -1
- package/dist/OAuth.js +522 -221
- package/dist/OAuth.js.map +1 -1
- package/dist/OAuthDeviceAuthorization.d.ts +378 -0
- package/dist/OAuthDeviceAuthorization.d.ts.map +1 -0
- package/dist/OAuthDeviceAuthorization.js +860 -0
- package/dist/OAuthDeviceAuthorization.js.map +1 -0
- package/dist/OAuthDeviceClient.d.ts +76 -0
- package/dist/OAuthDeviceClient.d.ts.map +1 -0
- package/dist/OAuthDeviceClient.js +362 -0
- package/dist/OAuthDeviceClient.js.map +1 -0
- 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 +16 -0
- package/dist/PostgresStorageMigrations.d.ts.map +1 -0
- package/dist/PostgresStorageMigrations.js +674 -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/Retention.d.ts +6 -1
- package/dist/Retention.d.ts.map +1 -1
- package/dist/Retention.js +49 -12
- package/dist/Retention.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/SqliteStorageSchemaData.d.ts +2 -0
- package/dist/SqliteStorageSchemaData.d.ts.map +1 -0
- package/dist/SqliteStorageSchemaData.js +508 -0
- package/dist/SqliteStorageSchemaData.js.map +1 -0
- 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 +7 -1
- package/dist/StorageMigrations.d.ts.map +1 -1
- package/dist/StorageMigrations.js +256 -0
- package/dist/StorageMigrations.js.map +1 -1
- package/dist/StorageSchemaGenerator.d.ts +544 -0
- package/dist/StorageSchemaGenerator.d.ts.map +1 -0
- package/dist/StorageSchemaGenerator.js +1418 -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/0029_auth_oauth_device_authorization.sql +28 -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/0010_auth_oauth_device_authorization.sql +50 -0
- package/migrations/postgres/delegated-access/0001_auth_delegated_access.sql +112 -0
- package/package.json +309 -2
package/README.md
CHANGED
|
@@ -6,44 +6,71 @@ The current alpha surface is primitive-first: service contracts, small helpers,
|
|
|
6
6
|
|
|
7
7
|
## Public API Surface
|
|
8
8
|
|
|
9
|
-
The root
|
|
9
|
+
The root entry is metadata-only:
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
|
-
import {
|
|
12
|
+
import { packageName } from "@effect-auth/core";
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Import every auth primitive, service, layer, identifier, and integration from its named public subpath:
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
```ts
|
|
18
|
+
import { UserId } from "@effect-auth/core/Identifiers";
|
|
19
|
+
import { PasswordLogin } from "@effect-auth/core/Password";
|
|
20
|
+
import { Sessions } from "@effect-auth/core/Sessions";
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Runtime-neutral primitive subpaths are stable alpha API. Examples include `@effect-auth/core/Password`, `@effect-auth/core/Sessions`, `@effect-auth/core/OAuth`, `@effect-auth/core/Jwt`, `@effect-auth/core/ApiKey`, `@effect-auth/core/Storage`, and `@effect-auth/core/RateLimiter`.
|
|
24
|
+
|
|
25
|
+
Utility subpaths are stable alpha APIs:
|
|
26
|
+
|
|
27
|
+
```txt
|
|
28
|
+
@effect-auth/core/StorageMigrations
|
|
29
|
+
```
|
|
18
30
|
|
|
19
31
|
Integration subpaths are public but opt-in. They may expose runtime-specific or transport-specific types and require the app to install their adapter packages when used:
|
|
20
32
|
|
|
21
33
|
```txt
|
|
22
34
|
@effect-auth/core/Client
|
|
23
35
|
@effect-auth/core/HttpApi
|
|
24
|
-
@effect-auth/core/
|
|
25
|
-
@effect-auth/core/RateLimiter
|
|
36
|
+
@effect-auth/core/PasskeyBrowser
|
|
26
37
|
```
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
Storage and runtime adapter subpaths are public alpha adapters. Their names may still be normalized before beta:
|
|
29
40
|
|
|
30
41
|
```txt
|
|
42
|
+
@effect-auth/core/EffectQbSqliteStorage
|
|
43
|
+
@effect-auth/core/DrizzleEffectSqliteStorage
|
|
44
|
+
@effect-auth/core/DrizzleD1SqliteStorage
|
|
45
|
+
@effect-auth/core/DrizzleBunSqliteStorage
|
|
46
|
+
@effect-auth/core/DrizzleNodeSqliteStorage
|
|
31
47
|
@effect-auth/core/CloudflareEmail
|
|
48
|
+
@effect-auth/core/CloudflareRequestMetadata
|
|
32
49
|
@effect-auth/core/CloudflareRateLimitDurableObject
|
|
33
50
|
@effect-auth/core/AlchemyCloudflareEmail
|
|
34
51
|
@effect-auth/core/AlchemyCloudflareRateLimitDurableObject
|
|
35
52
|
@effect-auth/core/PasskeySimpleWebAuthn
|
|
53
|
+
@effect-auth/core/StorageSchemaGenerator
|
|
54
|
+
@effect-auth/core/DevelopmentSeed
|
|
36
55
|
```
|
|
37
56
|
|
|
38
57
|
`@effect-auth/core/Testing` is test/dev-only API. Do not wire it into production applications.
|
|
39
58
|
|
|
40
|
-
SQL migrations are packaged as files for copy/read workflows, but the supported TypeScript
|
|
59
|
+
SQL migrations are packaged as files for copy/read workflows, but the supported TypeScript APIs are `authStorageMigrations` from `@effect-auth/core/StorageMigrations` and `postgresAuthStorageMigrations` from `@effect-auth/core/PostgresStorageMigrations`. Raw SQL files are not importable package subpaths.
|
|
60
|
+
|
|
61
|
+
For fresh PostgreSQL or SQLite/D1 schema planning, `@effect-auth/core/StorageSchemaGenerator` exposes the same deterministic feature resolver used by the public API at `https://effect-auth.itsbroly.com/api/generator/v1`. Tools and AI agents should call `/catalog`, choose the database and adapter, then request `migration-sql`, `development-seed`, and, for Drizzle, `drizzle-schema`; they should not infer physical tables from store service types. `@effect-auth/core/DevelopmentSeed` provides the fixed 100-user, development-only runtime program used by generated seed launchers. Maintained runtime bridges are available for Drizzle PostgreSQL, D1, Bun SQLite, Node SQLite, and application-provided Effect SQLite databases.
|
|
62
|
+
|
|
63
|
+
Before beta, breaking changes are still allowed when they simplify this API surface. Keep the root metadata-only and add public APIs through explicit subpaths.
|
|
64
|
+
|
|
65
|
+
### Cloudflare Request Metadata
|
|
66
|
+
|
|
67
|
+
`@effect-auth/core/CloudflareRequestMetadata` is an opt-in Worker-boundary adapter for login-risk composition. It uses structural request types and reads geographic facts from Cloudflare's `request.cf`. Client IP is omitted unless `trustCloudflareConnectingIp` is explicitly enabled at a verified Cloudflare boundary. It does not require `@cloudflare/workers-types`, `nodejs_compat`, or an IP database.
|
|
41
68
|
|
|
42
|
-
|
|
69
|
+
Call `readCloudflareRequestMetadata(request)` in Worker-owned code, then pass its coarse `request`, `locationKey`, and safe `metadata` fields into custom risk composition. Missing or malformed preview metadata produces unknown fields rather than an error. Never construct the input from browser JSON or forwarded geographic headers. Persist only the returned `durable` projection; the full result may contain transient IP and city values.
|
|
43
70
|
|
|
44
71
|
## HTTP Client
|
|
45
72
|
|
|
46
|
-
`@effect-auth/core/Client` exposes
|
|
73
|
+
`@effect-auth/core/Client` exposes one browser-friendly client for the standard user-facing auth groups. Applications still choose which groups to mount and which policies to apply on the server. The client accepts plain JSON input types, includes cookies by default, and decodes successful/error responses through Effect Schema.
|
|
47
74
|
|
|
48
75
|
```ts
|
|
49
76
|
import { createAuthClient } from "@effect-auth/core/Client";
|
|
@@ -56,13 +83,100 @@ const result = await authClient.password.signIn({
|
|
|
56
83
|
});
|
|
57
84
|
|
|
58
85
|
const session = await authClient.session.currentOrUndefined();
|
|
86
|
+
|
|
87
|
+
if (authClient.passkey.isSupported()) {
|
|
88
|
+
await authClient.passkey.signIn();
|
|
89
|
+
}
|
|
59
90
|
```
|
|
60
91
|
|
|
92
|
+
`createAuthClient()` also includes combined email auth, passkeys, TOTP, recovery codes, login MFA, and step-up. Its passkey methods complete the standard start/browser/finish sequence. The focused `createPasskeyClient`, `createTotpClient`, `createMfaClient`, and other factories remain available for custom paths and low-level protocol control.
|
|
93
|
+
|
|
94
|
+
Authentication continuations such as `requires_mfa`, `requires_email_verification`, and `requires_login_approval` are successful protocol results, not exceptions. Handle the returned discriminated union in the UI.
|
|
95
|
+
|
|
61
96
|
Use `@effect-auth/core/HttpApi` when you are wiring the server or need the raw `HttpApi` contract. Use `@effect-auth/core/Client` in application UI code.
|
|
62
97
|
|
|
98
|
+
### HTTP Operations
|
|
99
|
+
|
|
100
|
+
Applications that own their routes can use the per-feature operation services instead of mounting the built-in API groups. Every built-in HTTP API group has a corresponding portable, typed operations service and `Live` layer. Each layer acquires its feature dependencies once and exposes ready endpoint operations with the same responses, cookies, errors, optional-service behavior, extension hooks, configuration, and security checks as the built-in handlers.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { Effect } from "effect";
|
|
104
|
+
import {
|
|
105
|
+
PasswordHttpOperations,
|
|
106
|
+
PasswordHttpOperationsLive,
|
|
107
|
+
type PasswordHttpOperationsService,
|
|
108
|
+
} from "@effect-auth/core/HttpApi/Password";
|
|
109
|
+
|
|
110
|
+
const signIn = (
|
|
111
|
+
input: Parameters<PasswordHttpOperationsService["signIn"]>[0]
|
|
112
|
+
) => PasswordHttpOperations.use((operations) => operations.signIn(input));
|
|
113
|
+
|
|
114
|
+
// Provide PasswordLogin, PasswordRegistration, PasswordReset,
|
|
115
|
+
// PasswordManagement, Sessions, SessionCookie, AuthHttp,
|
|
116
|
+
// EmailVerificationFlow, and an explicit AuthRateLimit layer.
|
|
117
|
+
const PasswordRoutesLive = PasswordHttpOperationsLive;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`@effect-auth/core/HttpApi/Password` also exports the standalone `PasswordHttpApiLive` preset and the password endpoint contracts without loading the full server API assembly. The broad `@effect-auth/core/HttpApi` entry remains the aggregate boundary for `CoreAuthHttpApiLive` and cross-feature composition.
|
|
121
|
+
|
|
122
|
+
Feature operation services can also be replaced directly in tests with `FeatureHttpOperations.of(...)`. Secured feature layers always require `AuthRateLimit`; they never install a no-op implementation.
|
|
123
|
+
|
|
124
|
+
### Client Composition
|
|
125
|
+
|
|
126
|
+
The standard client is a starting point rather than an all-or-nothing abstraction. Its `protocol` option is a deep patch:
|
|
127
|
+
|
|
128
|
+
- omitted properties keep the standard implementation,
|
|
129
|
+
- functions and objects replace or extend it,
|
|
130
|
+
- `null` removes an operation or group,
|
|
131
|
+
- `extensions` adds app-owned auth operations under a collision-free namespace.
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const auth = createAuthClient({
|
|
135
|
+
protocol: {
|
|
136
|
+
passkey: null,
|
|
137
|
+
password: {
|
|
138
|
+
signUp: customSignUp,
|
|
139
|
+
},
|
|
140
|
+
extensions: {
|
|
141
|
+
organization: {
|
|
142
|
+
select: selectActiveOrganization,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
await auth.password.signUp(customInput);
|
|
149
|
+
await auth.extensions.organization.select({ organizationId: "org-1" });
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Literal `null` values also remove the corresponding property from the inferred client type.
|
|
153
|
+
|
|
154
|
+
Use `defineAuthHttpApiExtension` for an app-owned auth `HttpApi` contract that should share the standard client's base URL, Fetch configuration, cookies, cancellation, runtime, and disposal:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
const appAuthExtension = defineAuthHttpApiExtension(
|
|
158
|
+
AppAuthExtensionApi,
|
|
159
|
+
({ run }) => ({
|
|
160
|
+
discoverSso: (email: string, options?: AuthClientRequestOptions) =>
|
|
161
|
+
run(
|
|
162
|
+
(client) => client.appAuth.discoverSso({ payload: { email } }),
|
|
163
|
+
options
|
|
164
|
+
),
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const auth = createAuthClient({
|
|
169
|
+
protocol: { extensions: appAuthExtension },
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
await auth.extensions.discoverSso("reader@example.com");
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Extension contracts should contain browser-safe endpoint/schema declarations, use unique group identifiers, and require no client-side middleware services. Product APIs that merely require an auth cookie should remain separate from the auth client.
|
|
176
|
+
|
|
63
177
|
## Policy
|
|
64
178
|
|
|
65
|
-
`Policy` is an `Effect` used for authorization. Success means access is allowed. `
|
|
179
|
+
`Policy` is an `Effect` used for authorization. Success means access is allowed. `AuthorizationError` means access is denied. Other failures stay operational errors.
|
|
66
180
|
|
|
67
181
|
```ts
|
|
68
182
|
import { Effect } from "effect";
|
|
@@ -80,6 +194,29 @@ const detailed = Policy.checkDetailed(canEditProject);
|
|
|
80
194
|
|
|
81
195
|
Use `Policy.check` when callers should branch on allowed/denied and let operational errors fail. Use `Policy.checkDetailed` when callers need a value for allowed, denied, or failed.
|
|
82
196
|
|
|
197
|
+
Permission policies read a trusted `CurrentPrincipal`, not session-specific
|
|
198
|
+
`CurrentActor`. `Permissions` checks are subject-first, so the same policy seam
|
|
199
|
+
can authorize a user, service account, API key, or another app-defined subject:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import { Effect } from "effect";
|
|
203
|
+
import {
|
|
204
|
+
CurrentPrincipal,
|
|
205
|
+
PermissionSubject,
|
|
206
|
+
} from "@effect-auth/core/Permission";
|
|
207
|
+
|
|
208
|
+
const principal = PermissionSubject.user(validated.actor.userId);
|
|
209
|
+
|
|
210
|
+
const authorized = operation.pipe(
|
|
211
|
+
Effect.provideService(CurrentPrincipal, CurrentPrincipal.of(principal))
|
|
212
|
+
);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`CurrentActor` remains the authenticated session context containing `userId`
|
|
216
|
+
and `sessionId`. Credential adapters must choose the authorization principal
|
|
217
|
+
explicitly at a trusted boundary; never accept it from request input. Machine
|
|
218
|
+
credential scopes and durable permissions are cumulative restrictions.
|
|
219
|
+
|
|
83
220
|
Policies compose with `all`, `any`, and `not`:
|
|
84
221
|
|
|
85
222
|
```ts
|
|
@@ -162,12 +299,13 @@ const AuthPrivacyLive = PrivacyLive({
|
|
|
162
299
|
});
|
|
163
300
|
```
|
|
164
301
|
|
|
165
|
-
The built-in HTTP auth API
|
|
302
|
+
The built-in HTTP auth API consumes standard limits through `AuthRateLimitStandardLive(config)`. Production deployments provide a durable `RateLimiter` store and HMAC `Privacy` secret. In `config`, an undefined operation uses its standard rules, a rule array replaces them, and `null` disables that operation. `AuthServicesLive` below stands for your app-owned auth service wiring.
|
|
166
303
|
|
|
167
304
|
```ts
|
|
168
|
-
import { Layer, Redacted } from "effect";
|
|
305
|
+
import { Duration, Layer, Redacted } from "effect";
|
|
169
306
|
import { RateLimiter as PersistenceRateLimiter } from "effect/unstable/persistence";
|
|
170
|
-
import {
|
|
307
|
+
import { AuthRateLimitStandardLive } from "@effect-auth/core/AuthRateLimit";
|
|
308
|
+
import { CoreAuthHttpApiLive } from "@effect-auth/core/HttpApi";
|
|
171
309
|
import {
|
|
172
310
|
RateLimitStoreDurableObject,
|
|
173
311
|
type CloudflareRateLimitDurableObjectNamespace,
|
|
@@ -184,29 +322,43 @@ export const makeAuthHttpApiLayer = (
|
|
|
184
322
|
Layer.provide(RateLimitStoreDurableObject.layer({ namespace }))
|
|
185
323
|
);
|
|
186
324
|
|
|
187
|
-
return
|
|
325
|
+
return CoreAuthHttpApiLive.pipe(
|
|
188
326
|
Layer.provide(AuthServicesLive),
|
|
327
|
+
Layer.provide(
|
|
328
|
+
AuthRateLimitStandardLive({
|
|
329
|
+
// Keep standard sign-in rules, replace sign-up, disable reset-start.
|
|
330
|
+
"auth.password.sign_up": [
|
|
331
|
+
{
|
|
332
|
+
id: "app.password.sign_up.ip",
|
|
333
|
+
key: "ip",
|
|
334
|
+
limit: 5,
|
|
335
|
+
window: Duration.hours(1),
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
"auth.password.reset_start": null,
|
|
339
|
+
})
|
|
340
|
+
),
|
|
189
341
|
Layer.provide(DurableObjectRateLimiterLive),
|
|
190
342
|
Layer.provide(PrivacyLive({ secret: Redacted.make(privacySecret) }))
|
|
191
343
|
);
|
|
192
344
|
};
|
|
193
345
|
```
|
|
194
346
|
|
|
195
|
-
`
|
|
196
|
-
|
|
197
|
-
Advanced apps can replace the `AuthApiRateLimit` service directly. `AuthApiRateLimitMiddlewareLive` delegates request-level checks to that service, so custom policies can still use the built-in endpoint middleware and handler hooks.
|
|
198
|
-
|
|
199
|
-
Use `AuthHttpApiBareLive` only when you explicitly do not want built-in auth rate limits:
|
|
347
|
+
`AuthRateLimitStandardLive()` applies all standard rules. The explicit escape hatch is `AuthRateLimitNoopLive`; use it only when another boundary enforces equivalent controls or while deliberately running without them:
|
|
200
348
|
|
|
201
349
|
```ts
|
|
202
350
|
import { Layer } from "effect";
|
|
203
|
-
import {
|
|
351
|
+
import { AuthRateLimitNoopLive } from "@effect-auth/core/AuthRateLimit";
|
|
352
|
+
import { CoreAuthHttpApiLive } from "@effect-auth/core/HttpApi";
|
|
204
353
|
|
|
205
|
-
export const AuthHttpApiLayer =
|
|
206
|
-
Layer.provide(AuthServicesLive)
|
|
354
|
+
export const AuthHttpApiLayer = CoreAuthHttpApiLive.pipe(
|
|
355
|
+
Layer.provide(AuthServicesLive),
|
|
356
|
+
Layer.provide(AuthRateLimitNoopLive)
|
|
207
357
|
);
|
|
208
358
|
```
|
|
209
359
|
|
|
360
|
+
App-owned workflows can use `RateLimiter.require`, `StepUp`/`Policy` requirements, and `Guard.requireAll` directly. At an HTTP boundary, pipe the composed effect through `mapAuthGuardErrors` so rate-limit, step-up, policy, privacy, and permission failures become the declared auth HTTP errors while unrelated application errors remain unchanged.
|
|
361
|
+
|
|
210
362
|
## AuthFlow
|
|
211
363
|
|
|
212
364
|
Login methods should verify a factor, then hand the result to `AuthFlow`. `AuthFlow` returns a flat `AuthResult` tagged enum: authenticated, step-up/verification requirements, or successful auth outcomes such as invalid credentials.
|
|
@@ -240,7 +392,7 @@ declare const issuedSession: IssuedSession;
|
|
|
240
392
|
|
|
241
393
|
const AuthFlowLive = Layer.succeed(
|
|
242
394
|
AuthFlow,
|
|
243
|
-
AuthFlow.
|
|
395
|
+
AuthFlow.of({
|
|
244
396
|
startPrimaryFactor: () =>
|
|
245
397
|
Effect.succeed(AuthResult.PolicyDenied({ reason: "test" })),
|
|
246
398
|
completePrimaryFactor: () =>
|
|
@@ -255,6 +407,31 @@ const AuthFlowLive = Layer.succeed(
|
|
|
255
407
|
|
|
256
408
|
The same pattern is available on core services such as `AuditLog.make`, `Sessions.make`, `SessionCookie.make`, `Challenge.make`, `Crypto.make`, `Privacy.make`, and `WaitUntil.make`.
|
|
257
409
|
|
|
410
|
+
The reference flow is a resumable pipeline. It assesses risk before deciding whether MFA is required, resumes the same risk and approval path after MFA, and preserves MFA freshness through a later login-approval challenge. Applications can provide `AuthFlowPipeline` to run app-owned policy checks or deny the flow without replacing the reference orchestration. Pipeline stages cannot replace authentication state, claims, risk, or trusted request facts:
|
|
411
|
+
|
|
412
|
+
```ts
|
|
413
|
+
import { Effect, Layer } from "effect";
|
|
414
|
+
import {
|
|
415
|
+
AuthFlowLive,
|
|
416
|
+
AuthFlowPipeline,
|
|
417
|
+
AuthFlowPipelineLive,
|
|
418
|
+
} from "@effect-auth/core/AuthFlow";
|
|
419
|
+
|
|
420
|
+
const AppAuthPipelineLive = AuthFlowPipelineLive([
|
|
421
|
+
{
|
|
422
|
+
phases: ["before-login-approval"],
|
|
423
|
+
run: (context) =>
|
|
424
|
+
invitationIsValid(context.input)
|
|
425
|
+
? Effect.succeed(AuthFlowPipeline.continueWith())
|
|
426
|
+
: Effect.succeed(AuthFlowPipeline.deny("Invitation required")),
|
|
427
|
+
},
|
|
428
|
+
]);
|
|
429
|
+
|
|
430
|
+
const AppAuthFlowLive = AuthFlowLive.pipe(Layer.provide(AppAuthPipelineLive));
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Available phases are `before-risk`, `after-risk`, `before-mfa`, `after-mfa`, and `before-login-approval`. Every stage receives `mfaSatisfied`, so stages can distinguish the initial primary-factor pass from a resumed MFA flow. Stages run again when the flow resumes; side effects that must execute exactly once should use an idempotency key or inspect `mfaSatisfied`.
|
|
434
|
+
|
|
258
435
|
The first default live implementations are available for the phase-3 web session path:
|
|
259
436
|
|
|
260
437
|
```ts
|
|
@@ -340,17 +517,17 @@ const PasswordHashingLive = Layer.mergeAll(
|
|
|
340
517
|
|
|
341
518
|
## HTTP API
|
|
342
519
|
|
|
343
|
-
`@effect-auth/core/HttpApi` contains the first Effect v4 HttpApi contract for the built-in auth surface. It exports `
|
|
520
|
+
`@effect-auth/core/HttpApi` contains the first Effect v4 HttpApi contract for the built-in auth surface. It exports `CoreAuthHttpApi`, module-owned endpoint groups, and handler layers for the core services.
|
|
344
521
|
|
|
345
522
|
```ts
|
|
346
523
|
import { Layer } from "effect";
|
|
347
524
|
import { HttpRouter } from "effect/unstable/http";
|
|
348
|
-
import {
|
|
525
|
+
import { CoreAuthHttpApiLive } from "@effect-auth/core/HttpApi";
|
|
349
526
|
import { PrivacyLive } from "./auth/privacy";
|
|
350
527
|
import { RateLimiterLive } from "./auth/rate-limiter";
|
|
351
528
|
|
|
352
529
|
export const AuthRoutesLive = HttpRouter.serve(
|
|
353
|
-
|
|
530
|
+
CoreAuthHttpApiLive.pipe(
|
|
354
531
|
Layer.provide(AuthServicesLive),
|
|
355
532
|
Layer.provide(RateLimiterLive),
|
|
356
533
|
Layer.provide(PrivacyLive)
|
|
@@ -360,25 +537,25 @@ export const AuthRoutesLive = HttpRouter.serve(
|
|
|
360
537
|
|
|
361
538
|
The contract currently includes these endpoint groups:
|
|
362
539
|
|
|
363
|
-
| Group
|
|
364
|
-
|
|
|
365
|
-
| Password
|
|
366
|
-
| Sessions
|
|
367
|
-
| Email verification | `POST /auth/email-verification/start`, `POST /auth/email-verification/verify`.
|
|
368
|
-
| Email OTP
|
|
369
|
-
| Magic link
|
|
370
|
-
| Login approval
|
|
371
|
-
| Security
|
|
540
|
+
| Group | Endpoints |
|
|
541
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
542
|
+
| Password | `POST /auth/password/sign-in`, `POST /auth/password/sign-up`, `POST /auth/password/reset/start`, `POST /auth/password/reset/verify`, `POST /auth/password/set`, `POST /auth/password/change`. |
|
|
543
|
+
| Sessions | `GET /auth/session`, `POST /auth/session/refresh`, `POST /auth/logout`, `GET /auth/sessions`, `POST /auth/sessions/revoke`, `POST /auth/sessions/revoke-others`. |
|
|
544
|
+
| Email verification | `POST /auth/email-verification/start`, `POST /auth/email-verification/verify`. |
|
|
545
|
+
| Email OTP | `POST /auth/email-otp/start`, `POST /auth/email-otp/verify`. |
|
|
546
|
+
| Magic link | `POST /auth/magic-link/start`, `POST /auth/magic-link/verify`. |
|
|
547
|
+
| Login approval | `POST /auth/login-approval/approve`, `POST /auth/login-approval/status`, `POST /auth/login-approval/finalize`. |
|
|
548
|
+
| Security | `POST /auth/security/login/report`. |
|
|
372
549
|
|
|
373
|
-
`
|
|
550
|
+
`CoreAuthHttpApiLive` wires the full built-in surface. Apps can own the final HTTP contract and reuse individual endpoints, services, and the public OAuth/WebAuthn protocol adapters when a feature needs app-specific payloads or responses.
|
|
374
551
|
|
|
375
552
|
`Authenticated` results set the configured session cookie and never include the opaque session token in JSON bodies. Invalid credentials and disabled accounts map to the same `401 invalid_credentials` response by default. Duplicate password sign-up emails fail as `EmailAlreadyRegisteredError` in the domain layer and map to a `409 email_already_registered` HTTP API error.
|
|
376
553
|
|
|
377
|
-
`
|
|
554
|
+
`SessionHttpApiGroup` reads the configured session cookie and validates it with `Sessions`, returning a safe current-session JSON body or `401 unauthenticated`. Refresh extends the current session when it is eligible, commits the refreshed session cookie, and returns the safe current-session JSON body. Safe authenticated bodies include session claims when present, but never include the opaque session token. Logout revokes the current session when present and clears the session cookie with a `204` response.
|
|
378
555
|
|
|
379
|
-
`
|
|
556
|
+
`CoreAuthHttpApiLive` includes `AuthOriginCheckMiddlewareLive()` for cookie-based unsafe methods and requires an `AuthRateLimit` service for built-in operation limits. Origin checks allow same-origin requests, reject cross-origin browser requests with `403 request_rejected`, and allow missing `Origin`/`Referer` headers by default for non-browser clients. Browser-only apps can compose their own `HttpApiBuilder.layer(CoreAuthHttpApi)` and provide `AuthOriginCheckMiddlewareLive({ allowMissingOrigin: false })`.
|
|
380
557
|
|
|
381
|
-
`AuthCsrfMiddlewareLive()` is available for apps that want double-submit CSRF checks on unsafe cookie endpoints. It compares the `__Host-csrf` cookie to the `x-csrf-token` header by default and rejects mismatches with `403 request_rejected`. App-owned HTTP handlers should map core
|
|
558
|
+
`AuthCsrfMiddlewareLive()` is available for apps that want double-submit CSRF checks on unsafe cookie endpoints. It compares the `__Host-csrf` cookie to the `x-csrf-token` header by default and rejects mismatches with `403 request_rejected`. App-owned HTTP handlers should use `mapAuthGuardErrors` to map core guard failures to safe HTTP errors without exposing policy reasons or internal details.
|
|
382
559
|
|
|
383
560
|
Apps using `AuthCsrfMiddleware` must issue the CSRF token themselves, usually from an app-owned bootstrap endpoint or page render. The token should be high-entropy, set as the `__Host-csrf` cookie, and echoed by browser code in the `x-csrf-token` header on unsafe cookie requests:
|
|
384
561
|
|
|
@@ -399,127 +576,93 @@ await fetch("/auth/session/refresh", {
|
|
|
399
576
|
});
|
|
400
577
|
```
|
|
401
578
|
|
|
402
|
-
`AuthRequestMetadataMiddlewareLive()` can provide method, URL, origin, user-agent, and trusted proxy IP metadata to app-owned handlers.
|
|
579
|
+
`AuthRequestMetadataMiddlewareLive()` can provide method, URL, origin, user-agent, and trusted proxy IP metadata to app-owned handlers. IP metadata uses direct request headers by default; set `requestMetadata.trustProxyHeaders` when your deployment terminates trusted proxy headers before the app:
|
|
403
580
|
|
|
404
581
|
```ts
|
|
405
|
-
import {
|
|
582
|
+
import { Layer } from "effect";
|
|
583
|
+
import { AuthRateLimitStandardLive } from "@effect-auth/core/AuthRateLimit";
|
|
406
584
|
import {
|
|
407
585
|
AuthHttpApiConfigLive,
|
|
408
|
-
|
|
586
|
+
CoreAuthHttpApiLive,
|
|
409
587
|
} from "@effect-auth/core/HttpApi";
|
|
410
|
-
import { PrivacyLive } from "./auth/privacy";
|
|
411
|
-
import { RateLimiterLive } from "./auth/rate-limiter";
|
|
412
588
|
|
|
413
|
-
export const AuthHttpApiLayer =
|
|
589
|
+
export const AuthHttpApiLayer = CoreAuthHttpApiLive.pipe(
|
|
414
590
|
Layer.provide(
|
|
415
591
|
AuthHttpApiConfigLive({
|
|
416
|
-
|
|
592
|
+
requestMetadata: {
|
|
417
593
|
trustProxyHeaders: true,
|
|
418
|
-
passwordSignIn: {
|
|
419
|
-
byIp: { limit: 20, window: Duration.minutes(10) },
|
|
420
|
-
byEmail: { limit: 5, window: Duration.minutes(10) },
|
|
421
|
-
},
|
|
422
|
-
passwordSignUp: {
|
|
423
|
-
byIp: false,
|
|
424
|
-
byEmail: { limit: 3, window: Duration.hours(1) },
|
|
425
|
-
},
|
|
426
|
-
emailVerificationStart: false,
|
|
427
594
|
},
|
|
428
595
|
})
|
|
429
596
|
),
|
|
597
|
+
Layer.provide(AuthRateLimitStandardLive()),
|
|
430
598
|
Layer.provide(AuthServicesLive),
|
|
431
599
|
Layer.provide(RateLimiterLive),
|
|
432
600
|
Layer.provide(PrivacyLive)
|
|
433
601
|
);
|
|
434
602
|
```
|
|
435
603
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
```ts
|
|
439
|
-
import { AuthHttpApiBareLive } from "@effect-auth/core/HttpApi";
|
|
440
|
-
|
|
441
|
-
export const AuthHttpApiLayer = AuthHttpApiBareLive.pipe(
|
|
442
|
-
Layer.provide(AuthServicesLive)
|
|
443
|
-
);
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
`EmailVerificationApi` exposes `start` and `verify` endpoints. `start` calls `EmailVerificationFlow` to issue and send a verification challenge through the app-owned `EmailDelivery` adapter. `verify` calls `EmailVerification` and returns `204` on success. When the request includes a valid current session cookie for the same user, `verify` also marks that session's claims as email verified and removes the `email_verification` requirement. Error responses are generic and do not include emails, user ids, challenge secrets, or provider details.
|
|
604
|
+
`EmailVerificationHttpApiGroup` exposes `start` and `verify` endpoints. `start` calls `EmailVerificationFlow` to issue and send a verification challenge through the app-owned `EmailDelivery` adapter. `verify` calls `EmailVerification` and returns `204` on success. When the request includes a valid current session cookie for the same user, `verify` also marks that session's claims as email verified and removes the `email_verification` requirement. Error responses are generic and do not include emails, user ids, challenge secrets, or provider details.
|
|
447
605
|
|
|
448
606
|
Password HTTP handlers can start `EmailVerificationFlow` automatically when a custom auth flow returns `RequiresEmailVerification`. The HTTP response remains `requires_email_verification` and does not include the user id, email, challenge secret, or delivery provider details.
|
|
449
607
|
|
|
450
|
-
|
|
608
|
+
Application workflow handlers belong in the app. Compose domain/application effects with guards, then map only guard failures into the endpoint's HTTP error contract:
|
|
451
609
|
|
|
452
610
|
```ts
|
|
453
|
-
import { Effect, Schema } from "effect";
|
|
611
|
+
import { Duration, Effect, Schema } from "effect";
|
|
454
612
|
import {
|
|
455
613
|
HttpApi,
|
|
456
614
|
HttpApiBuilder,
|
|
457
615
|
HttpApiEndpoint,
|
|
458
616
|
HttpApiGroup,
|
|
459
617
|
} from "effect/unstable/httpapi";
|
|
618
|
+
import * as Guard from "@effect-auth/core/Guard";
|
|
619
|
+
import * as RateLimiter from "@effect-auth/core/RateLimiter";
|
|
460
620
|
import {
|
|
461
|
-
AuthBadRequestError,
|
|
462
|
-
AuthEmailAlreadyRegisteredError,
|
|
463
|
-
AuthHttp,
|
|
464
621
|
AuthInternalError,
|
|
465
|
-
AuthOriginCheckMiddleware,
|
|
466
|
-
AuthPolicyDeniedError,
|
|
467
622
|
AuthRateLimitedError,
|
|
468
|
-
|
|
469
|
-
makePasswordSignInHandler,
|
|
470
|
-
passwordSignInEndpoint,
|
|
471
|
-
PasswordAuthSuccess,
|
|
623
|
+
mapAuthGuardErrors,
|
|
472
624
|
} from "@effect-auth/core/HttpApi";
|
|
473
|
-
import { EmailSchema } from "@effect-auth/core/Identifiers";
|
|
474
|
-
import { PasswordLogin } from "@effect-auth/core/Password";
|
|
475
625
|
|
|
476
|
-
const
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
password: Schema.String,
|
|
481
|
-
phone: PhoneNumber,
|
|
626
|
+
const updateProfileEndpoint = HttpApiEndpoint.post("update", "/profile", {
|
|
627
|
+
payload: Schema.Struct({ displayName: Schema.String }),
|
|
628
|
+
success: Schema.Struct({ updated: Schema.Boolean }),
|
|
629
|
+
error: [AuthRateLimitedError, AuthInternalError],
|
|
482
630
|
});
|
|
483
631
|
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
AuthEmailAlreadyRegisteredError,
|
|
490
|
-
AuthPolicyDeniedError,
|
|
491
|
-
AuthRateLimitedError,
|
|
492
|
-
AuthInternalError,
|
|
493
|
-
],
|
|
632
|
+
const UpdateProfileRateLimit = RateLimiter.RateLimitPolicy.fixedWindow({
|
|
633
|
+
id: "app.profile.update",
|
|
634
|
+
key: RateLimiter.RateLimitKey.global,
|
|
635
|
+
limit: 20,
|
|
636
|
+
window: Duration.minutes(1),
|
|
494
637
|
});
|
|
495
638
|
|
|
496
|
-
class
|
|
497
|
-
.add(
|
|
498
|
-
.prefix("/auth
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
);
|
|
519
|
-
})
|
|
639
|
+
class ProfileHttpApiGroup extends HttpApiGroup.make("profile")
|
|
640
|
+
.add(updateProfileEndpoint)
|
|
641
|
+
.prefix("/auth") {}
|
|
642
|
+
|
|
643
|
+
class AppApi extends HttpApi.make("AppApi").add(ProfileHttpApiGroup) {}
|
|
644
|
+
|
|
645
|
+
const updateProfile = (displayName: string) =>
|
|
646
|
+
Effect.succeed({ updated: displayName.length > 0 });
|
|
647
|
+
|
|
648
|
+
export const ProfileHttpApiGroupLive = HttpApiBuilder.group(
|
|
649
|
+
AppApi,
|
|
650
|
+
"profile",
|
|
651
|
+
(handlers) =>
|
|
652
|
+
handlers.handle(
|
|
653
|
+
"update",
|
|
654
|
+
Effect.fn("app.auth.profile.update")(function* ({ payload }) {
|
|
655
|
+
return yield* updateProfile(payload.displayName).pipe(
|
|
656
|
+
Guard.requireAll(RateLimiter.require(UpdateProfileRateLimit)),
|
|
657
|
+
mapAuthGuardErrors
|
|
658
|
+
);
|
|
659
|
+
})
|
|
660
|
+
)
|
|
520
661
|
);
|
|
521
662
|
```
|
|
522
663
|
|
|
664
|
+
Use `Guard.requireAll` with `RateLimiter.require(...)`, `AuthRateLimit.require(...)`, direct `StepUp` effects, direct `Policy` effects, or any app-owned guard. This keeps workflow ownership local instead of importing a thin core handler factory. `mapAuthGuardErrors` preserves unrelated domain errors, so include those separately in the endpoint error schema.
|
|
665
|
+
|
|
523
666
|
## Sessions
|
|
524
667
|
|
|
525
668
|
`Sessions` is the server-side session authority. Transports such as cookies are separate services so browser, API, and custom transports can share the same session strategy.
|
|
@@ -556,15 +699,15 @@ export const createBrowserSession = (userId: UserId) =>
|
|
|
556
699
|
Password auth passes the user's email verification state into `AuthFlow`, where `EmailVerificationSessionPolicy` decides whether unverified users get a normal session or a constrained session. The default mode is `allow-unverified` for compatibility. Use `limited-session` to issue sessions with an `email_verification` requirement. Per-login email approval is a separate `UserSecurityPolicy` / `LoginApprovalPolicy` concern, not an email verification session mode.
|
|
557
700
|
|
|
558
701
|
```ts
|
|
559
|
-
import {
|
|
702
|
+
import { AuthFlowWithEmailVerificationPolicyLive } from "@effect-auth/core/AuthFlow";
|
|
560
703
|
|
|
561
704
|
export const AllowUnverifiedAuthFlowLive =
|
|
562
|
-
|
|
705
|
+
AuthFlowWithEmailVerificationPolicyLive({
|
|
563
706
|
mode: "allow-unverified",
|
|
564
707
|
});
|
|
565
708
|
|
|
566
709
|
export const LimitedSessionAuthFlowLive =
|
|
567
|
-
|
|
710
|
+
AuthFlowWithEmailVerificationPolicyLive({
|
|
568
711
|
mode: "limited-session",
|
|
569
712
|
});
|
|
570
713
|
```
|
|
@@ -721,7 +864,7 @@ import {
|
|
|
721
864
|
} from "@effect-auth/core/EmailVerification";
|
|
722
865
|
import type { ChallengeId, Email, UserId } from "@effect-auth/core/Identifiers";
|
|
723
866
|
|
|
724
|
-
const emailDelivery = EmailDelivery.
|
|
867
|
+
const emailDelivery = EmailDelivery.of({
|
|
725
868
|
sendEmailVerification: ({ email, secret, challengeId }) =>
|
|
726
869
|
sendMail({
|
|
727
870
|
to: email,
|
|
@@ -796,19 +939,19 @@ import {
|
|
|
796
939
|
VerificationStore,
|
|
797
940
|
} from "@effect-auth/core/Storage";
|
|
798
941
|
|
|
799
|
-
const UserStoreLive = UserStore.
|
|
942
|
+
const UserStoreLive = UserStore.of({
|
|
800
943
|
findById: () => Effect.succeed(Option.none()),
|
|
801
944
|
findByEmail: () => Effect.succeed(Option.none()),
|
|
802
945
|
insert: () => Effect.void,
|
|
803
946
|
markEmailVerified: () => Effect.succeed(Option.none()),
|
|
804
947
|
});
|
|
805
948
|
|
|
806
|
-
const CredentialStoreLive = CredentialStore.
|
|
949
|
+
const CredentialStoreLive = CredentialStore.of({
|
|
807
950
|
findPasswordByUserId: () => Effect.succeed(Option.none()),
|
|
808
951
|
insertPassword: () => Effect.void,
|
|
809
952
|
});
|
|
810
953
|
|
|
811
|
-
const SessionStoreLive = SessionStore.
|
|
954
|
+
const SessionStoreLive = SessionStore.of({
|
|
812
955
|
findById: () => Effect.succeed(Option.none()),
|
|
813
956
|
insert: () => Effect.void,
|
|
814
957
|
refresh: () => Effect.succeed(Option.none()),
|
|
@@ -817,7 +960,7 @@ const SessionStoreLive = SessionStore.make({
|
|
|
817
960
|
revokeAllForUser: () => Effect.void,
|
|
818
961
|
});
|
|
819
962
|
|
|
820
|
-
const VerificationStoreLive = VerificationStore.
|
|
963
|
+
const VerificationStoreLive = VerificationStore.of({
|
|
821
964
|
findById: () => Effect.succeed(Option.none()),
|
|
822
965
|
insert: () => Effect.void,
|
|
823
966
|
consume: () => Effect.succeed(Option.none()),
|
|
@@ -829,9 +972,10 @@ The default schema is exported as SQL and as package assets:
|
|
|
829
972
|
|
|
830
973
|
```ts
|
|
831
974
|
import { authStorageMigrations } from "@effect-auth/core/StorageMigrations";
|
|
975
|
+
import { postgresAuthStorageMigrations } from "@effect-auth/core/PostgresStorageMigrations";
|
|
832
976
|
```
|
|
833
977
|
|
|
834
|
-
Effect-QB SQLite/D1 storage is
|
|
978
|
+
Effect-QB SQLite/D1 storage is a first-party durable adapter. The default path uses the auth schema and requires no table mapping:
|
|
835
979
|
|
|
836
980
|
```ts
|
|
837
981
|
import { EffectQbSqliteAuthStorageLive } from "@effect-auth/core/EffectQbSqliteStorage";
|
|
@@ -841,6 +985,18 @@ const StorageLive = EffectQbSqliteAuthStorageLive(executor);
|
|
|
841
985
|
|
|
842
986
|
`EffectQbSqliteAuthStorageLive` provides all durable auth stores in the default schema, including audit log storage, domain verification storage, and the OAuth provider-token vault for already-encrypted provider token ciphertexts. Apps still own provider-token encryption, KMS/secrets-service policy, DNS/HTTP proof checking, and tenant authorization before values reach storage.
|
|
843
987
|
|
|
988
|
+
The native Effect-QB Postgres adapter also provides the complete grouped store set, including `PermissionStore`. Apply the exported Postgres migrations through `0009_auth_permissions`, then provide `EffectQbPostgresCoreStoresLive(sql)` or construct `makeEffectQbPostgresPermissionStore(executor)` directly.
|
|
989
|
+
|
|
990
|
+
Application-owned queries can reuse the adapter's canonical table objects instead of redeclaring `Table.make(...)` metadata:
|
|
991
|
+
|
|
992
|
+
```ts
|
|
993
|
+
import { effectQbPostgresTables } from "@effect-auth/core/EffectQbPostgresStorage";
|
|
994
|
+
|
|
995
|
+
const { user, session, permissionDefinition } = effectQbPostgresTables;
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
Use the public store services for auth mutations unless custom writes preserve the adapter's security and atomicity invariants.
|
|
999
|
+
|
|
844
1000
|
For Cloudflare D1, create an effect-qb SQLite executor from the D1 binding:
|
|
845
1001
|
|
|
846
1002
|
```ts
|
|
@@ -861,6 +1017,20 @@ import { DrizzleD1SqliteAuthStorageLive } from "@effect-auth/core/DrizzleD1Sqlit
|
|
|
861
1017
|
const StorageLive = DrizzleD1SqliteAuthStorageLive(env.DB);
|
|
862
1018
|
```
|
|
863
1019
|
|
|
1020
|
+
Runtime-specific Drizzle SQLite helpers are available for Node and Bun. They construct the matching Drizzle Effect SQLite database from the Effect SQL client layer, then reuse the same auth storage bridge:
|
|
1021
|
+
|
|
1022
|
+
```ts
|
|
1023
|
+
import { DrizzleBunSqliteAuthStorageLive } from "@effect-auth/core/DrizzleBunSqliteStorage";
|
|
1024
|
+
|
|
1025
|
+
const StorageLive = DrizzleBunSqliteAuthStorageLive({
|
|
1026
|
+
filename: "auth.sqlite",
|
|
1027
|
+
});
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
Install the matching runtime package when using a runtime-specific subpath, such as `@effect/sql-sqlite-bun` or `@effect/sql-sqlite-node`.
|
|
1031
|
+
|
|
1032
|
+
Database and ORM packages used only by storage subpaths are optional peers. The metadata-only root does not load them; install the matching optional peers for the adapter subpath your application imports.
|
|
1033
|
+
|
|
864
1034
|
If your app already builds a Drizzle Effect SQLite database, use the generic subpath instead. This keeps D1-specific dependencies out of non-D1 runtimes:
|
|
865
1035
|
|
|
866
1036
|
```ts
|
|
@@ -874,9 +1044,11 @@ Both Drizzle paths use the same default auth schema and table mapping options as
|
|
|
874
1044
|
```ts
|
|
875
1045
|
import { makeD1DrizzleEffectSqliteDatabase } from "@effect-auth/core/DrizzleD1SqliteStorage";
|
|
876
1046
|
|
|
877
|
-
const drizzle =
|
|
878
|
-
|
|
879
|
-
|
|
1047
|
+
const drizzle =
|
|
1048
|
+
yield *
|
|
1049
|
+
makeD1DrizzleEffectSqliteDatabase(env.DB, {
|
|
1050
|
+
relations,
|
|
1051
|
+
});
|
|
880
1052
|
```
|
|
881
1053
|
|
|
882
1054
|
Applications with their own Effect-QB tables can map semantic auth fields to app-owned columns with `defineEffectQbAuthTables`:
|
|
@@ -932,7 +1104,9 @@ const authTables = defineEffectQbAuthTables({
|
|
|
932
1104
|
// credential/session/verification/audit/review/trusted-device/passkey/TOTP/recovery-code/API-key/refresh-token/OAuth-account/provider-token-vault/domain-verification mappings follow the same pattern.
|
|
933
1105
|
});
|
|
934
1106
|
|
|
935
|
-
const StorageLive = EffectQbSqliteAuthStorageLive(executor, {
|
|
1107
|
+
const StorageLive = EffectQbSqliteAuthStorageLive(executor, atomic, {
|
|
936
1108
|
tables: authTables,
|
|
937
1109
|
});
|
|
938
1110
|
```
|
|
1111
|
+
|
|
1112
|
+
Mappings used by atomic composite stores must select direct bound columns and return literal driver values from mutation functions. Expression-valued mutation mappings require an application-owned store implementation.
|