@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/HttpApi/Api.js
CHANGED
|
@@ -1,80 +1,52 @@
|
|
|
1
|
-
import { Context, Effect, Encoding, Layer, Option, Redacted, Result } from "effect";
|
|
2
|
-
import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
1
|
+
import { Context, Effect, Encoding, Layer, Option, Redacted, Result, } from "effect";
|
|
2
|
+
import { HttpRouter, HttpServerRequest, HttpServerResponse, } from "effect/unstable/http";
|
|
3
3
|
import { HttpApi, HttpApiBuilder, HttpApiGroup } from "effect/unstable/httpapi";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { BotChallengeVerifier, BotProtectionNoopLive, } from "../AbuseProtection.js";
|
|
5
|
+
import { ApiKeyId, ApiKeyManagement } from "../ApiKey.js";
|
|
6
|
+
import { passkeyEvidence, passwordEvidence, recoveryCodeEvidence, totpEvidence, } from "../Assurance.js";
|
|
7
|
+
import * as Audit from "../AuditLog.js";
|
|
6
8
|
import { AuthFlow, AuthFlowState, AuthResult, LoginApprovalFinalize, } from "../AuthFlow.js";
|
|
9
|
+
import { AuthRateLimit } from "../AuthRateLimit.js";
|
|
10
|
+
import { EmailAuth } from "../EmailAuth.js";
|
|
7
11
|
import { EmailOtpLogin } from "../EmailOtp.js";
|
|
12
|
+
import { EmailRiskProviderUnavailableError } from "../EmailRisk.js";
|
|
8
13
|
import { EmailDeliveryError, EmailVerification, EmailVerificationFlow, EmailVerificationIssueError, } from "../EmailVerification.js";
|
|
9
|
-
import { OAuthClientId as makeOAuthClientId } from "../Identifiers.js";
|
|
14
|
+
import { ChallengeId, CredentialId, OAuthClientId as makeOAuthClientId, } from "../Identifiers.js";
|
|
15
|
+
import { IdentityAlreadyExistsError, IdentityConcurrentModificationError, IdentityInactiveError, IdentityIdGenerationError, IdentityManagement, IdentityManagementStorageError, IdentityMutationDeniedError, IdentityNotFoundError, IdentityNotLoginEligibleError, IdentityOwnershipError, IdentityUserNotActiveError, LastLoginIdentityError, } from "../IdentityManagement.js";
|
|
10
16
|
import { currentUnixMillis } from "../Internal.js";
|
|
17
|
+
import { AuthFlowFinalizer, AuthFlowFinalizerLive, } from "../internal/AuthFlowFinalizer.js";
|
|
18
|
+
import { Jwks, JwtIssuer, JwtRevocation } from "../Jwt.js";
|
|
11
19
|
import { LoginApproval, LoginApprovalReview } from "../LoginApproval.js";
|
|
12
20
|
import { LoginNotification } from "../LoginNotification.js";
|
|
13
21
|
import { MagicLinkLogin } from "../MagicLink.js";
|
|
14
|
-
import { OAuthAuthorizationCode, OAuthAuthorizationCodeTokenGrant, OAuthClientCredentialsGrant, OAuthProviderAuthorization, OAuthRefreshToken, OAuthRefreshTokenGrant, OAuthTokenIntrospection, OAuthTokenRevocation, OAuthCodeVerifier as makeOAuthCodeVerifier, } from "../OAuth.js";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
22
|
+
import { OAuthAuthorizationCode, OAuthAuthorizationCodeTokenGrant, OAuthAccountUnlinking, OAuthClientCredentialsGrant, OAuthProviderAuthorization, OAuthProviders, OAuthRefreshToken, OAuthRefreshTokenGrant, OAuthTokenIntrospection, OAuthTokenRevocation, OAuthLinkConfirmation, OAuthState, OAuthCodeVerifier as makeOAuthCodeVerifier, } from "../OAuth.js";
|
|
23
|
+
import { PasskeyCredentialId, PasskeyCredentialManagement, PasskeyOptions, PasskeyVerification, } from "../Passkey.js";
|
|
24
|
+
import { PasswordHasher } from "../Password.js";
|
|
25
|
+
import { normalizePermissionDefinitionListLimit, PermissionAdministration, } from "../Permission.js";
|
|
26
|
+
import { RecoveryCodeLoginCommitStore, RecoveryCodeManagement, } from "../RecoveryCode.js";
|
|
27
|
+
import { defaultRecoveryRemediationCapabilities, withRecoveryRemediationRequirement, } from "../RecoveryPolicy.js";
|
|
28
|
+
import { RefreshTokenManagement } from "../RefreshToken.js";
|
|
18
29
|
import { SecurityTimelineStore } from "../SecurityTimeline.js";
|
|
19
|
-
import {
|
|
30
|
+
import { SessionCookie, Sessions, RecoveryCodeSessionRotation, TotpSessionRotation, sessionRequestMetadataKey, } from "../Sessions.js";
|
|
31
|
+
import { CredentialStore, IdentityStore, UserStore, VerificationStore, } from "../Storage.js";
|
|
32
|
+
import { StrongFactorRemovalPolicy, strongFactor } from "../StrongFactor.js";
|
|
33
|
+
import { TotpFactorManagement, TotpLoginCommitStore } from "../Totp.js";
|
|
20
34
|
import { TrustedDevice, TrustedDeviceCookie, TrustedDeviceStore, } from "../TrustedDevice.js";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
35
|
+
import { EmailAuthHttpApiGroup, EmailOtpHttpApiGroup, EmailVerificationHttpApiGroup, IdentityHttpApiGroup, LoginApprovalHttpApiGroup, MagicLinkHttpApiGroup, MfaHttpApiGroup, PasskeyHttpApiGroup, PasswordHttpApiGroup, RecoveryCodesHttpApiGroup, LoginNotificationHttpApiGroup, SessionHttpApiGroup, StepUpHttpApiGroup, TotpHttpApiGroup, } from "./ClientApi.js";
|
|
36
|
+
import { EmailGuards } from "./EmailGuards.js";
|
|
37
|
+
import { adminSecurityTimelineListEndpoint, adminPermissionDefinitionCreateEndpoint, adminPermissionDefinitionDeleteEndpoint, adminPermissionDefinitionDisableEndpoint, adminPermissionDefinitionEnableEndpoint, adminPermissionDefinitionGetEndpoint, adminPermissionDefinitionListEndpoint, adminPermissionDefinitionUpdateEndpoint, adminSessionListEndpoint, adminSessionRevokeAllEndpoint, adminSessionRevokeEndpoint, adminTrustedDeviceListEndpoint, adminTrustedDeviceRevokeEndpoint, apiKeyCreateEndpoint, apiKeyListEndpoint, apiKeyRevokeEndpoint, jwtIntrospectEndpoint, jwtJwksEndpoint, jwtRevokeEndpoint, oauthAccountUnlinkEndpoint, oauthAuthorizationStartEndpoint, oauthLinkConfirmationConfirmEndpoint, oauthLinkConfirmationInspectEndpoint, oauthLinkConfirmationStartEndpoint, oauthProviderAuthorizeEndpoint, oauthTokenEndpoint, oauthTokenIntrospectionEndpoint, oauthTokenRevocationEndpoint, oidcDiscoveryMetadataEndpoint, refreshTokenRefreshEndpoint, securityTimelineListEndpoint, trustedDeviceListEndpoint, trustedDeviceRevokeEndpoint, } from "./Endpoints.js";
|
|
38
|
+
import { AuthBadRequestError, AuthConflictError, AuthIdentityAlreadyRegisteredError, AuthInternalError, AuthInvalidCredentialsError, AuthNotFoundError, AuthPolicyDeniedError, AuthSchemaErrorMiddleware, AuthSchemaErrorMiddlewareLive, AuthUnauthenticatedError, OAuthAuthorizationEndpointError, OAuthTokenEndpointError, OAuthTokenIntrospectionEndpointError, OAuthTokenRevocationEndpointError, } from "./Errors.js";
|
|
39
|
+
import { IdentityGuards } from "./IdentityGuards.js";
|
|
40
|
+
import { AuthOriginCheckMiddleware } from "./Middleware.js";
|
|
41
|
+
import { AdminSecurityTimelineHttpOperations, AdminPermissionDefinitionHttpOperations, AdminSessionHttpOperations, AdminTrustedDeviceHttpOperations, ApiKeyHttpOperations, EmailAuthHttpOperations, EmailOtpHttpOperations, EmailVerificationHttpOperations, JwtDiscoveryHttpOperations, JwtHttpOperations, LoginApprovalHttpOperations, MagicLinkHttpOperations, MfaHttpOperations, OAuthHttpOperations, OAuthProviderAuthorizationHttpOperations, OAuthTokenHttpOperations, OidcDiscoveryHttpOperations, PasskeyHttpOperations, IdentityHttpOperations, RecoveryCodesHttpOperations, RefreshTokenHttpOperations, LoginNotificationHttpOperations, SecurityTimelineHttpOperations, SessionHttpOperations, StepUpHttpOperations, TotpHttpOperations, TrustedDeviceHttpOperations, } from "./Operations/index.js";
|
|
42
|
+
import { PasswordHttpOperationsLive, passwordGroupHandlers, } from "./Password.js";
|
|
43
|
+
import { requireAuthRateLimit } from "./RequestGuards.js";
|
|
23
44
|
import { OAuthProviderAuthorizationQuery, OAuthTokenRequestBody, OAuthTokenIntrospectionRequestBody, OAuthTokenIntrospectionResponseBody, OAuthTokenRevocationRequestBody, } from "./Schemas.js";
|
|
24
|
-
import {
|
|
45
|
+
import { AuthOriginCheckMiddlewareConfigLive, customEvidencePolicyHttpFailure, } from "./Security.js";
|
|
46
|
+
import { readOptionalSession, readRequiredSession, requireSession, } from "./SessionGuards.js";
|
|
25
47
|
import { AuthHttp, LoginApprovalPendingCookie, makeLoginApprovalPendingCookie, } from "./Transport.js";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
result.email !== undefined;
|
|
29
|
-
const noopAuthApiRateLimit = AuthApiRateLimit.make({
|
|
30
|
-
request: () => Effect.void,
|
|
31
|
-
passwordSignIn: () => Effect.void,
|
|
32
|
-
passwordSignUp: () => Effect.void,
|
|
33
|
-
passwordResetStart: () => Effect.void,
|
|
34
|
-
emailOtpStart: () => Effect.void,
|
|
35
|
-
magicLinkStart: () => Effect.void,
|
|
36
|
-
emailVerificationStart: () => Effect.void,
|
|
37
|
-
});
|
|
38
|
-
export const passwordSignInInput = (payload, trustedDeviceToken, request) => ({
|
|
39
|
-
...payload,
|
|
40
|
-
password: Redacted.make(payload.password),
|
|
41
|
-
...(trustedDeviceToken === undefined ? {} : { trustedDeviceToken }),
|
|
42
|
-
...(request === undefined ? {} : { request }),
|
|
43
|
-
});
|
|
44
|
-
export const passwordSignUpInput = (payload, request) => ({
|
|
45
|
-
...payload,
|
|
46
|
-
password: Redacted.make(payload.password),
|
|
47
|
-
...(request === undefined ? {} : { request }),
|
|
48
|
-
});
|
|
49
|
-
export const passwordResetStartInput = (payload) => {
|
|
50
|
-
const { secret, ...input } = payload;
|
|
51
|
-
return {
|
|
52
|
-
...input,
|
|
53
|
-
...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
export const passwordResetVerifyInput = (payload) => ({
|
|
57
|
-
challengeId: payload.challengeId,
|
|
58
|
-
secret: Redacted.make(payload.secret),
|
|
59
|
-
password: Redacted.make(payload.password),
|
|
60
|
-
});
|
|
61
|
-
export const passwordSetInput = (userId, payload) => ({
|
|
62
|
-
userId,
|
|
63
|
-
password: Redacted.make(payload.password),
|
|
64
|
-
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
65
|
-
});
|
|
66
|
-
export const passwordChangeInput = (userId, payload) => ({
|
|
67
|
-
userId,
|
|
68
|
-
currentPassword: Redacted.make(payload.currentPassword),
|
|
69
|
-
newPassword: Redacted.make(payload.newPassword),
|
|
70
|
-
});
|
|
71
|
-
export const emailVerificationStartInput = (payload) => {
|
|
72
|
-
const { secret, ...input } = payload;
|
|
73
|
-
return {
|
|
74
|
-
...input,
|
|
75
|
-
...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
|
|
76
|
-
};
|
|
77
|
-
};
|
|
48
|
+
export { AuthClientProtocolApi, EmailAuthHttpApiGroup, EmailOtpHttpApiGroup, EmailVerificationHttpApiGroup, IdentityHttpApiGroup, LoginApprovalHttpApiGroup, MagicLinkHttpApiGroup, MfaHttpApiGroup, PasskeyHttpApiGroup, PasswordHttpApiGroup, RecoveryCodesHttpApiGroup, LoginNotificationHttpApiGroup, SessionHttpApiGroup, StepUpHttpApiGroup, TotpHttpApiGroup, } from "./ClientApi.js";
|
|
49
|
+
export { makePasswordChangeHandler, makePasswordResetStartHandler, makePasswordResetVerifyHandler, makePasswordSetHandler, makePasswordSignInHandler, makePasswordSignUpHandler, passwordChangeInput, passwordSetInput, PasswordHttpApi, PasswordHttpApiGroupLive, PasswordHttpApiLive, PasswordHttpOperationsLive, } from "./Password.js";
|
|
78
50
|
export const emailVerificationVerifyInput = (payload) => {
|
|
79
51
|
const { secret, ...input } = payload;
|
|
80
52
|
return {
|
|
@@ -82,36 +54,12 @@ export const emailVerificationVerifyInput = (payload) => {
|
|
|
82
54
|
...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
|
|
83
55
|
};
|
|
84
56
|
};
|
|
85
|
-
export const emailOtpStartInput = (payload) => {
|
|
86
|
-
const { secret, ...input } = payload;
|
|
87
|
-
return {
|
|
88
|
-
...input,
|
|
89
|
-
...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
export const emailOtpVerifyInput = (payload, trustedDeviceToken, request) => ({
|
|
93
|
-
challengeId: payload.challengeId,
|
|
94
|
-
secret: Redacted.make(payload.secret),
|
|
95
|
-
...(trustedDeviceToken === undefined ? {} : { trustedDeviceToken }),
|
|
96
|
-
...(request === undefined ? {} : { request }),
|
|
97
|
-
});
|
|
98
|
-
export const magicLinkStartInput = (payload) => {
|
|
99
|
-
const { secret, ...input } = payload;
|
|
100
|
-
return {
|
|
101
|
-
...input,
|
|
102
|
-
...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
|
|
103
|
-
};
|
|
104
|
-
};
|
|
105
|
-
export const magicLinkVerifyInput = (payload, trustedDeviceToken, request) => ({
|
|
106
|
-
challengeId: payload.challengeId,
|
|
107
|
-
secret: Redacted.make(payload.secret),
|
|
108
|
-
...(trustedDeviceToken === undefined ? {} : { trustedDeviceToken }),
|
|
109
|
-
...(request === undefined ? {} : { request }),
|
|
110
|
-
});
|
|
111
57
|
export const oauthAuthorizationStartInput = (payload, provider, options = {}) => ({
|
|
112
58
|
provider,
|
|
113
59
|
...(options.ttl === undefined ? {} : { ttl: options.ttl }),
|
|
114
|
-
...(payload.redirectUri === undefined
|
|
60
|
+
...(payload.redirectUri === undefined
|
|
61
|
+
? {}
|
|
62
|
+
: { redirectUri: payload.redirectUri }),
|
|
115
63
|
...(payload.scopes === undefined ? {} : { scopes: payload.scopes }),
|
|
116
64
|
...(payload.authorizationParams === undefined
|
|
117
65
|
? {}
|
|
@@ -166,11 +114,15 @@ export const oauthLinkConfirmationStartInput = (payload, options = {}) => Effect
|
|
|
166
114
|
});
|
|
167
115
|
export const oauthLinkConfirmationInspectInput = (payload) => ({
|
|
168
116
|
challengeId: payload.challengeId,
|
|
169
|
-
...(payload.secret === undefined
|
|
117
|
+
...(payload.secret === undefined
|
|
118
|
+
? {}
|
|
119
|
+
: { secret: Redacted.make(payload.secret) }),
|
|
170
120
|
});
|
|
171
121
|
export const oauthLinkConfirmationConfirmInput = (payload, currentUserId) => ({
|
|
172
122
|
challengeId: payload.challengeId,
|
|
173
|
-
...(payload.secret === undefined
|
|
123
|
+
...(payload.secret === undefined
|
|
124
|
+
? {}
|
|
125
|
+
: { secret: Redacted.make(payload.secret) }),
|
|
174
126
|
...(currentUserId === undefined ? {} : { currentUserId }),
|
|
175
127
|
...(payload.expectedProviderId === undefined
|
|
176
128
|
? {}
|
|
@@ -361,7 +313,9 @@ const oauthClientEndpointAuthentication = (input) => Effect.gen(function* () {
|
|
|
361
313
|
if (input.payload.client_secret !== undefined && postAuth === undefined) {
|
|
362
314
|
return yield* Effect.fail(input.invalidRequest());
|
|
363
315
|
}
|
|
364
|
-
const authentication = Option.isSome(basicAuth)
|
|
316
|
+
const authentication = Option.isSome(basicAuth)
|
|
317
|
+
? basicAuth.value
|
|
318
|
+
: postAuth;
|
|
365
319
|
const payloadClientId = oauthTokenGrantString(input.payload.client_id);
|
|
366
320
|
if (authentication !== undefined &&
|
|
367
321
|
payloadClientId !== undefined &&
|
|
@@ -438,7 +392,9 @@ const oauthTokenIntrospectionResponseHttpBody = (introspection) => {
|
|
|
438
392
|
...(introspection.notBefore === undefined
|
|
439
393
|
? {}
|
|
440
394
|
: { nbf: oauthUnixMillisToSeconds(introspection.notBefore) }),
|
|
441
|
-
...(introspection.subject === undefined
|
|
395
|
+
...(introspection.subject === undefined
|
|
396
|
+
? {}
|
|
397
|
+
: { sub: introspection.subject }),
|
|
442
398
|
...(introspection.audience === undefined
|
|
443
399
|
? {}
|
|
444
400
|
: {
|
|
@@ -446,9 +402,13 @@ const oauthTokenIntrospectionResponseHttpBody = (introspection) => {
|
|
|
446
402
|
? [...introspection.audience]
|
|
447
403
|
: introspection.audience,
|
|
448
404
|
}),
|
|
449
|
-
...(introspection.issuer === undefined
|
|
405
|
+
...(introspection.issuer === undefined
|
|
406
|
+
? {}
|
|
407
|
+
: { iss: introspection.issuer }),
|
|
450
408
|
...(introspection.jwtId === undefined ? {} : { jti: introspection.jwtId }),
|
|
451
|
-
...(introspection.extra === undefined
|
|
409
|
+
...(introspection.extra === undefined
|
|
410
|
+
? {}
|
|
411
|
+
: { extra: introspection.extra }),
|
|
452
412
|
};
|
|
453
413
|
};
|
|
454
414
|
const oauthRefreshTokenResponse = (input) => Effect.gen(function* () {
|
|
@@ -505,7 +465,9 @@ const oauthAuthorizationCodeTokenResponse = (input) => Effect.gen(function* () {
|
|
|
505
465
|
...(redirectUri === undefined ? {} : { redirectUri }),
|
|
506
466
|
...(codeVerifier === undefined
|
|
507
467
|
? {}
|
|
508
|
-
: {
|
|
468
|
+
: {
|
|
469
|
+
codeVerifier: Redacted.make(makeOAuthCodeVerifier(codeVerifier)),
|
|
470
|
+
}),
|
|
509
471
|
clientAuthenticated: input.clientAuthenticated,
|
|
510
472
|
})
|
|
511
473
|
.pipe(Effect.mapError(() => oauthInternalError("Failed to exchange OAuth token")));
|
|
@@ -526,7 +488,9 @@ export const oauthLinkConfirmationConfirmedHttpBody = (confirmed, options = {})
|
|
|
526
488
|
reason: confirmed.reason,
|
|
527
489
|
...(confirmed.existingAccount === undefined
|
|
528
490
|
? {}
|
|
529
|
-
: {
|
|
491
|
+
: {
|
|
492
|
+
existingAccount: oauthLinkedAccountHttpBody(confirmed.existingAccount),
|
|
493
|
+
}),
|
|
530
494
|
linked: options.linked === true || confirmed.existingAccount !== undefined,
|
|
531
495
|
});
|
|
532
496
|
export const oauthAccountUnlinkResolutionHttpBody = (resolution, options = {}) => {
|
|
@@ -573,11 +537,87 @@ export const oauthAccountUnlinkResolutionHttpBody = (resolution, options = {}) =
|
|
|
573
537
|
}
|
|
574
538
|
}
|
|
575
539
|
};
|
|
576
|
-
export
|
|
540
|
+
export class PasskeyHttpConfig extends Context.Service()("auth/http/config/Passkey") {
|
|
541
|
+
}
|
|
542
|
+
(function (PasskeyHttpConfig) {
|
|
543
|
+
PasskeyHttpConfig.make = (config) => PasskeyHttpConfig.of(config);
|
|
544
|
+
})(PasskeyHttpConfig || (PasskeyHttpConfig = {}));
|
|
545
|
+
export const PasskeyHttpConfigLive = (config) => Layer.succeed(PasskeyHttpConfig)(PasskeyHttpConfig.make(config));
|
|
546
|
+
export class TotpHttpConfig extends Context.Service()("auth/http/config/Totp") {
|
|
547
|
+
}
|
|
548
|
+
(function (TotpHttpConfig) {
|
|
549
|
+
TotpHttpConfig.make = (config) => TotpHttpConfig.of(config);
|
|
550
|
+
})(TotpHttpConfig || (TotpHttpConfig = {}));
|
|
551
|
+
export const TotpHttpConfigLive = (config) => Layer.succeed(TotpHttpConfig)(TotpHttpConfig.make(config));
|
|
552
|
+
export const RecoveryCodeHttpConfig = Context.Reference("auth/http/config/RecoveryCode", { defaultValue: () => ({}) });
|
|
553
|
+
export const RecoveryCodeHttpConfigLive = (config = {}) => Layer.succeed(RecoveryCodeHttpConfig)(config);
|
|
554
|
+
export const OAuthHttpConfig = Context.Reference("auth/http/config/OAuth", { defaultValue: () => ({}) });
|
|
555
|
+
export const OAuthHttpConfigLive = (config = {}) => Layer.succeed(OAuthHttpConfig)(config);
|
|
556
|
+
export const OAuthTokenHttpConfig = Context.Reference("auth/http/config/OAuthToken", { defaultValue: () => ({}) });
|
|
557
|
+
export const OAuthTokenHttpConfigLive = (config = {}) => Layer.succeed(OAuthTokenHttpConfig)(config);
|
|
558
|
+
export class RefreshTokenHttpConfig extends Context.Service()("auth/http/config/RefreshToken") {
|
|
559
|
+
}
|
|
560
|
+
(function (RefreshTokenHttpConfig) {
|
|
561
|
+
RefreshTokenHttpConfig.make = (config) => RefreshTokenHttpConfig.of(config);
|
|
562
|
+
})(RefreshTokenHttpConfig || (RefreshTokenHttpConfig = {}));
|
|
563
|
+
export const RefreshTokenHttpConfigLive = (config) => Layer.succeed(RefreshTokenHttpConfig)(RefreshTokenHttpConfig.make(config));
|
|
564
|
+
export const JwtHttpConfig = Context.Reference("auth/http/config/Jwt", { defaultValue: () => ({}) });
|
|
565
|
+
export const JwtHttpConfigLive = (config = {}) => Layer.succeed(JwtHttpConfig)(config);
|
|
566
|
+
export const passkeyRegistrationStartHttpOptions = (config) => ({
|
|
567
|
+
relyingParty: config.relyingParty,
|
|
568
|
+
...(config.timeout === undefined ? {} : { timeout: config.timeout }),
|
|
569
|
+
...(config.pubKeyCredParams === undefined
|
|
570
|
+
? {}
|
|
571
|
+
: { pubKeyCredParams: config.pubKeyCredParams }),
|
|
572
|
+
...(config.authenticatorSelection === undefined
|
|
573
|
+
? {}
|
|
574
|
+
: { authenticatorSelection: config.authenticatorSelection }),
|
|
575
|
+
...(config.attestation === undefined
|
|
576
|
+
? {}
|
|
577
|
+
: { attestation: config.attestation }),
|
|
578
|
+
});
|
|
579
|
+
export const passkeyAuthenticationStartHttpOptions = (config) => ({
|
|
580
|
+
relyingPartyId: config.relyingParty.id,
|
|
581
|
+
...(config.timeout === undefined ? {} : { timeout: config.timeout }),
|
|
582
|
+
...(config.userVerification === undefined
|
|
583
|
+
? {}
|
|
584
|
+
: { userVerification: config.userVerification }),
|
|
585
|
+
});
|
|
586
|
+
export const passkeyFinishHttpOptions = (config) => ({
|
|
587
|
+
relyingPartyId: config.relyingParty.id,
|
|
588
|
+
expectedOrigin: config.expectedOrigin,
|
|
589
|
+
...(config.requireUserVerification === undefined
|
|
590
|
+
? {}
|
|
591
|
+
: { requireUserVerification: config.requireUserVerification }),
|
|
592
|
+
});
|
|
593
|
+
export const passkeyAuthenticationSessionInput = ({ finished, payload, }) => ({
|
|
594
|
+
userId: finished.userId,
|
|
595
|
+
authenticationEvents: [
|
|
596
|
+
passkeyEvidence({
|
|
597
|
+
credentialId: CredentialId(finished.credential.id),
|
|
598
|
+
verifiedAt: finished.credential.lastUsedAt ?? finished.credential.createdAt,
|
|
599
|
+
userVerification: finished.userVerification,
|
|
600
|
+
...(finished.authenticatorAttachment === undefined
|
|
601
|
+
? {}
|
|
602
|
+
: { authenticatorAttachment: finished.authenticatorAttachment }),
|
|
603
|
+
...(finished.backedUp === undefined
|
|
604
|
+
? {}
|
|
605
|
+
: { backedUp: finished.backedUp }),
|
|
606
|
+
...(finished.backupEligible === undefined
|
|
607
|
+
? {}
|
|
608
|
+
: { backupEligible: finished.backupEligible }),
|
|
609
|
+
signCount: finished.signCount,
|
|
610
|
+
...(finished.aaguid === undefined ? {} : { aaguid: finished.aaguid }),
|
|
611
|
+
}),
|
|
612
|
+
],
|
|
613
|
+
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
614
|
+
});
|
|
615
|
+
const optionalHttpMetadata = (metadata) => (metadata === undefined ? {} : { metadata });
|
|
616
|
+
export const passkeyRegistrationStartInput = (userId, user, options) => ({
|
|
577
617
|
relyingParty: options.relyingParty,
|
|
578
|
-
userId
|
|
579
|
-
userName:
|
|
580
|
-
userDisplayName:
|
|
618
|
+
userId,
|
|
619
|
+
userName: user.userName,
|
|
620
|
+
userDisplayName: user.userDisplayName,
|
|
581
621
|
...(options.timeout === undefined ? {} : { timeout: options.timeout }),
|
|
582
622
|
...(options.pubKeyCredParams === undefined
|
|
583
623
|
? {}
|
|
@@ -585,8 +625,10 @@ export const passkeyRegistrationStartInput = (payload, options) => ({
|
|
|
585
625
|
...(options.authenticatorSelection === undefined
|
|
586
626
|
? {}
|
|
587
627
|
: { authenticatorSelection: options.authenticatorSelection }),
|
|
588
|
-
...(options.attestation === undefined
|
|
589
|
-
|
|
628
|
+
...(options.attestation === undefined
|
|
629
|
+
? {}
|
|
630
|
+
: { attestation: options.attestation }),
|
|
631
|
+
...optionalHttpMetadata(user.metadata),
|
|
590
632
|
});
|
|
591
633
|
export const passkeyAuthenticationStartInput = (payload, options) => ({
|
|
592
634
|
relyingPartyId: options.relyingPartyId,
|
|
@@ -607,16 +649,16 @@ export const passkeyMfaStartInput = (userId, payload, options) => ({
|
|
|
607
649
|
flowId: payload.flowId,
|
|
608
650
|
},
|
|
609
651
|
});
|
|
610
|
-
export const passkeyRegistrationFinishInput = (payload, options) => ({
|
|
652
|
+
export const passkeyRegistrationFinishInput = (userId, payload, user, options) => ({
|
|
611
653
|
challengeId: payload.challengeId,
|
|
612
|
-
userId
|
|
654
|
+
userId,
|
|
613
655
|
response: payload.credential,
|
|
614
656
|
relyingPartyId: options.relyingPartyId,
|
|
615
657
|
expectedOrigin: options.expectedOrigin,
|
|
616
658
|
...(options.requireUserVerification === undefined
|
|
617
659
|
? {}
|
|
618
660
|
: { requireUserVerification: options.requireUserVerification }),
|
|
619
|
-
...(
|
|
661
|
+
...optionalHttpMetadata(user.metadata),
|
|
620
662
|
});
|
|
621
663
|
export const passkeyAuthenticationFinishInput = (payload, options) => ({
|
|
622
664
|
challengeId: payload.challengeId,
|
|
@@ -629,15 +671,18 @@ export const passkeyAuthenticationFinishInput = (payload, options) => ({
|
|
|
629
671
|
: { requireUserVerification: options.requireUserVerification }),
|
|
630
672
|
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
631
673
|
});
|
|
632
|
-
export const passkeyMfaVerifyInput = (payload, options) => ({
|
|
674
|
+
export const passkeyMfaVerifyInput = (payload, options, expectedUserId) => ({
|
|
633
675
|
challengeId: payload.challengeId,
|
|
634
676
|
response: payload.credential,
|
|
635
|
-
...(
|
|
677
|
+
...(expectedUserId === undefined
|
|
678
|
+
? payload.userId === undefined
|
|
679
|
+
? {}
|
|
680
|
+
: { userId: payload.userId }
|
|
681
|
+
: { userId: expectedUserId }),
|
|
636
682
|
relyingPartyId: options.relyingPartyId,
|
|
637
683
|
expectedOrigin: options.expectedOrigin,
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
: { requireUserVerification: options.requireUserVerification }),
|
|
684
|
+
requireUserVerification: true,
|
|
685
|
+
expectedChallengeMetadata: { flowId: payload.flowId },
|
|
641
686
|
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
642
687
|
});
|
|
643
688
|
export const passkeyCredentialRevokeInput = (userId, payload) => ({
|
|
@@ -650,7 +695,9 @@ const passkeyCredentialInfoHttpBody = (credential) => ({
|
|
|
650
695
|
...(credential.transports === undefined
|
|
651
696
|
? {}
|
|
652
697
|
: { transports: credential.transports }),
|
|
653
|
-
...(credential.backedUp === undefined
|
|
698
|
+
...(credential.backedUp === undefined
|
|
699
|
+
? {}
|
|
700
|
+
: { backedUp: credential.backedUp }),
|
|
654
701
|
createdAt: credential.createdAt,
|
|
655
702
|
...(credential.lastUsedAt === undefined
|
|
656
703
|
? {}
|
|
@@ -658,13 +705,17 @@ const passkeyCredentialInfoHttpBody = (credential) => ({
|
|
|
658
705
|
...(credential.revokedAt === undefined
|
|
659
706
|
? {}
|
|
660
707
|
: { revokedAt: credential.revokedAt }),
|
|
661
|
-
...(credential.metadata === undefined
|
|
708
|
+
...(credential.metadata === undefined
|
|
709
|
+
? {}
|
|
710
|
+
: { metadata: credential.metadata }),
|
|
662
711
|
});
|
|
663
712
|
export const totpEnrollmentStartInput = (userId, payload, options) => ({
|
|
664
713
|
userId,
|
|
665
714
|
issuer: options.issuer,
|
|
666
715
|
accountName: payload.accountName,
|
|
667
|
-
...(options.secretBytes === undefined
|
|
716
|
+
...(options.secretBytes === undefined
|
|
717
|
+
? {}
|
|
718
|
+
: { secretBytes: options.secretBytes }),
|
|
668
719
|
...(options.algorithm === undefined ? {} : { algorithm: options.algorithm }),
|
|
669
720
|
...(options.digits === undefined ? {} : { digits: options.digits }),
|
|
670
721
|
...(options.period === undefined ? {} : { period: options.period }),
|
|
@@ -694,7 +745,9 @@ const totpFactorInfoHttpBody = (factor) => ({
|
|
|
694
745
|
digits: factor.digits,
|
|
695
746
|
period: factor.period,
|
|
696
747
|
createdAt: factor.createdAt,
|
|
697
|
-
...(factor.confirmedAt === undefined
|
|
748
|
+
...(factor.confirmedAt === undefined
|
|
749
|
+
? {}
|
|
750
|
+
: { confirmedAt: factor.confirmedAt }),
|
|
698
751
|
...(factor.lastUsedAt === undefined ? {} : { lastUsedAt: factor.lastUsedAt }),
|
|
699
752
|
...(factor.revokedAt === undefined ? {} : { revokedAt: factor.revokedAt }),
|
|
700
753
|
...(factor.metadata === undefined ? {} : { metadata: factor.metadata }),
|
|
@@ -710,6 +763,9 @@ const totpVerifyResultHttpBody = (result) => ({
|
|
|
710
763
|
? {}
|
|
711
764
|
: { factor: totpFactorInfoHttpBody(result.factor) }),
|
|
712
765
|
...(result.delta === undefined ? {} : { delta: result.delta }),
|
|
766
|
+
...(result.acceptedCounter === undefined
|
|
767
|
+
? {}
|
|
768
|
+
: { acceptedCounter: result.acceptedCounter }),
|
|
713
769
|
});
|
|
714
770
|
export const recoveryCodeGenerateInput = (userId, payload, options = {}) => ({
|
|
715
771
|
userId,
|
|
@@ -718,6 +774,16 @@ export const recoveryCodeGenerateInput = (userId, payload, options = {}) => ({
|
|
|
718
774
|
...(options.groupSize === undefined ? {} : { groupSize: options.groupSize }),
|
|
719
775
|
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
720
776
|
});
|
|
777
|
+
export const recoveryCodeRegenerateInput = (userId, payload, options = {}) => ({
|
|
778
|
+
userId,
|
|
779
|
+
...(options.count === undefined ? {} : { count: options.count }),
|
|
780
|
+
...(options.length === undefined ? {} : { length: options.length }),
|
|
781
|
+
...(options.groupSize === undefined ? {} : { groupSize: options.groupSize }),
|
|
782
|
+
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
783
|
+
...(payload.revokeReason === undefined
|
|
784
|
+
? {}
|
|
785
|
+
: { revokeReason: payload.revokeReason }),
|
|
786
|
+
});
|
|
721
787
|
export const recoveryCodeVerifyInput = (userId, payload) => ({
|
|
722
788
|
userId,
|
|
723
789
|
code: Redacted.make(payload.code),
|
|
@@ -796,7 +862,9 @@ const refreshTokenInfoHttpBody = (refreshToken) => ({
|
|
|
796
862
|
...(refreshToken.reuseDetectedAt === undefined
|
|
797
863
|
? {}
|
|
798
864
|
: { reuseDetectedAt: refreshToken.reuseDetectedAt }),
|
|
799
|
-
...(refreshToken.metadata === undefined
|
|
865
|
+
...(refreshToken.metadata === undefined
|
|
866
|
+
? {}
|
|
867
|
+
: { metadata: refreshToken.metadata }),
|
|
800
868
|
});
|
|
801
869
|
const issuedJwtExpiresAt = (issued) => typeof issued.claims.exp === "number"
|
|
802
870
|
? (issued.claims.exp * 1000)
|
|
@@ -826,9 +894,15 @@ const jwtKeyInfoHttpBody = (result) => ({
|
|
|
826
894
|
keyId: result.key.id,
|
|
827
895
|
alg: result.key.alg,
|
|
828
896
|
status: result.key.status,
|
|
829
|
-
...(result.key.createdAt === undefined
|
|
830
|
-
|
|
831
|
-
|
|
897
|
+
...(result.key.createdAt === undefined
|
|
898
|
+
? {}
|
|
899
|
+
: { createdAt: result.key.createdAt }),
|
|
900
|
+
...(result.key.expiresAt === undefined
|
|
901
|
+
? {}
|
|
902
|
+
: { expiresAt: result.key.expiresAt }),
|
|
903
|
+
...(result.key.metadata === undefined
|
|
904
|
+
? {}
|
|
905
|
+
: { metadata: result.key.metadata }),
|
|
832
906
|
});
|
|
833
907
|
const jwtIntrospectionHttpBody = (result) => result.active
|
|
834
908
|
? {
|
|
@@ -837,15 +911,21 @@ const jwtIntrospectionHttpBody = (result) => result.active
|
|
|
837
911
|
claims: result.claims,
|
|
838
912
|
key: jwtKeyInfoHttpBody(result),
|
|
839
913
|
...(result.jwtId === undefined ? {} : { jwtId: result.jwtId }),
|
|
840
|
-
...(result.expiresAt === undefined
|
|
914
|
+
...(result.expiresAt === undefined
|
|
915
|
+
? {}
|
|
916
|
+
: { expiresAt: result.expiresAt }),
|
|
841
917
|
revoked: false,
|
|
842
918
|
}
|
|
843
919
|
: {
|
|
844
920
|
active: false,
|
|
845
921
|
reason: result.reason,
|
|
846
922
|
...(result.jwtId === undefined ? {} : { jwtId: result.jwtId }),
|
|
847
|
-
...(result.expiresAt === undefined
|
|
848
|
-
|
|
923
|
+
...(result.expiresAt === undefined
|
|
924
|
+
? {}
|
|
925
|
+
: { expiresAt: result.expiresAt }),
|
|
926
|
+
...(result.revokedAt === undefined
|
|
927
|
+
? {}
|
|
928
|
+
: { revokedAt: result.revokedAt }),
|
|
849
929
|
...(result.revokedReason === undefined
|
|
850
930
|
? {}
|
|
851
931
|
: { revokedReason: result.revokedReason }),
|
|
@@ -881,6 +961,10 @@ export const stepUpTotpVerifyInput = (userId, payload, options = {}) => ({
|
|
|
881
961
|
...(options.window === undefined ? {} : { window: options.window }),
|
|
882
962
|
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
883
963
|
});
|
|
964
|
+
export const stepUpPasswordVerifyInput = (payload) => ({
|
|
965
|
+
password: Redacted.make(payload.password),
|
|
966
|
+
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
967
|
+
});
|
|
884
968
|
export const stepUpRecoveryCodeVerifyInput = (userId, payload) => ({
|
|
885
969
|
userId,
|
|
886
970
|
code: Redacted.make(payload.code),
|
|
@@ -899,9 +983,7 @@ export const stepUpPasskeyVerifyInput = (userId, payload, options) => ({
|
|
|
899
983
|
userId,
|
|
900
984
|
relyingPartyId: options.relyingPartyId,
|
|
901
985
|
expectedOrigin: options.expectedOrigin,
|
|
902
|
-
|
|
903
|
-
? {}
|
|
904
|
-
: { requireUserVerification: options.requireUserVerification }),
|
|
986
|
+
requireUserVerification: true,
|
|
905
987
|
...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
|
|
906
988
|
});
|
|
907
989
|
export const loginApprovalApproveInput = (payload) => ({
|
|
@@ -928,58 +1010,6 @@ export const loginNotificationReportInput = (payload) => ({
|
|
|
928
1010
|
secret: Redacted.make(payload.secret),
|
|
929
1011
|
});
|
|
930
1012
|
const webRequestFromHeaders = (headers) => new Request("http://localhost", { headers });
|
|
931
|
-
const firstHeaderValue = (value) => {
|
|
932
|
-
const first = value?.split(",", 1)[0]?.trim();
|
|
933
|
-
return first === "" ? undefined : first;
|
|
934
|
-
};
|
|
935
|
-
const headerNumber = (value) => {
|
|
936
|
-
const parsed = Number(firstHeaderValue(value));
|
|
937
|
-
return Number.isFinite(parsed) ? parsed : undefined;
|
|
938
|
-
};
|
|
939
|
-
const authRequestMetadataOptions = Effect.gen(function* () {
|
|
940
|
-
const config = yield* Effect.serviceOption(AuthHttpApiConfig);
|
|
941
|
-
return Option.isSome(config) ? (config.value.requestMetadata ?? {}) : {};
|
|
942
|
-
});
|
|
943
|
-
const loginRequestContextFromRequest = (request, options) => {
|
|
944
|
-
if (request === undefined) {
|
|
945
|
-
return undefined;
|
|
946
|
-
}
|
|
947
|
-
const metadata = makeAuthRequestMetadata(request, options);
|
|
948
|
-
const trustProxyHeaders = options.trustProxyHeaders ?? false;
|
|
949
|
-
const { headers } = request;
|
|
950
|
-
const country = trustProxyHeaders
|
|
951
|
-
? firstHeaderValue(headers["cf-ipcountry"])
|
|
952
|
-
: undefined;
|
|
953
|
-
const region = trustProxyHeaders
|
|
954
|
-
? firstHeaderValue(headers["cf-region"])
|
|
955
|
-
: undefined;
|
|
956
|
-
const city = trustProxyHeaders
|
|
957
|
-
? firstHeaderValue(headers["cf-ipcity"])
|
|
958
|
-
: undefined;
|
|
959
|
-
const latitude = trustProxyHeaders
|
|
960
|
-
? headerNumber(headers["cf-iplatitude"])
|
|
961
|
-
: undefined;
|
|
962
|
-
const longitude = trustProxyHeaders
|
|
963
|
-
? headerNumber(headers["cf-iplongitude"])
|
|
964
|
-
: undefined;
|
|
965
|
-
const context = {
|
|
966
|
-
...(metadata.ipAddress === undefined
|
|
967
|
-
? {}
|
|
968
|
-
: { ip: String(metadata.ipAddress) }),
|
|
969
|
-
...(metadata.userAgent === undefined
|
|
970
|
-
? {}
|
|
971
|
-
: { userAgent: metadata.userAgent }),
|
|
972
|
-
...(country === undefined ? {} : { country }),
|
|
973
|
-
...(region === undefined ? {} : { region }),
|
|
974
|
-
...(city === undefined ? {} : { city }),
|
|
975
|
-
...(latitude === undefined ? {} : { latitude }),
|
|
976
|
-
...(longitude === undefined ? {} : { longitude }),
|
|
977
|
-
};
|
|
978
|
-
return Object.keys(context).length === 0 ? undefined : context;
|
|
979
|
-
};
|
|
980
|
-
const trustedDeviceTokenFromRequest = (trustedDeviceCookie, request) => trustedDeviceCookie === undefined || request === undefined
|
|
981
|
-
? Effect.succeed(Option.none())
|
|
982
|
-
: trustedDeviceCookie.read(new Request("http://localhost", { headers: request.headers }));
|
|
983
1013
|
const metadataString = (metadata, key) => {
|
|
984
1014
|
const value = metadata?.[key];
|
|
985
1015
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
@@ -988,14 +1018,18 @@ const emailVerifiedClaims = (claims) => {
|
|
|
988
1018
|
const requirements = claims?.requirements?.filter((requirement) => requirement !== "email_verification");
|
|
989
1019
|
return {
|
|
990
1020
|
...claims,
|
|
991
|
-
|
|
1021
|
+
verifiedIdentityKinds: claims?.verifiedIdentityKinds?.includes("email")
|
|
1022
|
+
? claims.verifiedIdentityKinds
|
|
1023
|
+
: [...(claims?.verifiedIdentityKinds ?? []), "email"],
|
|
992
1024
|
...(requirements === undefined ? {} : { requirements }),
|
|
993
1025
|
};
|
|
994
1026
|
};
|
|
995
1027
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
996
1028
|
const metadataNumber = (metadata, key) => {
|
|
997
1029
|
const value = metadata?.[key];
|
|
998
|
-
return typeof value === "number" && Number.isFinite(value)
|
|
1030
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
1031
|
+
? value
|
|
1032
|
+
: undefined;
|
|
999
1033
|
};
|
|
1000
1034
|
const sessionRequestMetadata = (metadata) => {
|
|
1001
1035
|
const value = metadata?.[sessionRequestMetadataKey];
|
|
@@ -1078,40 +1112,37 @@ export const stepUpAuthenticatedHttpBody = (session) => {
|
|
|
1078
1112
|
? {}
|
|
1079
1113
|
: { mfaVerifiedAt: session.mfaVerifiedAt }),
|
|
1080
1114
|
};
|
|
1081
|
-
return session.claims === undefined
|
|
1115
|
+
return session.claims === undefined
|
|
1116
|
+
? body
|
|
1117
|
+
: { ...body, claims: session.claims };
|
|
1082
1118
|
};
|
|
1083
|
-
const
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
: Effect.fail(new AuthInternalError({
|
|
1089
|
-
code: "internal_error",
|
|
1090
|
-
message: "Failed to validate session",
|
|
1091
|
-
}))));
|
|
1092
|
-
if (Option.isNone(tokenOption)) {
|
|
1093
|
-
return Option.none();
|
|
1119
|
+
const provideHandlerAuthRateLimit = (authRateLimit, handler) => ((...args) => handler(...args).pipe(Effect.provideService(AuthRateLimit, authRateLimit)));
|
|
1120
|
+
const provideRequestGuardServices = (dependencies, handler) => ((...args) => {
|
|
1121
|
+
let effect = handler(...args).pipe(Effect.provideService(AuthRateLimit, dependencies.authRateLimit));
|
|
1122
|
+
if (dependencies.botChallengeVerifier !== undefined) {
|
|
1123
|
+
effect = effect.pipe(Effect.provideService(BotChallengeVerifier, dependencies.botChallengeVerifier));
|
|
1094
1124
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1125
|
+
if (dependencies.trustedDeviceCookie !== undefined) {
|
|
1126
|
+
effect = effect.pipe(Effect.provideService(TrustedDeviceCookie, dependencies.trustedDeviceCookie));
|
|
1127
|
+
}
|
|
1128
|
+
if (dependencies.identities !== undefined) {
|
|
1129
|
+
effect = effect.pipe(Effect.provideService(IdentityStore, dependencies.identities));
|
|
1130
|
+
}
|
|
1131
|
+
if (dependencies.sessions !== undefined) {
|
|
1132
|
+
effect = effect.pipe(Effect.provideService(Sessions, dependencies.sessions));
|
|
1133
|
+
}
|
|
1134
|
+
if (dependencies.sessionCookie !== undefined) {
|
|
1135
|
+
effect = effect.pipe(Effect.provideService(SessionCookie, dependencies.sessionCookie));
|
|
1136
|
+
}
|
|
1137
|
+
return effect;
|
|
1101
1138
|
});
|
|
1102
|
-
const readRequiredSession = (dependencies, request) => readOptionalSession(dependencies, request).pipe(Effect.flatMap((sessionOption) => Option.isSome(sessionOption)
|
|
1103
|
-
? Effect.succeed(sessionOption.value)
|
|
1104
|
-
: Effect.fail(new AuthUnauthenticatedError({
|
|
1105
|
-
code: "unauthenticated",
|
|
1106
|
-
message: "Unauthenticated",
|
|
1107
|
-
}))));
|
|
1108
1139
|
const upgradeVerifiedEmailSession = (dependencies, request, verified) => Effect.gen(function* () {
|
|
1109
1140
|
const sessionOption = yield* readOptionalSession(dependencies, request);
|
|
1110
1141
|
if (Option.isNone(sessionOption)) {
|
|
1111
1142
|
return;
|
|
1112
1143
|
}
|
|
1113
1144
|
const session = sessionOption.value.currentSession;
|
|
1114
|
-
if (session.userId !== verified.
|
|
1145
|
+
if (session.userId !== verified.identity.userId) {
|
|
1115
1146
|
return;
|
|
1116
1147
|
}
|
|
1117
1148
|
yield* dependencies.sessions
|
|
@@ -1127,27 +1158,6 @@ const upgradeVerifiedEmailSession = (dependencies, request, verified) => Effect.
|
|
|
1127
1158
|
message: "Failed to update session claims",
|
|
1128
1159
|
}))));
|
|
1129
1160
|
});
|
|
1130
|
-
const startRequiredEmailVerification = (dependencies, result) => Effect.gen(function* () {
|
|
1131
|
-
if (dependencies.emailVerificationFlow === undefined ||
|
|
1132
|
-
!canStartRequiredEmailVerification(result)) {
|
|
1133
|
-
return result;
|
|
1134
|
-
}
|
|
1135
|
-
const input = {
|
|
1136
|
-
userId: result.userId,
|
|
1137
|
-
email: result.email,
|
|
1138
|
-
};
|
|
1139
|
-
const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
|
|
1140
|
-
yield* catchAuthApiRateLimit(authApiRateLimit.emailVerificationStart(input), "Failed to start email verification");
|
|
1141
|
-
yield* dependencies.emailVerificationFlow
|
|
1142
|
-
.start(input)
|
|
1143
|
-
.pipe(Effect.catchTag("EmailVerificationFlowStartError", () => Effect.fail(passwordInternalError("Failed to start email verification"))));
|
|
1144
|
-
return result;
|
|
1145
|
-
});
|
|
1146
|
-
const rateLimited = (retryAfter) => new AuthRateLimitedError({
|
|
1147
|
-
code: "rate_limited",
|
|
1148
|
-
message: "Too many authentication attempts",
|
|
1149
|
-
retryAfter,
|
|
1150
|
-
});
|
|
1151
1161
|
const passwordInternalError = (message) => new AuthInternalError({
|
|
1152
1162
|
code: "internal_error",
|
|
1153
1163
|
message,
|
|
@@ -1192,7 +1202,8 @@ const oauthInternalError = (message = "Failed to complete OAuth request") => new
|
|
|
1192
1202
|
code: "internal_error",
|
|
1193
1203
|
message,
|
|
1194
1204
|
});
|
|
1195
|
-
const oauthHookHttpError = (error, internalMessage) => error instanceof AuthBadRequestError ||
|
|
1205
|
+
const oauthHookHttpError = (error, internalMessage) => error instanceof AuthBadRequestError ||
|
|
1206
|
+
error instanceof AuthUnauthenticatedError
|
|
1196
1207
|
? error
|
|
1197
1208
|
: oauthInternalError(internalMessage);
|
|
1198
1209
|
const oauthLinkConfirmationHttpError = (error, internalMessage) => error.message === "OAuth provider account is already linked to this user" ||
|
|
@@ -1211,15 +1222,122 @@ const passkeyBadRequest = (message = "Invalid passkey request") => new AuthBadRe
|
|
|
1211
1222
|
code: "bad_request",
|
|
1212
1223
|
message,
|
|
1213
1224
|
});
|
|
1225
|
+
const userMetadataString = (user, key) => {
|
|
1226
|
+
const value = user.metadata?.[key];
|
|
1227
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
1228
|
+
};
|
|
1229
|
+
export const makePasskeyRegistrationUserResolver = (dependencies) => Effect.fn("auth.http.passkey.registration_user.resolve")(function* (input) {
|
|
1230
|
+
const userOption = yield* dependencies.users
|
|
1231
|
+
.findById(input.currentSession.userId)
|
|
1232
|
+
.pipe(Effect.mapError(() => passkeyInternalError("Failed to load passkey registration user")));
|
|
1233
|
+
if (Option.isNone(userOption)) {
|
|
1234
|
+
return yield* passkeyBadRequest("Passkey registration user not found");
|
|
1235
|
+
}
|
|
1236
|
+
const user = userOption.value;
|
|
1237
|
+
const identities = yield* dependencies.identities
|
|
1238
|
+
.listByUser({ userId: user.id })
|
|
1239
|
+
.pipe(Effect.mapError(() => passkeyInternalError("Failed to load passkey registration identity")));
|
|
1240
|
+
const loginIdentity = identities.find((identity) => identity.isPrimaryLogin) ?? identities[0];
|
|
1241
|
+
if (loginIdentity === undefined) {
|
|
1242
|
+
return yield* passkeyBadRequest("Passkey registration identity not found");
|
|
1243
|
+
}
|
|
1244
|
+
const displayName = userMetadataString(user, "displayName") ??
|
|
1245
|
+
userMetadataString(user, "name") ??
|
|
1246
|
+
loginIdentity.value;
|
|
1247
|
+
return {
|
|
1248
|
+
userName: loginIdentity.value,
|
|
1249
|
+
userDisplayName: displayName,
|
|
1250
|
+
};
|
|
1251
|
+
});
|
|
1214
1252
|
const passkeyVerificationHttpError = (error) => error.message === "Failed to load passkey credential" ||
|
|
1215
1253
|
error.message === "Failed to store passkey credential" ||
|
|
1216
1254
|
error.message === "Failed to update passkey credential" ||
|
|
1217
1255
|
error.message === "Failed to generate passkey credential record id"
|
|
1218
1256
|
? passkeyInternalError()
|
|
1219
1257
|
: passkeyBadRequest();
|
|
1258
|
+
export const identityHttpError = (error) => {
|
|
1259
|
+
if (error instanceof IdentityMutationDeniedError) {
|
|
1260
|
+
return new AuthPolicyDeniedError({
|
|
1261
|
+
code: "policy_denied",
|
|
1262
|
+
message: "Identity mutation denied",
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1265
|
+
if (error instanceof LastLoginIdentityError) {
|
|
1266
|
+
return new AuthPolicyDeniedError({
|
|
1267
|
+
code: "policy_denied",
|
|
1268
|
+
message: "Cannot remove the last login identity",
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
if (error instanceof IdentityAlreadyExistsError) {
|
|
1272
|
+
return new AuthIdentityAlreadyRegisteredError({
|
|
1273
|
+
code: "identity_already_registered",
|
|
1274
|
+
message: "Identity is unavailable",
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
if (error instanceof IdentityNotFoundError ||
|
|
1278
|
+
error instanceof IdentityOwnershipError ||
|
|
1279
|
+
error instanceof IdentityInactiveError) {
|
|
1280
|
+
return new AuthBadRequestError({
|
|
1281
|
+
code: "bad_request",
|
|
1282
|
+
message: "Invalid identity request",
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
if (error instanceof IdentityConcurrentModificationError ||
|
|
1286
|
+
error instanceof IdentityNotLoginEligibleError ||
|
|
1287
|
+
error instanceof IdentityUserNotActiveError) {
|
|
1288
|
+
return new AuthBadRequestError({
|
|
1289
|
+
code: "bad_request",
|
|
1290
|
+
message: "Identity could not be updated",
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
if (error instanceof IdentityManagementStorageError ||
|
|
1294
|
+
error instanceof IdentityIdGenerationError) {
|
|
1295
|
+
return new AuthInternalError({
|
|
1296
|
+
code: "internal_error",
|
|
1297
|
+
message: "Failed to complete identity request",
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
if (error instanceof EmailRiskProviderUnavailableError) {
|
|
1301
|
+
return new AuthInternalError({
|
|
1302
|
+
code: "internal_error",
|
|
1303
|
+
message: "Failed to complete identity request",
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
return new AuthBadRequestError({
|
|
1307
|
+
code: "bad_request",
|
|
1308
|
+
message: "Invalid identity request",
|
|
1309
|
+
});
|
|
1310
|
+
};
|
|
1220
1311
|
const passkeyCredentialManagementHttpError = (error) => error.message === "Passkey credential not found"
|
|
1221
1312
|
? passkeyBadRequest("Invalid passkey credential")
|
|
1222
1313
|
: passkeyInternalError("Failed to update passkey credentials");
|
|
1314
|
+
const strongFactorRemovalPolicyHttpError = (error) => {
|
|
1315
|
+
switch (error.reason) {
|
|
1316
|
+
case "factor_not_found": {
|
|
1317
|
+
return new AuthBadRequestError({
|
|
1318
|
+
code: "bad_request",
|
|
1319
|
+
message: "Invalid strong factor removal request",
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
case "last_strong_factor": {
|
|
1323
|
+
return new AuthPolicyDeniedError({
|
|
1324
|
+
code: "policy_denied",
|
|
1325
|
+
message: "Cannot remove the last active strong factor",
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
case "inventory_unavailable": {
|
|
1329
|
+
return new AuthInternalError({
|
|
1330
|
+
code: "internal_error",
|
|
1331
|
+
message: "Failed to check strong factor removal policy",
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
const requireCanRemoveStrongFactor = (policy, input) => policy === undefined
|
|
1337
|
+
? Effect.void
|
|
1338
|
+
: policy
|
|
1339
|
+
.requireCanRemove(input)
|
|
1340
|
+
.pipe(Effect.mapError(strongFactorRemovalPolicyHttpError));
|
|
1223
1341
|
const totpInternalError = (message = "Failed to complete TOTP request") => new AuthInternalError({
|
|
1224
1342
|
code: "internal_error",
|
|
1225
1343
|
message,
|
|
@@ -1293,7 +1411,9 @@ const jwtBadRequest = (message = "Invalid JWT request") => new AuthBadRequestErr
|
|
|
1293
1411
|
code: "bad_request",
|
|
1294
1412
|
message,
|
|
1295
1413
|
});
|
|
1296
|
-
const jwtRevocationHttpError = (error) => error.message === "JWT ID must not be empty"
|
|
1414
|
+
const jwtRevocationHttpError = (error) => error.message === "JWT ID must not be empty"
|
|
1415
|
+
? jwtBadRequest()
|
|
1416
|
+
: jwtInternalError();
|
|
1297
1417
|
const mfaInternalError = (message = "Failed to complete MFA request") => new AuthInternalError({
|
|
1298
1418
|
code: "internal_error",
|
|
1299
1419
|
message,
|
|
@@ -1306,11 +1426,8 @@ const mfaInvalidCredentials = () => new AuthInvalidCredentialsError({
|
|
|
1306
1426
|
code: "invalid_credentials",
|
|
1307
1427
|
message: "Invalid MFA code",
|
|
1308
1428
|
});
|
|
1309
|
-
const
|
|
1310
|
-
|
|
1311
|
-
message: reason ?? "MFA policy denied the request",
|
|
1312
|
-
});
|
|
1313
|
-
const authFlowMfaHttpError = (error) => error._tag === "AuthFlowStateError" ? mfaBadRequest() : mfaInternalError();
|
|
1429
|
+
const authFlowMfaHttpFailure = (error) => customEvidencePolicyHttpFailure(error, "Failed to complete MFA request") ??
|
|
1430
|
+
Effect.fail(error._tag === "AuthFlowStateError" ? mfaBadRequest() : mfaInternalError());
|
|
1314
1431
|
const stepUpInternalError = (message = "Failed to complete step-up request") => new AuthInternalError({
|
|
1315
1432
|
code: "internal_error",
|
|
1316
1433
|
message,
|
|
@@ -1327,6 +1444,10 @@ const stepUpPolicyDenied = (message = "Step-up policy denied the request") => ne
|
|
|
1327
1444
|
code: "policy_denied",
|
|
1328
1445
|
message,
|
|
1329
1446
|
});
|
|
1447
|
+
const stepUpRotationHttpFailure = (error) => {
|
|
1448
|
+
const policyFailure = customEvidencePolicyHttpFailure(error, "Failed to upgrade current session");
|
|
1449
|
+
return policyFailure ?? Effect.fail(stepUpInvalidCredentials());
|
|
1450
|
+
};
|
|
1330
1451
|
const trustedDeviceSetCookies = (dependencies) => Effect.gen(function* () {
|
|
1331
1452
|
if (!dependencies.rememberDevice ||
|
|
1332
1453
|
dependencies.trustedDevice === undefined ||
|
|
@@ -1341,144 +1462,37 @@ const trustedDeviceSetCookies = (dependencies) => Effect.gen(function* () {
|
|
|
1341
1462
|
.pipe(Effect.mapError(() => passwordInternalError("Failed to remember trusted device")));
|
|
1342
1463
|
return [cookie];
|
|
1343
1464
|
});
|
|
1344
|
-
const catchAuthApiRateLimit = (effect, internalMessage) => effect.pipe(Effect.catchTag("RateLimitExceededError", (error) => Effect.fail(rateLimited(error.retryAfter))), Effect.catchTag("RateLimitStoreError", () => Effect.fail(passwordInternalError(internalMessage))), Effect.catchTag("PrivacyError", () => Effect.fail(passwordInternalError(internalMessage))));
|
|
1345
1465
|
export class AdminSessionAuthorization extends Context.Service()("auth/AdminSessionAuthorization") {
|
|
1346
1466
|
}
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
})(AdminSessionAuthorization || (AdminSessionAuthorization = {}));
|
|
1467
|
+
export class AdminPermissionDefinitionAuthorization extends Context.Service()("auth/AdminPermissionDefinitionAuthorization") {
|
|
1468
|
+
}
|
|
1350
1469
|
export class AdminSecurityTimelineAuthorization extends Context.Service()("auth/AdminSecurityTimelineAuthorization") {
|
|
1351
1470
|
}
|
|
1352
|
-
(function (AdminSecurityTimelineAuthorization) {
|
|
1353
|
-
AdminSecurityTimelineAuthorization.make = (service) => AdminSecurityTimelineAuthorization.of(service);
|
|
1354
|
-
})(AdminSecurityTimelineAuthorization || (AdminSecurityTimelineAuthorization = {}));
|
|
1355
1471
|
export class AdminTrustedDeviceAuthorization extends Context.Service()("auth/AdminTrustedDeviceAuthorization") {
|
|
1356
1472
|
}
|
|
1357
|
-
(function (AdminTrustedDeviceAuthorization) {
|
|
1358
|
-
AdminTrustedDeviceAuthorization.make = (service) => AdminTrustedDeviceAuthorization.of(service);
|
|
1359
|
-
})(AdminTrustedDeviceAuthorization || (AdminTrustedDeviceAuthorization = {}));
|
|
1360
1473
|
export class OidcDiscoveryMetadata extends Context.Service()("auth/OidcDiscoveryMetadata") {
|
|
1361
1474
|
}
|
|
1362
|
-
(
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
export const OidcDiscoveryMetadataLive = (metadata) => Layer.succeed(OidcDiscoveryMetadata, OidcDiscoveryMetadata.make({ load: () => Effect.succeed(metadata) }));
|
|
1366
|
-
export const makePasswordSignInHandler = (dependencies) => Effect.fn("auth.http.password.sign_in")(function* ({ payload, request, }) {
|
|
1367
|
-
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.sign_in");
|
|
1368
|
-
const trustedDeviceToken = yield* trustedDeviceTokenFromRequest(dependencies.trustedDeviceCookie, request).pipe(Effect.mapError(() => passwordInternalError("Failed to read trusted device cookie")));
|
|
1369
|
-
const requestMetadataOptions = yield* authRequestMetadataOptions;
|
|
1370
|
-
const requestContext = loginRequestContextFromRequest(request, requestMetadataOptions);
|
|
1371
|
-
const input = passwordSignInInput(payload, Option.isSome(trustedDeviceToken) ? trustedDeviceToken.value : undefined, requestContext);
|
|
1372
|
-
const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
|
|
1373
|
-
yield* catchAuthApiRateLimit(authApiRateLimit.passwordSignIn(input), "Failed to sign in with password");
|
|
1374
|
-
const result = yield* dependencies.password.signIn(input).pipe(Effect.catchTag("StorageError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("PasswordHashError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("TrustedDeviceError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("LoginRiskError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("SessionCreateError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("AuthFlowStateError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("LoginApprovalReviewError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("LoginApprovalFlowStartError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))));
|
|
1375
|
-
yield* startRequiredEmailVerification(dependencies, result);
|
|
1376
|
-
return yield* dependencies.authHttp.commitPasswordSignInResult(result);
|
|
1377
|
-
});
|
|
1378
|
-
export const makePasswordSignUpHandler = (dependencies) => Effect.fn("auth.http.password.sign_up")(function* ({ payload, request, }) {
|
|
1379
|
-
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.sign_up");
|
|
1380
|
-
const requestMetadataOptions = yield* authRequestMetadataOptions;
|
|
1381
|
-
const input = passwordSignUpInput(payload, loginRequestContextFromRequest(request, requestMetadataOptions));
|
|
1382
|
-
const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
|
|
1383
|
-
yield* catchAuthApiRateLimit(authApiRateLimit.passwordSignUp(input), "Failed to sign up with password");
|
|
1384
|
-
const result = yield* dependencies.registration.signUp(input).pipe(Effect.catchTag("EmailAlreadyRegisteredError", () => Effect.fail(new AuthEmailAlreadyRegisteredError({
|
|
1385
|
-
code: "email_already_registered",
|
|
1386
|
-
message: "Email is already registered",
|
|
1387
|
-
}))), Effect.catchTag("StorageError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("PasswordHashError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("CryptoError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("TrustedDeviceError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("LoginRiskError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("SessionCreateError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("AuthFlowStateError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("LoginApprovalReviewError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("LoginApprovalFlowStartError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))));
|
|
1388
|
-
yield* startRequiredEmailVerification(dependencies, result);
|
|
1389
|
-
return yield* dependencies.authHttp.commitPasswordSignUpResult(result);
|
|
1390
|
-
});
|
|
1391
|
-
export const makePasswordResetStartHandler = (dependencies) => Effect.fn("auth.http.password.reset_start")(function* ({ payload, }) {
|
|
1392
|
-
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.reset_start");
|
|
1393
|
-
const input = passwordResetStartInput(payload);
|
|
1394
|
-
const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
|
|
1395
|
-
yield* catchAuthApiRateLimit(authApiRateLimit.passwordResetStart(input), "Failed to start password reset");
|
|
1396
|
-
yield* dependencies.passwordReset.start(input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
1397
|
-
code: "internal_error",
|
|
1398
|
-
message: "Failed to start password reset",
|
|
1399
|
-
})));
|
|
1400
|
-
return HttpServerResponse.empty({ status: 204 });
|
|
1401
|
-
});
|
|
1402
|
-
export const makePasswordResetVerifyHandler = (dependencies) => Effect.fn("auth.http.password.reset_verify")(function* ({ payload, }) {
|
|
1403
|
-
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.reset_verify");
|
|
1404
|
-
yield* dependencies.passwordReset
|
|
1405
|
-
.verify(passwordResetVerifyInput(payload))
|
|
1406
|
-
.pipe(Effect.mapError(() => new AuthBadRequestError({
|
|
1407
|
-
code: "bad_request",
|
|
1408
|
-
message: "Invalid password reset request",
|
|
1409
|
-
})));
|
|
1410
|
-
return HttpServerResponse.empty({ status: 204 });
|
|
1411
|
-
});
|
|
1412
|
-
const passwordManagementError = (error) => error.reason === "internal"
|
|
1413
|
-
? new AuthInternalError({
|
|
1414
|
-
code: "internal_error",
|
|
1415
|
-
message: "Failed to update password",
|
|
1416
|
-
})
|
|
1417
|
-
: new AuthBadRequestError({
|
|
1418
|
-
code: "bad_request",
|
|
1419
|
-
message: "Invalid password update request",
|
|
1420
|
-
});
|
|
1421
|
-
export const makePasswordSetHandler = (dependencies) => Effect.fn("auth.http.password.set")(function* ({ payload, request, }) {
|
|
1422
|
-
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.set");
|
|
1423
|
-
const current = yield* readRequiredSession(dependencies, request);
|
|
1424
|
-
yield* dependencies.passwordManagement
|
|
1425
|
-
.set(passwordSetInput(current.currentSession.userId, payload))
|
|
1426
|
-
.pipe(Effect.mapError(passwordManagementError));
|
|
1427
|
-
return HttpServerResponse.empty({ status: 204 });
|
|
1428
|
-
});
|
|
1429
|
-
export const makePasswordChangeHandler = (dependencies) => Effect.fn("auth.http.password.change")(function* ({ payload, request, }) {
|
|
1430
|
-
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.change");
|
|
1431
|
-
const current = yield* readRequiredSession(dependencies, request);
|
|
1432
|
-
yield* dependencies.passwordManagement
|
|
1433
|
-
.change(passwordChangeInput(current.currentSession.userId, payload))
|
|
1434
|
-
.pipe(Effect.mapError(passwordManagementError));
|
|
1435
|
-
return HttpServerResponse.empty({ status: 204 });
|
|
1436
|
-
});
|
|
1437
|
-
export const makeCurrentSessionHandler = (dependencies) => Effect.fn("auth.http.session.current")(function* ({ request, }) {
|
|
1475
|
+
export const OidcDiscoveryMetadataLive = (metadata) => Layer.succeed(OidcDiscoveryMetadata, OidcDiscoveryMetadata.of({ load: () => Effect.succeed(metadata) }));
|
|
1476
|
+
export const makeCurrentSessionHandler = (dependencies) => Effect.fn("auth.http.session.current")(function* (handlerRequest) {
|
|
1477
|
+
const { request } = handlerRequest;
|
|
1438
1478
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.current");
|
|
1439
|
-
const
|
|
1440
|
-
.read(webRequestFromHeaders(request.headers))
|
|
1441
|
-
.pipe(Effect.mapError((error) => error.cause === undefined
|
|
1442
|
-
? new AuthUnauthenticatedError({
|
|
1443
|
-
code: "unauthenticated",
|
|
1444
|
-
message: "Unauthenticated",
|
|
1445
|
-
})
|
|
1446
|
-
: new AuthInternalError({
|
|
1447
|
-
code: "internal_error",
|
|
1448
|
-
message: "Failed to validate session",
|
|
1449
|
-
})));
|
|
1450
|
-
if (Option.isNone(tokenOption)) {
|
|
1451
|
-
return yield* new AuthUnauthenticatedError({
|
|
1452
|
-
code: "unauthenticated",
|
|
1453
|
-
message: "Unauthenticated",
|
|
1454
|
-
});
|
|
1455
|
-
}
|
|
1456
|
-
const session = yield* dependencies.sessions
|
|
1457
|
-
.validate(tokenOption.value)
|
|
1458
|
-
.pipe(Effect.mapError((error) => error.cause === undefined
|
|
1459
|
-
? new AuthUnauthenticatedError({
|
|
1460
|
-
code: "unauthenticated",
|
|
1461
|
-
message: "Unauthenticated",
|
|
1462
|
-
})
|
|
1463
|
-
: new AuthInternalError({
|
|
1464
|
-
code: "internal_error",
|
|
1465
|
-
message: "Failed to validate session",
|
|
1466
|
-
})));
|
|
1479
|
+
const session = yield* readRequiredSession(dependencies, request);
|
|
1467
1480
|
return yield* dependencies.authHttp.commitCurrentSession(session);
|
|
1468
1481
|
});
|
|
1469
1482
|
export const makeRefreshSessionHandler = (dependencies) => Effect.fn("auth.http.session.refresh")(function* ({ request, }) {
|
|
1470
1483
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.refresh");
|
|
1471
1484
|
const tokenOption = yield* dependencies.sessionCookie
|
|
1472
1485
|
.read(webRequestFromHeaders(request.headers))
|
|
1473
|
-
.pipe(Effect.
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1486
|
+
.pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to validate session") ??
|
|
1487
|
+
Effect.fail(error.cause === undefined
|
|
1488
|
+
? new AuthUnauthenticatedError({
|
|
1489
|
+
code: "unauthenticated",
|
|
1490
|
+
message: "Unauthenticated",
|
|
1491
|
+
})
|
|
1492
|
+
: new AuthInternalError({
|
|
1493
|
+
code: "internal_error",
|
|
1494
|
+
message: "Failed to validate session",
|
|
1495
|
+
}))));
|
|
1482
1496
|
if (Option.isNone(tokenOption)) {
|
|
1483
1497
|
return yield* new AuthUnauthenticatedError({
|
|
1484
1498
|
code: "unauthenticated",
|
|
@@ -1487,51 +1501,36 @@ export const makeRefreshSessionHandler = (dependencies) => Effect.fn("auth.http.
|
|
|
1487
1501
|
}
|
|
1488
1502
|
const session = yield* dependencies.sessions
|
|
1489
1503
|
.refresh(tokenOption.value)
|
|
1490
|
-
.pipe(Effect.
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1504
|
+
.pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to refresh session") ??
|
|
1505
|
+
Effect.fail(error.cause === undefined
|
|
1506
|
+
? new AuthUnauthenticatedError({
|
|
1507
|
+
code: "unauthenticated",
|
|
1508
|
+
message: "Unauthenticated",
|
|
1509
|
+
})
|
|
1510
|
+
: new AuthInternalError({
|
|
1511
|
+
code: "internal_error",
|
|
1512
|
+
message: "Failed to refresh session",
|
|
1513
|
+
}))));
|
|
1499
1514
|
return yield* dependencies.authHttp.commitSessionRefreshed(session);
|
|
1500
1515
|
});
|
|
1501
1516
|
export const makeLogoutHandler = (dependencies) => Effect.fn("auth.http.session.logout")(function* ({ request, }) {
|
|
1502
1517
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.logout");
|
|
1503
|
-
const
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1518
|
+
const sessionOption = yield* readOptionalSession(dependencies, request);
|
|
1519
|
+
if (Option.isSome(sessionOption)) {
|
|
1520
|
+
yield* dependencies.sessions
|
|
1521
|
+
.revoke({
|
|
1522
|
+
sessionId: sessionOption.value.currentSession.sessionId,
|
|
1523
|
+
reason: "logout",
|
|
1524
|
+
})
|
|
1525
|
+
.pipe(Effect.mapError(() => new AuthInternalError({
|
|
1508
1526
|
code: "internal_error",
|
|
1509
|
-
message: "Failed to
|
|
1510
|
-
})))
|
|
1511
|
-
if (Option.isSome(tokenOption)) {
|
|
1512
|
-
const sessionOption = yield* dependencies.sessions
|
|
1513
|
-
.validate(tokenOption.value)
|
|
1514
|
-
.pipe(Effect.map(Option.some), Effect.catchTag("SessionValidateError", (error) => error.cause === undefined
|
|
1515
|
-
? Effect.succeed(Option.none())
|
|
1516
|
-
: Effect.fail(new AuthInternalError({
|
|
1517
|
-
code: "internal_error",
|
|
1518
|
-
message: "Failed to validate session",
|
|
1519
|
-
}))));
|
|
1520
|
-
if (Option.isSome(sessionOption)) {
|
|
1521
|
-
yield* dependencies.sessions
|
|
1522
|
-
.revoke({
|
|
1523
|
-
sessionId: sessionOption.value.currentSession.sessionId,
|
|
1524
|
-
reason: "logout",
|
|
1525
|
-
})
|
|
1526
|
-
.pipe(Effect.mapError(() => new AuthInternalError({
|
|
1527
|
-
code: "internal_error",
|
|
1528
|
-
message: "Failed to revoke session",
|
|
1529
|
-
})));
|
|
1530
|
-
}
|
|
1527
|
+
message: "Failed to revoke session",
|
|
1528
|
+
})));
|
|
1531
1529
|
}
|
|
1532
1530
|
return yield* dependencies.authHttp.commitSessionCleared();
|
|
1533
1531
|
});
|
|
1534
|
-
export const makeListSessionsHandler = (dependencies) => Effect.fn("auth.http.session.list")(function* (
|
|
1532
|
+
export const makeListSessionsHandler = (dependencies) => Effect.fn("auth.http.session.list")(function* (handlerRequest) {
|
|
1533
|
+
const { request } = handlerRequest;
|
|
1535
1534
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.list");
|
|
1536
1535
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1537
1536
|
const sessions = yield* dependencies.sessions
|
|
@@ -1544,7 +1543,8 @@ export const makeListSessionsHandler = (dependencies) => Effect.fn("auth.http.se
|
|
|
1544
1543
|
sessions: sessions.map((session) => activeSessionBody(session, current.currentSession.sessionId)),
|
|
1545
1544
|
};
|
|
1546
1545
|
});
|
|
1547
|
-
export const makeRevokeSessionHandler = (dependencies) => Effect.fn("auth.http.session.revoke")(function* (
|
|
1546
|
+
export const makeRevokeSessionHandler = (dependencies) => Effect.fn("auth.http.session.revoke")(function* (handlerRequest) {
|
|
1547
|
+
const { payload, request } = handlerRequest;
|
|
1548
1548
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.revoke");
|
|
1549
1549
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1550
1550
|
yield* dependencies.sessions
|
|
@@ -1561,7 +1561,8 @@ export const makeRevokeSessionHandler = (dependencies) => Effect.fn("auth.http.s
|
|
|
1561
1561
|
? yield* dependencies.authHttp.commitSessionCleared()
|
|
1562
1562
|
: HttpServerResponse.empty({ status: 204 });
|
|
1563
1563
|
});
|
|
1564
|
-
export const makeRevokeOtherSessionsHandler = (dependencies) => Effect.fn("auth.http.session.revoke_others")(function* (
|
|
1564
|
+
export const makeRevokeOtherSessionsHandler = (dependencies) => Effect.fn("auth.http.session.revoke_others")(function* (handlerRequest) {
|
|
1565
|
+
const { request } = handlerRequest;
|
|
1565
1566
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.revoke_others");
|
|
1566
1567
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1567
1568
|
yield* dependencies.sessions
|
|
@@ -1576,7 +1577,8 @@ export const makeRevokeOtherSessionsHandler = (dependencies) => Effect.fn("auth.
|
|
|
1576
1577
|
})));
|
|
1577
1578
|
return HttpServerResponse.empty({ status: 204 });
|
|
1578
1579
|
});
|
|
1579
|
-
export const makeAdminSessionListHandler = (dependencies) => Effect.fn("auth.http.admin_session.list")(function* (
|
|
1580
|
+
export const makeAdminSessionListHandler = (dependencies) => Effect.fn("auth.http.admin_session.list")(function* (handlerRequest) {
|
|
1581
|
+
const { query, request } = handlerRequest;
|
|
1580
1582
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_session.list");
|
|
1581
1583
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1582
1584
|
yield* dependencies.authorization.authorize({
|
|
@@ -1593,7 +1595,8 @@ export const makeAdminSessionListHandler = (dependencies) => Effect.fn("auth.htt
|
|
|
1593
1595
|
})));
|
|
1594
1596
|
return { sessions: sessions.map(adminSessionHttpBody) };
|
|
1595
1597
|
});
|
|
1596
|
-
export const makeAdminSessionRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke")(function* (
|
|
1598
|
+
export const makeAdminSessionRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke")(function* (handlerRequest) {
|
|
1599
|
+
const { payload, request } = handlerRequest;
|
|
1597
1600
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_session.revoke");
|
|
1598
1601
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1599
1602
|
yield* dependencies.authorization.authorize({
|
|
@@ -1615,7 +1618,8 @@ export const makeAdminSessionRevokeHandler = (dependencies) => Effect.fn("auth.h
|
|
|
1615
1618
|
})));
|
|
1616
1619
|
return HttpServerResponse.empty({ status: 204 });
|
|
1617
1620
|
});
|
|
1618
|
-
export const makeAdminSessionRevokeAllHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke_all")(function* (
|
|
1621
|
+
export const makeAdminSessionRevokeAllHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke_all")(function* (handlerRequest) {
|
|
1622
|
+
const { payload, request } = handlerRequest;
|
|
1619
1623
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_session.revoke_all");
|
|
1620
1624
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1621
1625
|
yield* dependencies.authorization.authorize({
|
|
@@ -1630,6 +1634,213 @@ export const makeAdminSessionRevokeAllHandler = (dependencies) => Effect.fn("aut
|
|
|
1630
1634
|
})));
|
|
1631
1635
|
return HttpServerResponse.empty({ status: 204 });
|
|
1632
1636
|
});
|
|
1637
|
+
export const adminPermissionDefinitionHttpBody = (definition) => ({
|
|
1638
|
+
id: definition.id,
|
|
1639
|
+
...(definition.description === undefined
|
|
1640
|
+
? {}
|
|
1641
|
+
: { description: definition.description }),
|
|
1642
|
+
...(definition.scopeType === undefined
|
|
1643
|
+
? {}
|
|
1644
|
+
: { scopeType: definition.scopeType }),
|
|
1645
|
+
createdAt: definition.createdAt,
|
|
1646
|
+
updatedAt: definition.updatedAt,
|
|
1647
|
+
...(definition.disabledAt === undefined
|
|
1648
|
+
? {}
|
|
1649
|
+
: { disabledAt: definition.disabledAt }),
|
|
1650
|
+
...(definition.deletedAt === undefined
|
|
1651
|
+
? {}
|
|
1652
|
+
: { deletedAt: definition.deletedAt }),
|
|
1653
|
+
});
|
|
1654
|
+
const adminPermissionDefinitionHttpError = (error) => {
|
|
1655
|
+
switch (error.reason) {
|
|
1656
|
+
case "storage": {
|
|
1657
|
+
return new AuthInternalError({
|
|
1658
|
+
code: "internal_error",
|
|
1659
|
+
message: "Failed to complete permission definition request",
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
case "not_found": {
|
|
1663
|
+
return new AuthNotFoundError({
|
|
1664
|
+
code: "not_found",
|
|
1665
|
+
message: "Permission definition not found",
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
case "already_exists":
|
|
1669
|
+
case "concurrent_modification":
|
|
1670
|
+
case "deleted":
|
|
1671
|
+
case "inactive": {
|
|
1672
|
+
return new AuthConflictError({
|
|
1673
|
+
code: "conflict",
|
|
1674
|
+
message: "Permission definition conflicts with its current state",
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
case "invalid_input": {
|
|
1678
|
+
return new AuthBadRequestError({
|
|
1679
|
+
code: "bad_request",
|
|
1680
|
+
message: "Invalid permission definition request",
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
};
|
|
1685
|
+
export const adminPermissionDefinitionCreateOperation = Effect.fn("auth.http.admin_permission_definition.create")(function* (handlerRequest) {
|
|
1686
|
+
const { payload, request } = handlerRequest;
|
|
1687
|
+
const administration = yield* PermissionAdministration;
|
|
1688
|
+
const authorization = yield* AdminPermissionDefinitionAuthorization;
|
|
1689
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.create");
|
|
1690
|
+
const current = yield* requireSession(request);
|
|
1691
|
+
yield* authorization.authorize({
|
|
1692
|
+
currentSession: current.currentSession,
|
|
1693
|
+
action: "create",
|
|
1694
|
+
request,
|
|
1695
|
+
permissionId: payload.id,
|
|
1696
|
+
...(payload.scopeType === undefined
|
|
1697
|
+
? {}
|
|
1698
|
+
: { scopeType: payload.scopeType }),
|
|
1699
|
+
});
|
|
1700
|
+
const definition = yield* administration
|
|
1701
|
+
.createPermissionDefinition(payload)
|
|
1702
|
+
.pipe(Effect.mapError(adminPermissionDefinitionHttpError));
|
|
1703
|
+
yield* Audit.emit({
|
|
1704
|
+
type: "auth.permission_definition.created",
|
|
1705
|
+
actor: Audit.AuditActor.user({
|
|
1706
|
+
userId: current.currentSession.userId,
|
|
1707
|
+
sessionId: current.currentSession.sessionId,
|
|
1708
|
+
}),
|
|
1709
|
+
permissionId: definition.id,
|
|
1710
|
+
...(definition.scopeType === undefined
|
|
1711
|
+
? {}
|
|
1712
|
+
: { scopeType: definition.scopeType }),
|
|
1713
|
+
occurredAt: definition.updatedAt,
|
|
1714
|
+
});
|
|
1715
|
+
return adminPermissionDefinitionHttpBody(definition);
|
|
1716
|
+
});
|
|
1717
|
+
export const adminPermissionDefinitionGetOperation = Effect.fn("auth.http.admin_permission_definition.get")(function* (handlerRequest) {
|
|
1718
|
+
const { query, request } = handlerRequest;
|
|
1719
|
+
const administration = yield* PermissionAdministration;
|
|
1720
|
+
const authorization = yield* AdminPermissionDefinitionAuthorization;
|
|
1721
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.get");
|
|
1722
|
+
const current = yield* requireSession(request);
|
|
1723
|
+
yield* authorization.authorize({
|
|
1724
|
+
currentSession: current.currentSession,
|
|
1725
|
+
action: "get",
|
|
1726
|
+
request,
|
|
1727
|
+
permissionId: query.id,
|
|
1728
|
+
});
|
|
1729
|
+
const definition = yield* administration
|
|
1730
|
+
.getPermissionDefinition(query.id)
|
|
1731
|
+
.pipe(Effect.mapError(adminPermissionDefinitionHttpError));
|
|
1732
|
+
if (Option.isNone(definition)) {
|
|
1733
|
+
return yield* new AuthNotFoundError({
|
|
1734
|
+
code: "not_found",
|
|
1735
|
+
message: "Permission definition not found",
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
return adminPermissionDefinitionHttpBody(definition.value);
|
|
1739
|
+
});
|
|
1740
|
+
export const adminPermissionDefinitionListOperation = Effect.fn("auth.http.admin_permission_definition.list")(function* (handlerRequest) {
|
|
1741
|
+
const { query, request } = handlerRequest;
|
|
1742
|
+
const administration = yield* PermissionAdministration;
|
|
1743
|
+
const authorization = yield* AdminPermissionDefinitionAuthorization;
|
|
1744
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.list");
|
|
1745
|
+
const current = yield* requireSession(request);
|
|
1746
|
+
yield* authorization.authorize({
|
|
1747
|
+
currentSession: current.currentSession,
|
|
1748
|
+
action: "list",
|
|
1749
|
+
request,
|
|
1750
|
+
});
|
|
1751
|
+
const limit = normalizePermissionDefinitionListLimit(query.limit);
|
|
1752
|
+
const definitions = yield* administration
|
|
1753
|
+
.listPermissionDefinitions({ ...query, limit })
|
|
1754
|
+
.pipe(Effect.mapError(adminPermissionDefinitionHttpError));
|
|
1755
|
+
const nextAfter = definitions.length === limit ? definitions.at(-1)?.id : undefined;
|
|
1756
|
+
return {
|
|
1757
|
+
definitions: definitions.map(adminPermissionDefinitionHttpBody),
|
|
1758
|
+
...(nextAfter === undefined ? {} : { nextAfter }),
|
|
1759
|
+
};
|
|
1760
|
+
});
|
|
1761
|
+
export const adminPermissionDefinitionUpdateOperation = Effect.fn("auth.http.admin_permission_definition.update")(function* (handlerRequest) {
|
|
1762
|
+
const { payload, request } = handlerRequest;
|
|
1763
|
+
const administration = yield* PermissionAdministration;
|
|
1764
|
+
const authorization = yield* AdminPermissionDefinitionAuthorization;
|
|
1765
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.update");
|
|
1766
|
+
const current = yield* requireSession(request);
|
|
1767
|
+
yield* authorization.authorize({
|
|
1768
|
+
currentSession: current.currentSession,
|
|
1769
|
+
action: "update",
|
|
1770
|
+
request,
|
|
1771
|
+
permissionId: payload.id,
|
|
1772
|
+
...(payload.scopeType === undefined
|
|
1773
|
+
? {}
|
|
1774
|
+
: { scopeType: payload.scopeType }),
|
|
1775
|
+
});
|
|
1776
|
+
const definition = yield* administration
|
|
1777
|
+
.updatePermissionDefinition(payload)
|
|
1778
|
+
.pipe(Effect.mapError(adminPermissionDefinitionHttpError));
|
|
1779
|
+
yield* Audit.emit({
|
|
1780
|
+
type: "auth.permission_definition.updated",
|
|
1781
|
+
actor: Audit.AuditActor.user({
|
|
1782
|
+
userId: current.currentSession.userId,
|
|
1783
|
+
sessionId: current.currentSession.sessionId,
|
|
1784
|
+
}),
|
|
1785
|
+
permissionId: definition.id,
|
|
1786
|
+
...(definition.scopeType === undefined
|
|
1787
|
+
? {}
|
|
1788
|
+
: { scopeType: definition.scopeType }),
|
|
1789
|
+
changedFields: [
|
|
1790
|
+
...(payload.description === undefined ? [] : ["description"]),
|
|
1791
|
+
...(payload.scopeType === undefined ? [] : ["scopeType"]),
|
|
1792
|
+
],
|
|
1793
|
+
occurredAt: definition.updatedAt,
|
|
1794
|
+
});
|
|
1795
|
+
return adminPermissionDefinitionHttpBody(definition);
|
|
1796
|
+
});
|
|
1797
|
+
const runAdminPermissionDefinitionMutation = Effect.fn("auth.http.admin_permission_definition.mutate")(function* (action, handlerRequest) {
|
|
1798
|
+
const { payload, request } = handlerRequest;
|
|
1799
|
+
const administration = yield* PermissionAdministration;
|
|
1800
|
+
const authorization = yield* AdminPermissionDefinitionAuthorization;
|
|
1801
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", `admin_permission_definition.${action}`);
|
|
1802
|
+
const current = yield* requireSession(request);
|
|
1803
|
+
yield* authorization.authorize({
|
|
1804
|
+
currentSession: current.currentSession,
|
|
1805
|
+
action,
|
|
1806
|
+
request,
|
|
1807
|
+
permissionId: payload.id,
|
|
1808
|
+
});
|
|
1809
|
+
const mutation = action === "disable"
|
|
1810
|
+
? administration.disablePermissionDefinition(payload)
|
|
1811
|
+
: action === "enable"
|
|
1812
|
+
? administration.enablePermissionDefinition(payload)
|
|
1813
|
+
: administration.deletePermissionDefinition(payload);
|
|
1814
|
+
const definition = yield* mutation.pipe(Effect.mapError(adminPermissionDefinitionHttpError));
|
|
1815
|
+
const actor = Audit.AuditActor.user({
|
|
1816
|
+
userId: current.currentSession.userId,
|
|
1817
|
+
sessionId: current.currentSession.sessionId,
|
|
1818
|
+
});
|
|
1819
|
+
const common = {
|
|
1820
|
+
actor,
|
|
1821
|
+
permissionId: definition.id,
|
|
1822
|
+
...(definition.scopeType === undefined
|
|
1823
|
+
? {}
|
|
1824
|
+
: { scopeType: definition.scopeType }),
|
|
1825
|
+
occurredAt: definition.updatedAt,
|
|
1826
|
+
};
|
|
1827
|
+
const event = action === "disable"
|
|
1828
|
+
? { type: "auth.permission_definition.disabled", ...common }
|
|
1829
|
+
: action === "enable"
|
|
1830
|
+
? { type: "auth.permission_definition.enabled", ...common }
|
|
1831
|
+
: { type: "auth.permission_definition.deleted", ...common };
|
|
1832
|
+
yield* Audit.emit(event);
|
|
1833
|
+
return adminPermissionDefinitionHttpBody(definition);
|
|
1834
|
+
});
|
|
1835
|
+
export const adminPermissionDefinitionDisableOperation = Effect.fn("auth.http.admin_permission_definition.disable")(function* (handlerRequest) {
|
|
1836
|
+
return yield* runAdminPermissionDefinitionMutation("disable", handlerRequest);
|
|
1837
|
+
});
|
|
1838
|
+
export const adminPermissionDefinitionEnableOperation = Effect.fn("auth.http.admin_permission_definition.enable")(function* (handlerRequest) {
|
|
1839
|
+
return yield* runAdminPermissionDefinitionMutation("enable", handlerRequest);
|
|
1840
|
+
});
|
|
1841
|
+
export const adminPermissionDefinitionDeleteOperation = Effect.fn("auth.http.admin_permission_definition.delete")(function* (handlerRequest) {
|
|
1842
|
+
return yield* runAdminPermissionDefinitionMutation("delete", handlerRequest);
|
|
1843
|
+
});
|
|
1633
1844
|
export const makeLoginNotificationReportHandler = (dependencies) => Effect.fn("auth.http.security.login_notification.report")(function* ({ payload, }) {
|
|
1634
1845
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "security.login_notification.report");
|
|
1635
1846
|
if (dependencies.loginNotification === undefined) {
|
|
@@ -1645,33 +1856,48 @@ export const makeLoginNotificationReportHandler = (dependencies) => Effect.fn("a
|
|
|
1645
1856
|
})));
|
|
1646
1857
|
return HttpServerResponse.empty({ status: 204 });
|
|
1647
1858
|
});
|
|
1648
|
-
const securityTimelineActorHttpBody = (actor) =>
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1859
|
+
const securityTimelineActorHttpBody = (actor) => {
|
|
1860
|
+
switch (actor.type) {
|
|
1861
|
+
case "anonymous": {
|
|
1862
|
+
return { type: "anonymous" };
|
|
1863
|
+
}
|
|
1864
|
+
case "user": {
|
|
1865
|
+
return {
|
|
1866
|
+
type: "user",
|
|
1867
|
+
...(actor.sessionId === undefined
|
|
1868
|
+
? {}
|
|
1869
|
+
: { sessionId: actor.sessionId }),
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
case "custom": {
|
|
1873
|
+
return undefined;
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1654
1877
|
const securityTimelineRequestHttpBody = (request) => ({
|
|
1655
1878
|
...(request.ipHash === undefined ? {} : { ipHash: request.ipHash }),
|
|
1656
1879
|
...(request.userAgentHash === undefined
|
|
1657
1880
|
? {}
|
|
1658
1881
|
: { userAgentHash: request.userAgentHash }),
|
|
1659
1882
|
});
|
|
1660
|
-
export const securityTimelineEventHttpBody = (event) =>
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
:
|
|
1670
|
-
|
|
1671
|
-
? {}
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
})
|
|
1883
|
+
export const securityTimelineEventHttpBody = (event) => {
|
|
1884
|
+
const actor = event.actor === undefined
|
|
1885
|
+
? undefined
|
|
1886
|
+
: securityTimelineActorHttpBody(event.actor);
|
|
1887
|
+
return {
|
|
1888
|
+
eventId: event.id,
|
|
1889
|
+
type: event.type,
|
|
1890
|
+
category: event.category,
|
|
1891
|
+
severity: event.severity,
|
|
1892
|
+
occurredAt: event.occurredAt,
|
|
1893
|
+
summary: event.summary,
|
|
1894
|
+
...(actor === undefined ? {} : { actor }),
|
|
1895
|
+
...(event.request === undefined
|
|
1896
|
+
? {}
|
|
1897
|
+
: { request: securityTimelineRequestHttpBody(event.request) }),
|
|
1898
|
+
...(event.metadata === undefined ? {} : { metadata: event.metadata }),
|
|
1899
|
+
};
|
|
1900
|
+
};
|
|
1675
1901
|
const securityTimelineListInput = (query, userId) => ({
|
|
1676
1902
|
userId,
|
|
1677
1903
|
...(query.limit === undefined ? {} : { limit: query.limit }),
|
|
@@ -1682,7 +1908,8 @@ const securityTimelineListInput = (query, userId) => ({
|
|
|
1682
1908
|
...(query.categories === undefined ? {} : { categories: query.categories }),
|
|
1683
1909
|
});
|
|
1684
1910
|
const adminSecurityTimelineListInput = (query) => securityTimelineListInput(query, query.userId);
|
|
1685
|
-
export const makeSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.security_timeline.list")(function* (
|
|
1911
|
+
export const makeSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.security_timeline.list")(function* (handlerRequest) {
|
|
1912
|
+
const { query, request } = handlerRequest;
|
|
1686
1913
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "security_timeline.list");
|
|
1687
1914
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1688
1915
|
const events = yield* dependencies.securityTimeline
|
|
@@ -1693,7 +1920,8 @@ export const makeSecurityTimelineListHandler = (dependencies) => Effect.fn("auth
|
|
|
1693
1920
|
})));
|
|
1694
1921
|
return { events: events.map(securityTimelineEventHttpBody) };
|
|
1695
1922
|
});
|
|
1696
|
-
export const makeAdminSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.admin_security_timeline.list")(function* (
|
|
1923
|
+
export const makeAdminSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.admin_security_timeline.list")(function* (handlerRequest) {
|
|
1924
|
+
const { query, request } = handlerRequest;
|
|
1697
1925
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_security_timeline.list");
|
|
1698
1926
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1699
1927
|
yield* dependencies.authorization.authorize({
|
|
@@ -1716,7 +1944,8 @@ export const trustedDeviceHttpBody = (device) => ({
|
|
|
1716
1944
|
expiresAt: device.expiresAt,
|
|
1717
1945
|
...(device.metadata === undefined ? {} : { metadata: device.metadata }),
|
|
1718
1946
|
});
|
|
1719
|
-
export const makeTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.trusted_device.list")(function* (
|
|
1947
|
+
export const makeTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.trusted_device.list")(function* (handlerRequest) {
|
|
1948
|
+
const { request } = handlerRequest;
|
|
1720
1949
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "trusted_device.list");
|
|
1721
1950
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1722
1951
|
const now = yield* currentUnixMillis;
|
|
@@ -1728,7 +1957,8 @@ export const makeTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.ht
|
|
|
1728
1957
|
})));
|
|
1729
1958
|
return { devices: devices.map(trustedDeviceHttpBody) };
|
|
1730
1959
|
});
|
|
1731
|
-
export const makeTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.trusted_device.revoke")(function* (
|
|
1960
|
+
export const makeTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.trusted_device.revoke")(function* (handlerRequest) {
|
|
1961
|
+
const { payload, request } = handlerRequest;
|
|
1732
1962
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "trusted_device.revoke");
|
|
1733
1963
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1734
1964
|
yield* dependencies.trustedDevices
|
|
@@ -1742,7 +1972,8 @@ export const makeTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.
|
|
|
1742
1972
|
})));
|
|
1743
1973
|
return HttpServerResponse.empty({ status: 204 });
|
|
1744
1974
|
});
|
|
1745
|
-
export const makeAdminTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.list")(function* (
|
|
1975
|
+
export const makeAdminTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.list")(function* (handlerRequest) {
|
|
1976
|
+
const { query, request } = handlerRequest;
|
|
1746
1977
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_trusted_device.list");
|
|
1747
1978
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1748
1979
|
yield* dependencies.authorization.authorize({
|
|
@@ -1760,7 +1991,8 @@ export const makeAdminTrustedDeviceListHandler = (dependencies) => Effect.fn("au
|
|
|
1760
1991
|
})));
|
|
1761
1992
|
return { devices: devices.map(trustedDeviceHttpBody) };
|
|
1762
1993
|
});
|
|
1763
|
-
export const makeAdminTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.revoke")(function* (
|
|
1994
|
+
export const makeAdminTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.revoke")(function* (handlerRequest) {
|
|
1995
|
+
const { payload, request } = handlerRequest;
|
|
1764
1996
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_trusted_device.revoke");
|
|
1765
1997
|
const current = yield* readRequiredSession(dependencies, request);
|
|
1766
1998
|
yield* dependencies.authorization.authorize({
|
|
@@ -1781,12 +2013,10 @@ export const makeAdminTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("
|
|
|
1781
2013
|
})));
|
|
1782
2014
|
return HttpServerResponse.empty({ status: 204 });
|
|
1783
2015
|
});
|
|
1784
|
-
export const makeEmailVerificationStartHandler = (dependencies) => Effect.fn("auth.http.email_verification.start")(function* (
|
|
2016
|
+
export const makeEmailVerificationStartHandler = (dependencies) => Effect.fn("auth.http.email_verification.start")(function* (handlerRequest) {
|
|
1785
2017
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email_verification.start");
|
|
1786
|
-
const
|
|
1787
|
-
|
|
1788
|
-
yield* catchAuthApiRateLimit(authApiRateLimit.emailVerificationStart(input), "Failed to start email verification");
|
|
1789
|
-
yield* dependencies.emailVerificationFlow.start(input).pipe(Effect.catchTag("EmailVerificationFlowStartError", (error) => Effect.fail(error.cause instanceof EmailVerificationIssueError
|
|
2018
|
+
const guarded = yield* EmailGuards.emailVerification.start(handlerRequest);
|
|
2019
|
+
yield* dependencies.emailVerificationFlow.start(guarded.input).pipe(Effect.catchTag("EmailVerificationFlowStartError", (error) => Effect.fail(error.cause instanceof EmailVerificationIssueError
|
|
1790
2020
|
? new AuthBadRequestError({
|
|
1791
2021
|
code: "bad_request",
|
|
1792
2022
|
message: "Invalid email verification request",
|
|
@@ -1813,55 +2043,65 @@ export const makeEmailVerificationVerifyHandler = (dependencies) => Effect.fn("a
|
|
|
1813
2043
|
yield* upgradeVerifiedEmailSession(dependencies, request, verified);
|
|
1814
2044
|
return HttpServerResponse.empty({ status: 204 });
|
|
1815
2045
|
});
|
|
1816
|
-
export const makeEmailOtpStartHandler = (dependencies) => Effect.fn("auth.http.email_otp.start")(function* (
|
|
2046
|
+
export const makeEmailOtpStartHandler = (dependencies) => Effect.fn("auth.http.email_otp.start")(function* (handlerRequest) {
|
|
2047
|
+
const { payload } = handlerRequest;
|
|
1817
2048
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email_otp.start");
|
|
1818
|
-
const
|
|
1819
|
-
const
|
|
1820
|
-
yield* catchAuthApiRateLimit(authApiRateLimit.emailOtpStart(input), "Failed to start email OTP");
|
|
1821
|
-
return yield* dependencies.emailOtp.start(input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
2049
|
+
const guarded = yield* EmailGuards.emailOtp.start(handlerRequest);
|
|
2050
|
+
const started = yield* dependencies.emailOtp.start(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
1822
2051
|
code: "internal_error",
|
|
1823
2052
|
message: "Failed to start email OTP",
|
|
1824
2053
|
})));
|
|
2054
|
+
return {
|
|
2055
|
+
challengeId: started.challengeId,
|
|
2056
|
+
identity: payload.identity,
|
|
2057
|
+
expiresAt: started.expiresAt,
|
|
2058
|
+
};
|
|
1825
2059
|
});
|
|
1826
|
-
export const makeEmailOtpVerifyHandler = (dependencies) => Effect.fn("auth.http.email_otp.verify")(function* (
|
|
2060
|
+
export const makeEmailOtpVerifyHandler = (dependencies) => Effect.fn("auth.http.email_otp.verify")(function* (handlerRequest) {
|
|
1827
2061
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email_otp.verify");
|
|
1828
|
-
const
|
|
1829
|
-
const
|
|
1830
|
-
const requestContext = loginRequestContextFromRequest(request, requestMetadataOptions);
|
|
1831
|
-
const result = yield* dependencies.emailOtp
|
|
1832
|
-
.verify(emailOtpVerifyInput(payload, Option.isSome(trustedDeviceToken)
|
|
1833
|
-
? trustedDeviceToken.value
|
|
1834
|
-
: undefined, requestContext))
|
|
1835
|
-
.pipe(Effect.mapError(() => new AuthInternalError({
|
|
2062
|
+
const guarded = yield* EmailGuards.emailOtp.verify(handlerRequest);
|
|
2063
|
+
const result = yield* dependencies.emailOtp.verify(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
1836
2064
|
code: "internal_error",
|
|
1837
2065
|
message: "Failed to verify email OTP",
|
|
1838
2066
|
})));
|
|
1839
2067
|
return yield* dependencies.authHttp.commitEmailOtpVerifyResult(result);
|
|
1840
2068
|
});
|
|
1841
|
-
export const
|
|
2069
|
+
export const makeEmailAuthStartHandler = (dependencies) => Effect.fn("auth.http.email.start")(function* (handlerRequest) {
|
|
2070
|
+
const { payload } = handlerRequest;
|
|
2071
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email.start");
|
|
2072
|
+
const guarded = yield* EmailGuards.emailAuth.start(handlerRequest);
|
|
2073
|
+
const started = yield* dependencies.emailAuth.start(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
2074
|
+
code: "internal_error",
|
|
2075
|
+
message: "Failed to start email authentication",
|
|
2076
|
+
})));
|
|
2077
|
+
return {
|
|
2078
|
+
identity: payload.identity,
|
|
2079
|
+
emailOtp: {
|
|
2080
|
+
challengeId: started.emailOtp.challengeId,
|
|
2081
|
+
expiresAt: started.emailOtp.expiresAt,
|
|
2082
|
+
},
|
|
2083
|
+
magicLink: {
|
|
2084
|
+
expiresAt: started.magicLink.expiresAt,
|
|
2085
|
+
},
|
|
2086
|
+
};
|
|
2087
|
+
});
|
|
2088
|
+
export const makeMagicLinkStartHandler = (dependencies) => Effect.fn("auth.http.magic_link.start")(function* (handlerRequest) {
|
|
2089
|
+
const { payload } = handlerRequest;
|
|
1842
2090
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "magic_link.start");
|
|
1843
|
-
const
|
|
1844
|
-
const
|
|
1845
|
-
yield* catchAuthApiRateLimit(authApiRateLimit.magicLinkStart(input), "Failed to start magic link");
|
|
1846
|
-
const started = yield* dependencies.magicLink.start(input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
2091
|
+
const guarded = yield* EmailGuards.magicLink.start(handlerRequest);
|
|
2092
|
+
const started = yield* dependencies.magicLink.start(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
1847
2093
|
code: "internal_error",
|
|
1848
2094
|
message: "Failed to start magic link",
|
|
1849
2095
|
})));
|
|
1850
2096
|
return {
|
|
1851
|
-
|
|
2097
|
+
identity: payload.identity,
|
|
1852
2098
|
expiresAt: started.expiresAt,
|
|
1853
2099
|
};
|
|
1854
2100
|
});
|
|
1855
|
-
export const makeMagicLinkVerifyHandler = (dependencies) => Effect.fn("auth.http.magic_link.verify")(function* (
|
|
2101
|
+
export const makeMagicLinkVerifyHandler = (dependencies) => Effect.fn("auth.http.magic_link.verify")(function* (handlerRequest) {
|
|
1856
2102
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "magic_link.verify");
|
|
1857
|
-
const
|
|
1858
|
-
const
|
|
1859
|
-
const requestContext = loginRequestContextFromRequest(request, requestMetadataOptions);
|
|
1860
|
-
const result = yield* dependencies.magicLink
|
|
1861
|
-
.verify(magicLinkVerifyInput(payload, Option.isSome(trustedDeviceToken)
|
|
1862
|
-
? trustedDeviceToken.value
|
|
1863
|
-
: undefined, requestContext))
|
|
1864
|
-
.pipe(Effect.mapError(() => new AuthInternalError({
|
|
2103
|
+
const guarded = yield* EmailGuards.magicLink.verify(handlerRequest);
|
|
2104
|
+
const result = yield* dependencies.magicLink.verify(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
|
|
1865
2105
|
code: "internal_error",
|
|
1866
2106
|
message: "Failed to verify magic link",
|
|
1867
2107
|
})));
|
|
@@ -1869,7 +2109,9 @@ export const makeMagicLinkVerifyHandler = (dependencies) => Effect.fn("auth.http
|
|
|
1869
2109
|
});
|
|
1870
2110
|
export const makeOAuthAuthorizationStartHandler = (dependencies) => Effect.fn("auth.http.oauth.authorization_start")(function* ({ payload, }) {
|
|
1871
2111
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.authorization_start");
|
|
1872
|
-
const provider = yield* dependencies.oauthProviders
|
|
2112
|
+
const provider = yield* dependencies.oauthProviders
|
|
2113
|
+
.get(payload.providerId)
|
|
2114
|
+
.pipe(Effect.mapError(() => oauthInternalError("Failed to load OAuth provider")));
|
|
1873
2115
|
if (Option.isNone(provider)) {
|
|
1874
2116
|
return yield* oauthBadRequest("Unknown OAuth provider");
|
|
1875
2117
|
}
|
|
@@ -1877,7 +2119,9 @@ export const makeOAuthAuthorizationStartHandler = (dependencies) => Effect.fn("a
|
|
|
1877
2119
|
.start(oauthAuthorizationStartInput(payload, provider.value, dependencies))
|
|
1878
2120
|
.pipe(Effect.mapError(() => oauthInternalError("Failed to start OAuth authorization")));
|
|
1879
2121
|
if (dependencies.storeCodeVerifier !== undefined) {
|
|
1880
|
-
yield* dependencies
|
|
2122
|
+
yield* dependencies
|
|
2123
|
+
.storeCodeVerifier({ payload, started })
|
|
2124
|
+
.pipe(Effect.mapError(() => oauthInternalError("Failed to store OAuth verifier")));
|
|
1881
2125
|
}
|
|
1882
2126
|
return oauthAuthorizationStartedHttpBody(started);
|
|
1883
2127
|
});
|
|
@@ -2008,12 +2252,15 @@ const makeOAuthTokenIntrospectionNotConfiguredHandler = () => Effect.fn("auth.ht
|
|
|
2008
2252
|
yield* oauthTokenIntrospectionRequestBody(request);
|
|
2009
2253
|
return yield* oauthTokenIntrospectionEndpointError("invalid_request");
|
|
2010
2254
|
});
|
|
2011
|
-
export const makeOAuthAccountUnlinkHandler = (dependencies) => Effect.fn("auth.http.oauth.account_unlink")(function* (
|
|
2255
|
+
export const makeOAuthAccountUnlinkHandler = (dependencies) => Effect.fn("auth.http.oauth.account_unlink")(function* (handlerRequest) {
|
|
2256
|
+
const { payload, request } = handlerRequest;
|
|
2012
2257
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.account_unlink");
|
|
2013
2258
|
const session = yield* readRequiredSession(dependencies, request);
|
|
2014
2259
|
const stepUpSatisfied = dependencies.stepUpSatisfied === undefined
|
|
2015
2260
|
? undefined
|
|
2016
|
-
: yield* dependencies
|
|
2261
|
+
: yield* dependencies
|
|
2262
|
+
.stepUpSatisfied({ payload, request, session })
|
|
2263
|
+
.pipe(Effect.mapError(() => oauthInternalError("Failed to evaluate OAuth unlink step-up")));
|
|
2017
2264
|
const decision = yield* dependencies.oauthAccountUnlinking
|
|
2018
2265
|
.resolve({
|
|
2019
2266
|
userId: session.currentSession.userId,
|
|
@@ -2038,16 +2285,22 @@ export const makeOAuthLinkConfirmationStartHandler = (dependencies) => Effect.fn
|
|
|
2038
2285
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.link_confirmation_start");
|
|
2039
2286
|
const baseInput = dependencies.startInput === undefined
|
|
2040
2287
|
? yield* oauthLinkConfirmationStartInput(payload, dependencies)
|
|
2041
|
-
: yield* dependencies
|
|
2288
|
+
: yield* dependencies
|
|
2289
|
+
.startInput({ payload, request })
|
|
2290
|
+
.pipe(Effect.mapError((error) => oauthHookHttpError(error, "Failed to resolve OAuth link confirmation input")));
|
|
2042
2291
|
const input = {
|
|
2043
2292
|
...baseInput,
|
|
2044
2293
|
...(baseInput.ttl === undefined && dependencies.ttl !== undefined
|
|
2045
2294
|
? { ttl: dependencies.ttl }
|
|
2046
2295
|
: {}),
|
|
2047
2296
|
};
|
|
2048
|
-
const started = yield* dependencies.oauthLinkConfirmation
|
|
2297
|
+
const started = yield* dependencies.oauthLinkConfirmation
|
|
2298
|
+
.start(input)
|
|
2299
|
+
.pipe(Effect.mapError((error) => oauthLinkConfirmationHttpError(error, "Failed to start OAuth link confirmation")));
|
|
2049
2300
|
if (dependencies.onStarted !== undefined) {
|
|
2050
|
-
yield* dependencies
|
|
2301
|
+
yield* dependencies
|
|
2302
|
+
.onStarted({ payload, request, started })
|
|
2303
|
+
.pipe(Effect.mapError(() => oauthInternalError("Failed to deliver OAuth link confirmation")));
|
|
2051
2304
|
}
|
|
2052
2305
|
return oauthLinkConfirmationStartedHttpBody(started);
|
|
2053
2306
|
});
|
|
@@ -2062,38 +2315,62 @@ export const makeOAuthLinkConfirmationConfirmHandler = (dependencies) => Effect.
|
|
|
2062
2315
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.link_confirmation_confirm");
|
|
2063
2316
|
const currentUserId = dependencies.currentUserId === undefined
|
|
2064
2317
|
? undefined
|
|
2065
|
-
: yield* dependencies
|
|
2318
|
+
: yield* dependencies
|
|
2319
|
+
.currentUserId({ payload, request })
|
|
2320
|
+
.pipe(Effect.mapError((error) => oauthHookHttpError(error, "Failed to resolve current OAuth user")));
|
|
2066
2321
|
const confirmed = yield* dependencies.oauthLinkConfirmation
|
|
2067
2322
|
.confirm(oauthLinkConfirmationConfirmInput(payload, currentUserId))
|
|
2068
2323
|
.pipe(Effect.mapError((error) => oauthLinkConfirmationHttpError(error, "Failed to confirm OAuth link confirmation")));
|
|
2069
2324
|
if (dependencies.linkAfterConfirm !== undefined) {
|
|
2070
|
-
yield* dependencies
|
|
2325
|
+
yield* dependencies
|
|
2326
|
+
.linkAfterConfirm({ payload, request, confirmed })
|
|
2327
|
+
.pipe(Effect.mapError(() => oauthInternalError("Failed to link OAuth account")));
|
|
2071
2328
|
}
|
|
2072
2329
|
return oauthLinkConfirmationConfirmedHttpBody(confirmed, {
|
|
2073
2330
|
linked: dependencies.linkAfterConfirm !== undefined,
|
|
2074
2331
|
});
|
|
2075
2332
|
});
|
|
2076
|
-
export const makePasskeyRegistrationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_start")(function* (
|
|
2333
|
+
export const makePasskeyRegistrationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_start")(function* (handlerRequest) {
|
|
2334
|
+
const { request } = handlerRequest;
|
|
2077
2335
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.registration_start");
|
|
2336
|
+
const current = yield* readRequiredSession(dependencies, request);
|
|
2337
|
+
yield* requireAuthRateLimit("auth.passkey.registration_start", handlerRequest, current.currentSession.userId);
|
|
2338
|
+
const user = yield* dependencies.resolveUser({
|
|
2339
|
+
currentSession: current.currentSession,
|
|
2340
|
+
actor: current.actor,
|
|
2341
|
+
request,
|
|
2342
|
+
});
|
|
2078
2343
|
return yield* dependencies.passkeyOptions
|
|
2079
|
-
.startRegistration(passkeyRegistrationStartInput(
|
|
2344
|
+
.startRegistration(passkeyRegistrationStartInput(current.currentSession.userId, user, dependencies))
|
|
2080
2345
|
.pipe(Effect.mapError(() => passkeyInternalError("Failed to start passkey registration")));
|
|
2081
2346
|
});
|
|
2082
|
-
export const makePasskeyRegistrationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_finish")(function* (
|
|
2347
|
+
export const makePasskeyRegistrationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_finish")(function* (handlerRequest) {
|
|
2348
|
+
const { payload, request } = handlerRequest;
|
|
2083
2349
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.registration_finish");
|
|
2350
|
+
const current = yield* readRequiredSession(dependencies, request);
|
|
2351
|
+
yield* requireAuthRateLimit("auth.passkey.registration_finish", handlerRequest, current.currentSession.userId);
|
|
2352
|
+
const user = yield* dependencies.resolveUser({
|
|
2353
|
+
currentSession: current.currentSession,
|
|
2354
|
+
actor: current.actor,
|
|
2355
|
+
request,
|
|
2356
|
+
});
|
|
2084
2357
|
const finished = yield* dependencies.passkeyVerification
|
|
2085
|
-
.finishRegistration(passkeyRegistrationFinishInput(payload, dependencies))
|
|
2358
|
+
.finishRegistration(passkeyRegistrationFinishInput(current.currentSession.userId, payload, user, dependencies))
|
|
2086
2359
|
.pipe(Effect.mapError(passkeyVerificationHttpError));
|
|
2087
2360
|
return { credentialId: finished.credential.credentialId };
|
|
2088
2361
|
});
|
|
2089
|
-
export const makePasskeyAuthenticationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_start")(function* (
|
|
2362
|
+
export const makePasskeyAuthenticationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_start")(function* (handlerRequest) {
|
|
2363
|
+
const { payload } = handlerRequest;
|
|
2090
2364
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.authentication_start");
|
|
2365
|
+
yield* requireAuthRateLimit("auth.passkey.authentication_start", handlerRequest);
|
|
2091
2366
|
return yield* dependencies.passkeyOptions
|
|
2092
2367
|
.startAuthentication(passkeyAuthenticationStartInput(payload, dependencies))
|
|
2093
2368
|
.pipe(Effect.mapError(() => passkeyInternalError("Failed to start passkey authentication")));
|
|
2094
2369
|
});
|
|
2095
|
-
export const makePasskeyAuthenticationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_finish")(function* (
|
|
2370
|
+
export const makePasskeyAuthenticationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_finish")(function* (handlerRequest) {
|
|
2371
|
+
const { payload, request } = handlerRequest;
|
|
2096
2372
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.authentication_finish");
|
|
2373
|
+
yield* requireAuthRateLimit("auth.passkey.authentication_finish", handlerRequest);
|
|
2097
2374
|
const finished = yield* dependencies.passkeyVerification
|
|
2098
2375
|
.finishAuthentication(passkeyAuthenticationFinishInput(payload, dependencies))
|
|
2099
2376
|
.pipe(Effect.mapError(passkeyVerificationHttpError));
|
|
@@ -2106,9 +2383,58 @@ export const makePasskeyAuthenticationFinishHandler = (dependencies) => Effect.f
|
|
|
2106
2383
|
.pipe(Effect.mapError(() => passkeyInternalError("Failed to create passkey session")));
|
|
2107
2384
|
return yield* dependencies.authHttp.commitAuthenticatedSession(session);
|
|
2108
2385
|
});
|
|
2109
|
-
|
|
2386
|
+
const identityInfoHttpBody = (identity) => ({ ...identity });
|
|
2387
|
+
const withIdentitySession = (dependencies, request, operation, handlerRequest, run) => Effect.gen(function* () {
|
|
2388
|
+
const session = yield* readRequiredSession(dependencies, request);
|
|
2389
|
+
yield* requireAuthRateLimit(operation, handlerRequest, session.currentSession.userId);
|
|
2390
|
+
return yield* run(session).pipe(Effect.mapError(identityHttpError));
|
|
2391
|
+
});
|
|
2392
|
+
export const makeIdentityAvailabilityHandler = (dependencies) => (handlerRequest) => Effect.gen(function* () {
|
|
2393
|
+
const guarded = yield* IdentityGuards.availability(handlerRequest);
|
|
2394
|
+
const available = yield* dependencies.identityManagement
|
|
2395
|
+
.availability(guarded.input)
|
|
2396
|
+
.pipe(Effect.mapError(identityHttpError));
|
|
2397
|
+
return { available };
|
|
2398
|
+
});
|
|
2399
|
+
export const makeIdentityListHandler = (dependencies) => (handlerRequest) => withIdentitySession(dependencies, handlerRequest.request, "auth.identity.list", handlerRequest, (session) => dependencies.identityManagement
|
|
2400
|
+
.list(session.currentSession.userId)
|
|
2401
|
+
.pipe(Effect.map((identities) => ({
|
|
2402
|
+
identities: identities.map(identityInfoHttpBody),
|
|
2403
|
+
}))));
|
|
2404
|
+
const identityMutationHandler = (dependencies, operation, handlerRequest, run) => withIdentitySession(dependencies, handlerRequest.request, operation, handlerRequest, (session) => run(session, handlerRequest.payload));
|
|
2405
|
+
export const makeIdentityAddHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.add", request, (session, payload) => dependencies.identityManagement
|
|
2406
|
+
.add({
|
|
2407
|
+
...payload,
|
|
2408
|
+
userId: session.currentSession.userId,
|
|
2409
|
+
currentSession: session,
|
|
2410
|
+
})
|
|
2411
|
+
.pipe(Effect.map(identityInfoHttpBody)));
|
|
2412
|
+
export const makeIdentityReplaceHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.replace", request, (session, payload) => dependencies.identityManagement
|
|
2413
|
+
.replace({
|
|
2414
|
+
...payload,
|
|
2415
|
+
userId: session.currentSession.userId,
|
|
2416
|
+
currentSession: session,
|
|
2417
|
+
})
|
|
2418
|
+
.pipe(Effect.map(identityInfoHttpBody)));
|
|
2419
|
+
export const makeIdentityRevokeHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.revoke", request, (session, payload) => dependencies.identityManagement
|
|
2420
|
+
.revoke({
|
|
2421
|
+
...payload,
|
|
2422
|
+
userId: session.currentSession.userId,
|
|
2423
|
+
currentSession: session,
|
|
2424
|
+
})
|
|
2425
|
+
.pipe(Effect.map(identityInfoHttpBody)));
|
|
2426
|
+
export const makeIdentityPrimaryHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.set_primary", request, (session, payload) => dependencies.identityManagement
|
|
2427
|
+
.setPrimary({
|
|
2428
|
+
...payload,
|
|
2429
|
+
userId: session.currentSession.userId,
|
|
2430
|
+
currentSession: session,
|
|
2431
|
+
})
|
|
2432
|
+
.pipe(Effect.map(identityInfoHttpBody)));
|
|
2433
|
+
export const makePasskeyCredentialListHandler = (dependencies) => Effect.fn("auth.http.passkey.credential_list")(function* (handlerRequest) {
|
|
2434
|
+
const { request } = handlerRequest;
|
|
2110
2435
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.credential_list");
|
|
2111
2436
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2437
|
+
yield* requireAuthRateLimit("auth.passkey.credentials.list", handlerRequest, current.currentSession.userId);
|
|
2112
2438
|
const credentials = yield* dependencies.passkeyCredentialManagement
|
|
2113
2439
|
.listForUser({ userId: current.currentSession.userId })
|
|
2114
2440
|
.pipe(Effect.mapError(() => passkeyInternalError("Failed to list passkey credentials")));
|
|
@@ -2116,87 +2442,130 @@ export const makePasskeyCredentialListHandler = (dependencies) => Effect.fn("aut
|
|
|
2116
2442
|
credentials: credentials.map(passkeyCredentialInfoHttpBody),
|
|
2117
2443
|
};
|
|
2118
2444
|
});
|
|
2119
|
-
export const makePasskeyCredentialRevokeHandler = (dependencies) => Effect.fn("auth.http.passkey.credential_revoke")(function* (
|
|
2445
|
+
export const makePasskeyCredentialRevokeHandler = (dependencies) => Effect.fn("auth.http.passkey.credential_revoke")(function* (handlerRequest) {
|
|
2446
|
+
const { payload, request } = handlerRequest;
|
|
2120
2447
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.credential_revoke");
|
|
2121
2448
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2449
|
+
yield* requireAuthRateLimit("auth.passkey.credentials.revoke", handlerRequest, current.currentSession.userId);
|
|
2450
|
+
yield* requireCanRemoveStrongFactor(dependencies.strongFactorRemovalPolicy, {
|
|
2451
|
+
userId: current.currentSession.userId,
|
|
2452
|
+
factor: strongFactor("passkey", PasskeyCredentialId(payload.credentialId)),
|
|
2453
|
+
});
|
|
2122
2454
|
yield* dependencies.passkeyCredentialManagement
|
|
2123
2455
|
.revokeForUser(passkeyCredentialRevokeInput(current.currentSession.userId, payload))
|
|
2124
2456
|
.pipe(Effect.mapError(passkeyCredentialManagementHttpError));
|
|
2125
2457
|
return HttpServerResponse.empty({ status: 204 });
|
|
2126
2458
|
});
|
|
2127
|
-
export const makeTotpEnrollmentStartHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_start")(function* (
|
|
2459
|
+
export const makeTotpEnrollmentStartHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_start")(function* (handlerRequest) {
|
|
2460
|
+
const { payload, request } = handlerRequest;
|
|
2128
2461
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.enrollment_start");
|
|
2129
2462
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2463
|
+
yield* requireAuthRateLimit("auth.totp.enrollment_start", handlerRequest, current.currentSession.userId);
|
|
2130
2464
|
const started = yield* dependencies.totpFactorManagement
|
|
2131
2465
|
.startEnrollment(totpEnrollmentStartInput(current.currentSession.userId, payload, dependencies))
|
|
2132
2466
|
.pipe(Effect.mapError(totpFactorManagementHttpError));
|
|
2133
2467
|
return totpEnrollmentStartedHttpBody(started);
|
|
2134
2468
|
});
|
|
2135
|
-
export const makeTotpEnrollmentConfirmHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_confirm")(function* (
|
|
2469
|
+
export const makeTotpEnrollmentConfirmHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_confirm")(function* (handlerRequest) {
|
|
2470
|
+
const { payload, request } = handlerRequest;
|
|
2136
2471
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.enrollment_confirm");
|
|
2137
2472
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2473
|
+
yield* requireAuthRateLimit("auth.totp.enrollment_confirm", handlerRequest, current.currentSession.userId);
|
|
2138
2474
|
const confirmed = yield* dependencies.totpFactorManagement
|
|
2139
2475
|
.confirmEnrollment(totpEnrollmentConfirmInput(current.currentSession.userId, payload, dependencies))
|
|
2140
2476
|
.pipe(Effect.mapError(totpFactorManagementHttpError));
|
|
2141
2477
|
return totpFactorInfoHttpBody(confirmed);
|
|
2142
2478
|
});
|
|
2143
|
-
export const makeTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.totp.verify")(function* (
|
|
2479
|
+
export const makeTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.totp.verify")(function* (handlerRequest) {
|
|
2480
|
+
const { payload, request } = handlerRequest;
|
|
2144
2481
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.verify");
|
|
2145
2482
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2483
|
+
yield* requireAuthRateLimit("auth.totp.verify", handlerRequest, current.currentSession.userId);
|
|
2146
2484
|
const result = yield* dependencies.totpFactorManagement
|
|
2147
2485
|
.verifyForUser(totpVerifyInput(current.currentSession.userId, payload, dependencies))
|
|
2148
2486
|
.pipe(Effect.mapError(() => totpInternalError("Failed to verify TOTP factor")));
|
|
2149
2487
|
return totpVerifyResultHttpBody(result);
|
|
2150
2488
|
});
|
|
2151
|
-
export const makeTotpFactorListHandler = (dependencies) => Effect.fn("auth.http.totp.factor_list")(function* (
|
|
2489
|
+
export const makeTotpFactorListHandler = (dependencies) => Effect.fn("auth.http.totp.factor_list")(function* (handlerRequest) {
|
|
2490
|
+
const { request } = handlerRequest;
|
|
2152
2491
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.factor_list");
|
|
2153
2492
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2493
|
+
yield* requireAuthRateLimit("auth.totp.factors.list", handlerRequest, current.currentSession.userId);
|
|
2154
2494
|
const factors = yield* dependencies.totpFactorManagement
|
|
2155
2495
|
.listForUser({ userId: current.currentSession.userId })
|
|
2156
2496
|
.pipe(Effect.mapError(() => totpInternalError("Failed to list TOTP factors")));
|
|
2157
2497
|
return { factors: factors.map(totpFactorInfoHttpBody) };
|
|
2158
2498
|
});
|
|
2159
|
-
export const makeTotpFactorRevokeHandler = (dependencies) => Effect.fn("auth.http.totp.factor_revoke")(function* (
|
|
2499
|
+
export const makeTotpFactorRevokeHandler = (dependencies) => Effect.fn("auth.http.totp.factor_revoke")(function* (handlerRequest) {
|
|
2500
|
+
const { payload, request } = handlerRequest;
|
|
2160
2501
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.factor_revoke");
|
|
2161
2502
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2503
|
+
yield* requireAuthRateLimit("auth.totp.factors.revoke", handlerRequest, current.currentSession.userId);
|
|
2504
|
+
yield* requireCanRemoveStrongFactor(dependencies.strongFactorRemovalPolicy, {
|
|
2505
|
+
userId: current.currentSession.userId,
|
|
2506
|
+
factor: strongFactor("totp", payload.factorId),
|
|
2507
|
+
});
|
|
2162
2508
|
yield* dependencies.totpFactorManagement
|
|
2163
2509
|
.revokeForUser(totpFactorRevokeInput(current.currentSession.userId, payload))
|
|
2164
2510
|
.pipe(Effect.mapError(totpFactorManagementHttpError));
|
|
2165
2511
|
return HttpServerResponse.empty({ status: 204 });
|
|
2166
2512
|
});
|
|
2167
|
-
export const makeRecoveryCodeGenerateHandler = (dependencies) => Effect.fn("auth.http.recovery_code.generate")(function* (
|
|
2513
|
+
export const makeRecoveryCodeGenerateHandler = (dependencies) => Effect.fn("auth.http.recovery_code.generate")(function* (handlerRequest) {
|
|
2514
|
+
const { payload, request } = handlerRequest;
|
|
2168
2515
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.generate");
|
|
2169
2516
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2517
|
+
yield* requireAuthRateLimit("auth.recovery_code.generate", handlerRequest, current.currentSession.userId);
|
|
2170
2518
|
const generated = yield* dependencies.recoveryCodeManagement
|
|
2171
2519
|
.generateForUser(recoveryCodeGenerateInput(current.currentSession.userId, payload, dependencies))
|
|
2172
2520
|
.pipe(Effect.mapError(recoveryCodeManagementHttpError));
|
|
2173
2521
|
return recoveryCodesGeneratedHttpBody(generated);
|
|
2174
2522
|
});
|
|
2175
|
-
export const
|
|
2523
|
+
export const makeRecoveryCodeRegenerateHandler = (dependencies) => Effect.fn("auth.http.recovery_code.regenerate")(function* (handlerRequest) {
|
|
2524
|
+
const { payload, request } = handlerRequest;
|
|
2525
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.regenerate");
|
|
2526
|
+
const current = yield* readRequiredSession(dependencies, request);
|
|
2527
|
+
yield* requireAuthRateLimit("auth.recovery_code.regenerate", handlerRequest, current.currentSession.userId);
|
|
2528
|
+
const generated = yield* dependencies.recoveryCodeManagement
|
|
2529
|
+
.regenerateForUser(recoveryCodeRegenerateInput(current.currentSession.userId, payload, dependencies))
|
|
2530
|
+
.pipe(Effect.mapError(recoveryCodeManagementHttpError));
|
|
2531
|
+
return recoveryCodesGeneratedHttpBody(generated);
|
|
2532
|
+
});
|
|
2533
|
+
export const makeRecoveryCodeVerifyHandler = (dependencies) => Effect.fn("auth.http.recovery_code.verify")(function* (handlerRequest) {
|
|
2534
|
+
const { payload, request } = handlerRequest;
|
|
2176
2535
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.verify");
|
|
2177
2536
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2537
|
+
yield* requireAuthRateLimit("auth.recovery_code.verify", handlerRequest, current.currentSession.userId);
|
|
2178
2538
|
const result = yield* dependencies.recoveryCodeManagement
|
|
2179
2539
|
.verifyForUser(recoveryCodeVerifyInput(current.currentSession.userId, payload))
|
|
2180
2540
|
.pipe(Effect.mapError(() => recoveryCodeInternalError("Failed to verify recovery code")));
|
|
2181
2541
|
return recoveryCodeVerifyResultHttpBody(result);
|
|
2182
2542
|
});
|
|
2183
|
-
export const makeRecoveryCodeListHandler = (dependencies) => Effect.fn("auth.http.recovery_code.list")(function* (
|
|
2543
|
+
export const makeRecoveryCodeListHandler = (dependencies) => Effect.fn("auth.http.recovery_code.list")(function* (handlerRequest) {
|
|
2544
|
+
const { request } = handlerRequest;
|
|
2184
2545
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.list");
|
|
2185
2546
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2547
|
+
yield* requireAuthRateLimit("auth.recovery_code.list", handlerRequest, current.currentSession.userId);
|
|
2186
2548
|
const codes = yield* dependencies.recoveryCodeManagement
|
|
2187
2549
|
.listForUser({ userId: current.currentSession.userId })
|
|
2188
2550
|
.pipe(Effect.mapError(() => recoveryCodeInternalError("Failed to list recovery codes")));
|
|
2189
2551
|
return { codes: codes.map(recoveryCodeInfoHttpBody) };
|
|
2190
2552
|
});
|
|
2191
|
-
export const makeRecoveryCodeRevokeHandler = (dependencies) => Effect.fn("auth.http.recovery_code.revoke")(function* (
|
|
2553
|
+
export const makeRecoveryCodeRevokeHandler = (dependencies) => Effect.fn("auth.http.recovery_code.revoke")(function* (handlerRequest) {
|
|
2554
|
+
const { payload, request } = handlerRequest;
|
|
2192
2555
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.revoke");
|
|
2193
2556
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2557
|
+
yield* requireAuthRateLimit("auth.recovery_code.revoke", handlerRequest, current.currentSession.userId);
|
|
2558
|
+
yield* requireCanRemoveStrongFactor(dependencies.strongFactorRemovalPolicy, {
|
|
2559
|
+
userId: current.currentSession.userId,
|
|
2560
|
+
factor: strongFactor("recovery-code", payload.codeId),
|
|
2561
|
+
});
|
|
2194
2562
|
yield* dependencies.recoveryCodeManagement
|
|
2195
2563
|
.revokeForUser(recoveryCodeRevokeInput(current.currentSession.userId, payload))
|
|
2196
2564
|
.pipe(Effect.mapError(recoveryCodeManagementHttpError));
|
|
2197
2565
|
return HttpServerResponse.empty({ status: 204 });
|
|
2198
2566
|
});
|
|
2199
|
-
export const makeApiKeyCreateHandler = (dependencies) => Effect.fn("auth.http.api_key.create")(function* (
|
|
2567
|
+
export const makeApiKeyCreateHandler = (dependencies) => Effect.fn("auth.http.api_key.create")(function* (handlerRequest) {
|
|
2568
|
+
const { payload, request } = handlerRequest;
|
|
2200
2569
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "api_key.create");
|
|
2201
2570
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2202
2571
|
const created = yield* dependencies.apiKeyManagement
|
|
@@ -2204,7 +2573,8 @@ export const makeApiKeyCreateHandler = (dependencies) => Effect.fn("auth.http.ap
|
|
|
2204
2573
|
.pipe(Effect.mapError(apiKeyManagementHttpError));
|
|
2205
2574
|
return apiKeyCreatedHttpBody(created);
|
|
2206
2575
|
});
|
|
2207
|
-
export const makeApiKeyListHandler = (dependencies) => Effect.fn("auth.http.api_key.list")(function* (
|
|
2576
|
+
export const makeApiKeyListHandler = (dependencies) => Effect.fn("auth.http.api_key.list")(function* (handlerRequest) {
|
|
2577
|
+
const { request } = handlerRequest;
|
|
2208
2578
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "api_key.list");
|
|
2209
2579
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2210
2580
|
const keys = yield* dependencies.apiKeyManagement
|
|
@@ -2212,7 +2582,8 @@ export const makeApiKeyListHandler = (dependencies) => Effect.fn("auth.http.api_
|
|
|
2212
2582
|
.pipe(Effect.mapError(() => apiKeyInternalError("Failed to list API keys")));
|
|
2213
2583
|
return { keys: keys.map(apiKeyInfoHttpBody) };
|
|
2214
2584
|
});
|
|
2215
|
-
export const makeApiKeyRevokeHandler = (dependencies) => Effect.fn("auth.http.api_key.revoke")(function* (
|
|
2585
|
+
export const makeApiKeyRevokeHandler = (dependencies) => Effect.fn("auth.http.api_key.revoke")(function* (handlerRequest) {
|
|
2586
|
+
const { payload, request } = handlerRequest;
|
|
2216
2587
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "api_key.revoke");
|
|
2217
2588
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2218
2589
|
yield* dependencies.apiKeyManagement
|
|
@@ -2257,7 +2628,7 @@ export const makeJwtIntrospectHandler = (dependencies) => Effect.fn("auth.http.j
|
|
|
2257
2628
|
.pipe(Effect.mapError(() => jwtInternalError("Failed to introspect JWT access token")));
|
|
2258
2629
|
return jwtIntrospectionHttpBody(result);
|
|
2259
2630
|
});
|
|
2260
|
-
export const makeJwtRevokeHandler = (dependencies) => Effect.fn("auth.http.jwt.revoke")(function* ({ payload }) {
|
|
2631
|
+
export const makeJwtRevokeHandler = (dependencies) => Effect.fn("auth.http.jwt.revoke")(function* ({ payload, }) {
|
|
2261
2632
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "jwt.revoke");
|
|
2262
2633
|
yield* dependencies.jwtRevocation
|
|
2263
2634
|
.revokeJwtId(jwtRevokeInput(payload))
|
|
@@ -2266,20 +2637,28 @@ export const makeJwtRevokeHandler = (dependencies) => Effect.fn("auth.http.jwt.r
|
|
|
2266
2637
|
});
|
|
2267
2638
|
export const makeJwtJwksHandler = (dependencies) => Effect.fn("auth.http.jwt.jwks")(function* (_) {
|
|
2268
2639
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "jwt.jwks");
|
|
2269
|
-
const document = yield* dependencies.jwks
|
|
2640
|
+
const document = yield* dependencies.jwks
|
|
2641
|
+
.document()
|
|
2642
|
+
.pipe(Effect.mapError(() => jwtInternalError("Failed to load JWT JWKS document")));
|
|
2270
2643
|
return jwtJwksHttpBody(document);
|
|
2271
2644
|
});
|
|
2272
2645
|
export const makeOidcDiscoveryMetadataHandler = (dependencies) => Effect.fn("auth.http.oidc.discovery_metadata")(function* (_) {
|
|
2273
2646
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oidc.discovery_metadata");
|
|
2274
|
-
return yield* dependencies.metadata
|
|
2647
|
+
return yield* dependencies.metadata
|
|
2648
|
+
.load()
|
|
2649
|
+
.pipe(Effect.mapError(() => jwtInternalError("Failed to load OIDC discovery metadata")));
|
|
2275
2650
|
});
|
|
2276
|
-
export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.options")(function* (
|
|
2651
|
+
export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.options")(function* (handlerRequest) {
|
|
2652
|
+
const { payload } = handlerRequest;
|
|
2277
2653
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.options");
|
|
2654
|
+
yield* requireAuthRateLimit("auth.mfa.options", handlerRequest);
|
|
2278
2655
|
const pending = yield* dependencies.authFlowState
|
|
2279
2656
|
.inspect(payload.flowId)
|
|
2280
2657
|
.pipe(Effect.mapError(() => mfaBadRequest()));
|
|
2658
|
+
const allowed = new Set(pending.factors?.map((factor) => factor.type));
|
|
2281
2659
|
const factors = [];
|
|
2282
|
-
if (
|
|
2660
|
+
if (allowed.has("totp") &&
|
|
2661
|
+
dependencies.totpFactorManagement !== undefined) {
|
|
2283
2662
|
const totpFactors = yield* dependencies.totpFactorManagement
|
|
2284
2663
|
.listForUser({ userId: pending.userId })
|
|
2285
2664
|
.pipe(Effect.mapError(() => mfaInternalError("Failed to list MFA options")));
|
|
@@ -2287,7 +2666,8 @@ export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.
|
|
|
2287
2666
|
factors.push({ type: "totp" });
|
|
2288
2667
|
}
|
|
2289
2668
|
}
|
|
2290
|
-
if (
|
|
2669
|
+
if (allowed.has("backup-code") &&
|
|
2670
|
+
dependencies.recoveryCodeManagement !== undefined) {
|
|
2291
2671
|
const recoveryCodes = yield* dependencies.recoveryCodeManagement
|
|
2292
2672
|
.listForUser({ userId: pending.userId })
|
|
2293
2673
|
.pipe(Effect.mapError(() => mfaInternalError("Failed to list MFA options")));
|
|
@@ -2295,7 +2675,8 @@ export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.
|
|
|
2295
2675
|
factors.push({ type: "backup-code" });
|
|
2296
2676
|
}
|
|
2297
2677
|
}
|
|
2298
|
-
if (
|
|
2678
|
+
if (allowed.has("passkey") &&
|
|
2679
|
+
dependencies.passkeyCredentialManagement !== undefined) {
|
|
2299
2680
|
const credentials = yield* dependencies.passkeyCredentialManagement
|
|
2300
2681
|
.listForUser({ userId: pending.userId })
|
|
2301
2682
|
.pipe(Effect.mapError(() => mfaInternalError("Failed to list MFA options")));
|
|
@@ -2305,12 +2686,29 @@ export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.
|
|
|
2305
2686
|
}
|
|
2306
2687
|
return { factors };
|
|
2307
2688
|
});
|
|
2308
|
-
|
|
2689
|
+
const inspectMfaFlowForFactor = (authFlowState, flowId, factorType) => Effect.gen(function* () {
|
|
2690
|
+
const pending = yield* authFlowState
|
|
2691
|
+
.inspect(flowId)
|
|
2692
|
+
.pipe(Effect.mapError(() => mfaBadRequest()));
|
|
2693
|
+
if (pending.factors?.some((factor) => factor.type === factorType) !== true) {
|
|
2694
|
+
return yield* mfaBadRequest();
|
|
2695
|
+
}
|
|
2696
|
+
return pending;
|
|
2697
|
+
});
|
|
2698
|
+
export const makeTotpMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.totp_verify")(function* (handlerRequest) {
|
|
2699
|
+
const { payload } = handlerRequest;
|
|
2309
2700
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.totp_verify");
|
|
2701
|
+
yield* requireAuthRateLimit("auth.mfa.totp_verify", handlerRequest);
|
|
2702
|
+
const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "totp");
|
|
2703
|
+
if (pending.userId !== payload.userId) {
|
|
2704
|
+
return yield* mfaInvalidCredentials();
|
|
2705
|
+
}
|
|
2310
2706
|
const verified = yield* dependencies.totpFactorManagement
|
|
2311
2707
|
.verifyForUser(totpMfaVerifyInput(payload, dependencies))
|
|
2312
2708
|
.pipe(Effect.mapError(() => mfaInternalError("Failed to verify TOTP MFA factor")));
|
|
2313
|
-
if (!verified.valid
|
|
2709
|
+
if (!verified.valid ||
|
|
2710
|
+
verified.factor === undefined ||
|
|
2711
|
+
verified.acceptedCounter === undefined) {
|
|
2314
2712
|
return yield* mfaInvalidCredentials();
|
|
2315
2713
|
}
|
|
2316
2714
|
const result = yield* dependencies.authFlow
|
|
@@ -2318,44 +2716,98 @@ export const makeTotpMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.m
|
|
|
2318
2716
|
flowId: payload.flowId,
|
|
2319
2717
|
userId: payload.userId,
|
|
2320
2718
|
method: "totp",
|
|
2321
|
-
|
|
2719
|
+
evidence: totpEvidence({
|
|
2720
|
+
factorId: verified.factor.id,
|
|
2721
|
+
acceptedCounter: verified.acceptedCounter,
|
|
2722
|
+
verifiedAt: yield* currentUnixMillis,
|
|
2723
|
+
}),
|
|
2322
2724
|
})
|
|
2323
|
-
.pipe(Effect.
|
|
2324
|
-
|
|
2325
|
-
return yield* mfaPolicyDenied(result.reason);
|
|
2326
|
-
}
|
|
2327
|
-
return yield* dependencies.authHttp.commitAuthenticatedSession(result.session);
|
|
2725
|
+
.pipe(Effect.catch(authFlowMfaHttpFailure));
|
|
2726
|
+
return yield* dependencies.authHttp.commitMfaResult(result);
|
|
2328
2727
|
});
|
|
2329
|
-
export const makeTotpMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.totp_verify_for_flow")(function* (
|
|
2728
|
+
export const makeTotpMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.totp_verify_for_flow")(function* (handlerRequest) {
|
|
2729
|
+
const { payload } = handlerRequest;
|
|
2330
2730
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.totp_verify_for_flow");
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2731
|
+
yield* requireAuthRateLimit("auth.mfa.totp_verify_for_flow", handlerRequest);
|
|
2732
|
+
const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "totp");
|
|
2733
|
+
const user = yield* dependencies.users
|
|
2734
|
+
.findById(pending.userId)
|
|
2735
|
+
.pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA user")));
|
|
2736
|
+
if (Option.isNone(user) || user.value.disabledAt !== undefined) {
|
|
2737
|
+
return yield* mfaInvalidCredentials();
|
|
2738
|
+
}
|
|
2739
|
+
const verification = yield* dependencies.verificationStore
|
|
2740
|
+
.findById(ChallengeId(payload.flowId))
|
|
2741
|
+
.pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA flow")));
|
|
2742
|
+
if (Option.isNone(verification)) {
|
|
2743
|
+
return yield* mfaBadRequest();
|
|
2744
|
+
}
|
|
2334
2745
|
const verified = yield* dependencies.totpFactorManagement
|
|
2335
|
-
.
|
|
2746
|
+
.identifyForUser(totpMfaVerifyForFlowInput(pending.userId, payload, dependencies))
|
|
2336
2747
|
.pipe(Effect.mapError(() => mfaInternalError("Failed to verify TOTP MFA factor")));
|
|
2337
|
-
if (!verified.valid
|
|
2748
|
+
if (!verified.valid ||
|
|
2749
|
+
verified.factor === undefined ||
|
|
2750
|
+
verified.acceptedCounter === undefined) {
|
|
2338
2751
|
return yield* mfaInvalidCredentials();
|
|
2339
2752
|
}
|
|
2753
|
+
if (dependencies.authFlow.prepareMfa === undefined) {
|
|
2754
|
+
return yield* mfaInternalError("Atomic TOTP login is not configured");
|
|
2755
|
+
}
|
|
2756
|
+
const verifiedAt = yield* currentUnixMillis;
|
|
2340
2757
|
const result = yield* dependencies.authFlow
|
|
2341
|
-
.
|
|
2758
|
+
.prepareMfa({
|
|
2342
2759
|
flowId: payload.flowId,
|
|
2343
2760
|
userId: pending.userId,
|
|
2344
2761
|
method: "totp",
|
|
2345
|
-
|
|
2762
|
+
evidence: totpEvidence({
|
|
2763
|
+
factorId: verified.factor.id,
|
|
2764
|
+
acceptedCounter: verified.acceptedCounter,
|
|
2765
|
+
verifiedAt,
|
|
2766
|
+
}),
|
|
2346
2767
|
})
|
|
2347
|
-
.pipe(Effect.
|
|
2768
|
+
.pipe(Effect.catch(authFlowMfaHttpFailure));
|
|
2348
2769
|
if (result._tag === "PolicyDenied") {
|
|
2349
|
-
return yield*
|
|
2770
|
+
return yield* dependencies.authHttp.commitMfaResult(result);
|
|
2771
|
+
}
|
|
2772
|
+
const committedAt = yield* currentUnixMillis;
|
|
2773
|
+
const committed = yield* dependencies.totpLoginCommitStore
|
|
2774
|
+
.commit({
|
|
2775
|
+
verification: verification.value,
|
|
2776
|
+
factorId: verified.factor.id,
|
|
2777
|
+
userId: pending.userId,
|
|
2778
|
+
counter: verified.acceptedCounter,
|
|
2779
|
+
consumedAt: committedAt,
|
|
2780
|
+
lastUsedAt: committedAt,
|
|
2781
|
+
...(payload.metadata === undefined
|
|
2782
|
+
? {}
|
|
2783
|
+
: { factorMetadata: payload.metadata }),
|
|
2784
|
+
...(result._tag === "PreparedAuthenticated"
|
|
2785
|
+
? { session: result.prepared.row }
|
|
2786
|
+
: { continuation: "login-approval" }),
|
|
2787
|
+
})
|
|
2788
|
+
.pipe(Effect.catch(() => Effect.succeed(false)));
|
|
2789
|
+
if (!committed) {
|
|
2790
|
+
return yield* mfaInvalidCredentials();
|
|
2791
|
+
}
|
|
2792
|
+
if (result._tag === "PreparedLoginApproval") {
|
|
2793
|
+
const approval = yield* result.complete.pipe(Effect.catch(authFlowMfaHttpFailure));
|
|
2794
|
+
return yield* dependencies.authHttp.commitMfaResult(approval);
|
|
2350
2795
|
}
|
|
2351
|
-
|
|
2796
|
+
yield* result.notify;
|
|
2797
|
+
return yield* dependencies.authHttp.commitAuthenticatedSession(result.prepared.session);
|
|
2352
2798
|
});
|
|
2353
|
-
export const makeRecoveryCodeMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify")(function* (
|
|
2799
|
+
export const makeRecoveryCodeMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify")(function* (handlerRequest) {
|
|
2800
|
+
const { payload } = handlerRequest;
|
|
2354
2801
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.recovery_code_verify");
|
|
2802
|
+
yield* requireAuthRateLimit("auth.mfa.recovery_code_verify", handlerRequest);
|
|
2803
|
+
const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "backup-code");
|
|
2804
|
+
if (pending.userId !== payload.userId) {
|
|
2805
|
+
return yield* mfaInvalidCredentials();
|
|
2806
|
+
}
|
|
2355
2807
|
const verified = yield* dependencies.recoveryCodeManagement
|
|
2356
2808
|
.verifyForUser(recoveryCodeMfaVerifyInput(payload))
|
|
2357
2809
|
.pipe(Effect.mapError(() => mfaInternalError("Failed to verify recovery code MFA factor")));
|
|
2358
|
-
if (!verified.valid) {
|
|
2810
|
+
if (!verified.valid || verified.code === undefined) {
|
|
2359
2811
|
return yield* mfaInvalidCredentials();
|
|
2360
2812
|
}
|
|
2361
2813
|
const result = yield* dependencies.authFlow
|
|
@@ -2363,71 +2815,159 @@ export const makeRecoveryCodeMfaVerifyHandler = (dependencies) => Effect.fn("aut
|
|
|
2363
2815
|
flowId: payload.flowId,
|
|
2364
2816
|
userId: payload.userId,
|
|
2365
2817
|
method: "backup-code",
|
|
2366
|
-
|
|
2818
|
+
evidence: recoveryCodeEvidence({
|
|
2819
|
+
codeId: verified.code.id,
|
|
2820
|
+
verifiedAt: yield* currentUnixMillis,
|
|
2821
|
+
}),
|
|
2367
2822
|
})
|
|
2368
|
-
.pipe(Effect.
|
|
2369
|
-
|
|
2370
|
-
return yield* mfaPolicyDenied(result.reason);
|
|
2371
|
-
}
|
|
2372
|
-
return yield* dependencies.authHttp.commitAuthenticatedSession(result.session);
|
|
2823
|
+
.pipe(Effect.catch(authFlowMfaHttpFailure));
|
|
2824
|
+
return yield* dependencies.authHttp.commitMfaResult(result);
|
|
2373
2825
|
});
|
|
2374
|
-
export const makeRecoveryCodeMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify_for_flow")(function* (
|
|
2826
|
+
export const makeRecoveryCodeMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify_for_flow")(function* (handlerRequest) {
|
|
2827
|
+
const { payload } = handlerRequest;
|
|
2375
2828
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.recovery_code_verify_for_flow");
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2829
|
+
yield* requireAuthRateLimit("auth.mfa.recovery_code_verify_for_flow", handlerRequest);
|
|
2830
|
+
const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "backup-code");
|
|
2831
|
+
const user = yield* dependencies.users
|
|
2832
|
+
.findById(pending.userId)
|
|
2833
|
+
.pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA user")));
|
|
2834
|
+
if (Option.isNone(user) || user.value.disabledAt !== undefined) {
|
|
2835
|
+
return yield* mfaInvalidCredentials();
|
|
2836
|
+
}
|
|
2837
|
+
const verification = yield* dependencies.verificationStore
|
|
2838
|
+
.findById(ChallengeId(payload.flowId))
|
|
2839
|
+
.pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA flow")));
|
|
2840
|
+
if (Option.isNone(verification)) {
|
|
2841
|
+
return yield* mfaBadRequest();
|
|
2842
|
+
}
|
|
2379
2843
|
const verified = yield* dependencies.recoveryCodeManagement
|
|
2380
|
-
.
|
|
2844
|
+
.identifyForUser(recoveryCodeMfaVerifyForFlowInput(pending.userId, payload))
|
|
2381
2845
|
.pipe(Effect.mapError(() => mfaInternalError("Failed to verify recovery code MFA factor")));
|
|
2382
|
-
if (!verified.valid) {
|
|
2846
|
+
if (!verified.valid || verified.code === undefined) {
|
|
2383
2847
|
return yield* mfaInvalidCredentials();
|
|
2384
2848
|
}
|
|
2849
|
+
if (dependencies.authFlow.prepareMfa === undefined) {
|
|
2850
|
+
return yield* mfaInternalError("Atomic recovery-code login is not configured");
|
|
2851
|
+
}
|
|
2852
|
+
const verifiedAt = yield* currentUnixMillis;
|
|
2385
2853
|
const result = yield* dependencies.authFlow
|
|
2386
|
-
.
|
|
2854
|
+
.prepareMfa({
|
|
2387
2855
|
flowId: payload.flowId,
|
|
2388
2856
|
userId: pending.userId,
|
|
2389
2857
|
method: "backup-code",
|
|
2390
|
-
|
|
2858
|
+
evidence: recoveryCodeEvidence({
|
|
2859
|
+
codeId: verified.code.id,
|
|
2860
|
+
verifiedAt,
|
|
2861
|
+
}),
|
|
2391
2862
|
})
|
|
2392
|
-
.pipe(Effect.
|
|
2863
|
+
.pipe(Effect.catch(authFlowMfaHttpFailure));
|
|
2393
2864
|
if (result._tag === "PolicyDenied") {
|
|
2394
|
-
return yield*
|
|
2865
|
+
return yield* dependencies.authHttp.commitMfaResult(result);
|
|
2866
|
+
}
|
|
2867
|
+
const committedAt = yield* currentUnixMillis;
|
|
2868
|
+
const committed = yield* dependencies.recoveryCodeLoginCommitStore
|
|
2869
|
+
.commit({
|
|
2870
|
+
verification: verification.value,
|
|
2871
|
+
codeId: verified.code.id,
|
|
2872
|
+
userId: pending.userId,
|
|
2873
|
+
consumedAt: committedAt,
|
|
2874
|
+
usedAt: committedAt,
|
|
2875
|
+
...(payload.metadata === undefined
|
|
2876
|
+
? {}
|
|
2877
|
+
: { codeMetadata: payload.metadata }),
|
|
2878
|
+
...(result._tag === "PreparedAuthenticated"
|
|
2879
|
+
? { session: result.prepared.row }
|
|
2880
|
+
: { continuation: "login-approval" }),
|
|
2881
|
+
})
|
|
2882
|
+
.pipe(Effect.catch(() => Effect.succeed(false)));
|
|
2883
|
+
if (!committed) {
|
|
2884
|
+
return yield* mfaInvalidCredentials();
|
|
2885
|
+
}
|
|
2886
|
+
if (result._tag === "PreparedLoginApproval") {
|
|
2887
|
+
const approval = yield* result.complete.pipe(Effect.catch(authFlowMfaHttpFailure));
|
|
2888
|
+
return yield* dependencies.authHttp.commitMfaResult(approval);
|
|
2395
2889
|
}
|
|
2396
|
-
|
|
2890
|
+
yield* result.notify;
|
|
2891
|
+
return yield* dependencies.authHttp.commitAuthenticatedSession(result.prepared.session);
|
|
2397
2892
|
});
|
|
2398
|
-
export const makePasskeyMfaStartHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_start")(function* (
|
|
2893
|
+
export const makePasskeyMfaStartHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_start")(function* (handlerRequest) {
|
|
2894
|
+
const { payload } = handlerRequest;
|
|
2399
2895
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.passkey_start");
|
|
2896
|
+
yield* requireAuthRateLimit("auth.mfa.passkey_start", handlerRequest);
|
|
2400
2897
|
const pending = yield* dependencies.authFlowState
|
|
2401
2898
|
.inspect(payload.flowId)
|
|
2402
2899
|
.pipe(Effect.mapError(() => mfaBadRequest()));
|
|
2900
|
+
if (pending.factors?.some((factor) => factor.type === "passkey") !== true) {
|
|
2901
|
+
return yield* mfaBadRequest();
|
|
2902
|
+
}
|
|
2403
2903
|
return yield* dependencies.passkeyOptions
|
|
2404
2904
|
.startAuthentication(passkeyMfaStartInput(pending.userId, payload, dependencies))
|
|
2405
2905
|
.pipe(Effect.mapError(() => passkeyInternalError("Failed to start passkey MFA authentication")));
|
|
2406
2906
|
});
|
|
2407
|
-
export const makePasskeyMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_verify")(function* (
|
|
2907
|
+
export const makePasskeyMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_verify")(function* (handlerRequest) {
|
|
2908
|
+
const { payload } = handlerRequest;
|
|
2408
2909
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.passkey_verify");
|
|
2910
|
+
yield* requireAuthRateLimit("auth.mfa.passkey_verify", handlerRequest);
|
|
2911
|
+
const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "passkey");
|
|
2409
2912
|
const finished = yield* dependencies.passkeyVerification
|
|
2410
|
-
.finishAuthentication(passkeyMfaVerifyInput(payload, dependencies))
|
|
2913
|
+
.finishAuthentication(passkeyMfaVerifyInput(payload, dependencies, pending.userId))
|
|
2411
2914
|
.pipe(Effect.mapError(passkeyVerificationHttpError));
|
|
2915
|
+
if (finished.userVerification !== "verified") {
|
|
2916
|
+
return yield* mfaBadRequest();
|
|
2917
|
+
}
|
|
2412
2918
|
const result = yield* dependencies.authFlow
|
|
2413
2919
|
.completeMfa({
|
|
2414
2920
|
flowId: payload.flowId,
|
|
2415
2921
|
userId: finished.userId,
|
|
2416
2922
|
method: "passkey",
|
|
2417
|
-
|
|
2923
|
+
evidence: passkeyEvidence({
|
|
2924
|
+
credentialId: CredentialId(finished.credential.id),
|
|
2925
|
+
verifiedAt: yield* currentUnixMillis,
|
|
2926
|
+
userVerification: finished.userVerification,
|
|
2927
|
+
...(finished.authenticatorAttachment === undefined
|
|
2928
|
+
? {}
|
|
2929
|
+
: { authenticatorAttachment: finished.authenticatorAttachment }),
|
|
2930
|
+
...(finished.backedUp === undefined
|
|
2931
|
+
? {}
|
|
2932
|
+
: { backedUp: finished.backedUp }),
|
|
2933
|
+
...(finished.backupEligible === undefined
|
|
2934
|
+
? {}
|
|
2935
|
+
: { backupEligible: finished.backupEligible }),
|
|
2936
|
+
signCount: finished.signCount,
|
|
2937
|
+
...(finished.aaguid === undefined ? {} : { aaguid: finished.aaguid }),
|
|
2938
|
+
}),
|
|
2418
2939
|
})
|
|
2419
|
-
.pipe(Effect.
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2940
|
+
.pipe(Effect.catch(authFlowMfaHttpFailure));
|
|
2941
|
+
return yield* dependencies.authHttp.commitMfaResult(result);
|
|
2942
|
+
});
|
|
2943
|
+
const upgradeStepUpSession = (dependencies, current, evidence, claims) => dependencies.sessions
|
|
2944
|
+
.assureAndRotate({
|
|
2945
|
+
token: current.issued.token,
|
|
2946
|
+
evidence,
|
|
2947
|
+
claims,
|
|
2948
|
+
reason: "step_up",
|
|
2949
|
+
})
|
|
2950
|
+
.pipe(Effect.flatMap((issued) => dependencies.sessionCookie.commit(issued).pipe(Effect.flatMap((cookie) => HttpServerResponse.json(stepUpAuthenticatedHttpBody(issued), {
|
|
2951
|
+
status: 200,
|
|
2952
|
+
headers: { "set-cookie": cookie },
|
|
2953
|
+
})))), Effect.mapError(() => stepUpInternalError("Failed to upgrade current session")));
|
|
2954
|
+
const reauthenticateStepUpSession = (dependencies, current, evidence) => upgradeStepUpSession(dependencies, current, evidence);
|
|
2955
|
+
export const makeStepUpOptionsHandler = (dependencies) => Effect.fn("auth.http.step_up.options")(function* (handlerRequest) {
|
|
2956
|
+
const { request } = handlerRequest;
|
|
2427
2957
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.options");
|
|
2428
2958
|
const current = yield* readRequiredSession(dependencies, request);
|
|
2959
|
+
yield* requireAuthRateLimit("auth.step_up.options", handlerRequest, current.currentSession.userId);
|
|
2429
2960
|
const { userId } = current.currentSession;
|
|
2430
2961
|
const factors = [];
|
|
2962
|
+
if (dependencies.credentials !== undefined) {
|
|
2963
|
+
const passwordCredential = yield* dependencies.credentials
|
|
2964
|
+
.findPasswordByUserId(userId)
|
|
2965
|
+
.pipe(Effect.mapError(() => stepUpInternalError("Failed to list step-up options")));
|
|
2966
|
+
if (Option.isSome(passwordCredential) &&
|
|
2967
|
+
passwordCredential.value.revokedAt === undefined) {
|
|
2968
|
+
factors.push({ type: "password" });
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2431
2971
|
if (dependencies.totpFactorManagement !== undefined) {
|
|
2432
2972
|
const totpFactors = yield* dependencies.totpFactorManagement
|
|
2433
2973
|
.listForUser({ userId })
|
|
@@ -2454,90 +2994,234 @@ export const makeStepUpOptionsHandler = (dependencies) => Effect.fn("auth.http.s
|
|
|
2454
2994
|
}
|
|
2455
2995
|
return { factors };
|
|
2456
2996
|
});
|
|
2457
|
-
export const makeStepUpTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.totp_verify")(function* (
|
|
2997
|
+
export const makeStepUpTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.totp_verify")(function* (handlerRequest) {
|
|
2998
|
+
const { payload, request } = handlerRequest;
|
|
2458
2999
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.totp_verify");
|
|
2459
3000
|
const current = yield* readRequiredSession(dependencies, request);
|
|
3001
|
+
yield* requireAuthRateLimit("auth.step_up.totp_verify", handlerRequest, current.currentSession.userId);
|
|
2460
3002
|
const verified = yield* dependencies.totpFactorManagement
|
|
2461
|
-
.
|
|
3003
|
+
.identifyForUser(stepUpTotpVerifyInput(current.currentSession.userId, payload, dependencies))
|
|
2462
3004
|
.pipe(Effect.mapError(() => stepUpInternalError("Failed to verify TOTP step-up factor")));
|
|
2463
3005
|
if (!verified.valid) {
|
|
2464
3006
|
return yield* stepUpInvalidCredentials();
|
|
2465
3007
|
}
|
|
2466
|
-
|
|
3008
|
+
if (verified.factor === undefined ||
|
|
3009
|
+
verified.acceptedCounter === undefined) {
|
|
3010
|
+
return yield* stepUpInvalidCredentials();
|
|
3011
|
+
}
|
|
3012
|
+
const issued = yield* dependencies.totpSessionRotation
|
|
3013
|
+
.acceptAndRotate({
|
|
3014
|
+
token: current.issued.token,
|
|
3015
|
+
factorId: verified.factor.id,
|
|
3016
|
+
userId: current.currentSession.userId,
|
|
3017
|
+
acceptedCounter: verified.acceptedCounter,
|
|
3018
|
+
expectedAuthenticationEvents: current.currentSession.authenticationEvents,
|
|
3019
|
+
...(payload.metadata === undefined
|
|
3020
|
+
? {}
|
|
3021
|
+
: { factorMetadata: payload.metadata }),
|
|
3022
|
+
evidence: totpEvidence({
|
|
3023
|
+
factorId: verified.factor.id,
|
|
3024
|
+
acceptedCounter: verified.acceptedCounter,
|
|
3025
|
+
verifiedAt: yield* currentUnixMillis,
|
|
3026
|
+
}),
|
|
3027
|
+
reason: "step_up",
|
|
3028
|
+
})
|
|
3029
|
+
.pipe(Effect.catch(stepUpRotationHttpFailure));
|
|
3030
|
+
const cookie = yield* dependencies.sessionCookie
|
|
3031
|
+
.commit(issued)
|
|
3032
|
+
.pipe(Effect.mapError(() => stepUpInternalError("Failed to commit upgraded session")));
|
|
3033
|
+
return yield* HttpServerResponse.json(stepUpAuthenticatedHttpBody(issued), {
|
|
3034
|
+
status: 200,
|
|
3035
|
+
headers: { "set-cookie": cookie },
|
|
3036
|
+
}).pipe(Effect.mapError(() => stepUpInternalError("Failed to encode upgraded session")));
|
|
3037
|
+
});
|
|
3038
|
+
export const makeStepUpPasswordVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.password_verify")(function* (handlerRequest) {
|
|
3039
|
+
const { payload, request } = handlerRequest;
|
|
3040
|
+
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.password_verify");
|
|
3041
|
+
const current = yield* readRequiredSession(dependencies, request);
|
|
3042
|
+
yield* requireAuthRateLimit("auth.step_up.password_verify", handlerRequest, current.currentSession.userId);
|
|
3043
|
+
const input = stepUpPasswordVerifyInput(payload);
|
|
3044
|
+
const credential = yield* dependencies.credentials
|
|
3045
|
+
.findPasswordByUserId(current.currentSession.userId)
|
|
3046
|
+
.pipe(Effect.mapError(() => stepUpInternalError("Failed to verify password step-up factor")));
|
|
3047
|
+
if (Option.isNone(credential) || credential.value.revokedAt !== undefined) {
|
|
3048
|
+
return yield* stepUpInvalidCredentials();
|
|
3049
|
+
}
|
|
3050
|
+
const verified = yield* dependencies.hasher
|
|
3051
|
+
.verify({ hash: credential.value.passwordHash, password: input.password })
|
|
3052
|
+
.pipe(Effect.mapError(() => stepUpInternalError("Failed to verify password step-up factor")));
|
|
3053
|
+
if (!verified) {
|
|
3054
|
+
return yield* stepUpInvalidCredentials();
|
|
3055
|
+
}
|
|
3056
|
+
return yield* reauthenticateStepUpSession(dependencies, current, passwordEvidence({
|
|
3057
|
+
credentialId: credential.value.id,
|
|
3058
|
+
verifiedAt: yield* currentUnixMillis,
|
|
3059
|
+
}));
|
|
2467
3060
|
});
|
|
2468
|
-
export const makeStepUpRecoveryCodeVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.recovery_code_verify")(function* (
|
|
3061
|
+
export const makeStepUpRecoveryCodeVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.recovery_code_verify")(function* (handlerRequest) {
|
|
3062
|
+
const { payload, request } = handlerRequest;
|
|
2469
3063
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.recovery_code_verify");
|
|
2470
3064
|
const current = yield* readRequiredSession(dependencies, request);
|
|
3065
|
+
yield* requireAuthRateLimit("auth.step_up.recovery_code_verify", handlerRequest, current.currentSession.userId);
|
|
2471
3066
|
const verified = yield* dependencies.recoveryCodeManagement
|
|
2472
|
-
.
|
|
3067
|
+
.identifyForUser(stepUpRecoveryCodeVerifyInput(current.currentSession.userId, payload))
|
|
2473
3068
|
.pipe(Effect.mapError(() => stepUpInternalError("Failed to verify recovery-code step-up factor")));
|
|
2474
3069
|
if (!verified.valid) {
|
|
2475
3070
|
return yield* stepUpInvalidCredentials();
|
|
2476
3071
|
}
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
3072
|
+
if (verified.code === undefined) {
|
|
3073
|
+
return yield* stepUpInvalidCredentials();
|
|
3074
|
+
}
|
|
3075
|
+
const evidence = recoveryCodeEvidence({
|
|
3076
|
+
codeId: verified.code.id,
|
|
3077
|
+
verifiedAt: yield* currentUnixMillis,
|
|
3078
|
+
});
|
|
3079
|
+
const issued = yield* dependencies.recoveryCodeSessionRotation
|
|
3080
|
+
.consumeAndRotate({
|
|
3081
|
+
token: current.issued.token,
|
|
3082
|
+
codeId: verified.code.id,
|
|
3083
|
+
userId: current.currentSession.userId,
|
|
3084
|
+
expectedAuthenticationEvents: current.currentSession.authenticationEvents,
|
|
3085
|
+
evidence,
|
|
3086
|
+
claims: withRecoveryRemediationRequirement(current.currentSession.claims, defaultRecoveryRemediationCapabilities),
|
|
3087
|
+
reason: "recovery_code_step_up",
|
|
3088
|
+
})
|
|
3089
|
+
.pipe(Effect.catch(stepUpRotationHttpFailure));
|
|
3090
|
+
const cookie = yield* dependencies.sessionCookie
|
|
3091
|
+
.commit(issued)
|
|
3092
|
+
.pipe(Effect.mapError(() => stepUpInternalError("Failed to commit recovery session")));
|
|
3093
|
+
return yield* HttpServerResponse.json(stepUpAuthenticatedHttpBody(issued), {
|
|
3094
|
+
status: 200,
|
|
3095
|
+
headers: { "set-cookie": cookie },
|
|
3096
|
+
}).pipe(Effect.mapError(() => stepUpInternalError("Failed to encode recovery session")));
|
|
3097
|
+
});
|
|
3098
|
+
export const makeStepUpPasskeyStartHandler = (dependencies) => Effect.fn("auth.http.step_up.passkey_start")(function* (handlerRequest) {
|
|
3099
|
+
const { payload, request } = handlerRequest;
|
|
2480
3100
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.passkey_start");
|
|
2481
3101
|
const current = yield* readRequiredSession(dependencies, request);
|
|
3102
|
+
yield* requireAuthRateLimit("auth.step_up.passkey_start", handlerRequest, current.currentSession.userId);
|
|
2482
3103
|
return yield* dependencies.passkeyOptions
|
|
2483
3104
|
.startAuthentication(stepUpPasskeyStartInput(current.currentSession.userId, payload, dependencies))
|
|
2484
3105
|
.pipe(Effect.mapError((error) => error.cause === undefined
|
|
2485
3106
|
? stepUpBadRequest()
|
|
2486
3107
|
: stepUpInternalError("Failed to start passkey step-up")));
|
|
2487
3108
|
});
|
|
2488
|
-
export const makeStepUpPasskeyVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.passkey_verify")(function* (
|
|
3109
|
+
export const makeStepUpPasskeyVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.passkey_verify")(function* (handlerRequest) {
|
|
3110
|
+
const { payload, request } = handlerRequest;
|
|
2489
3111
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.passkey_verify");
|
|
2490
3112
|
const current = yield* readRequiredSession(dependencies, request);
|
|
3113
|
+
yield* requireAuthRateLimit("auth.step_up.passkey_verify", handlerRequest, current.currentSession.userId);
|
|
2491
3114
|
const finished = yield* dependencies.passkeyVerification
|
|
2492
3115
|
.finishAuthentication(stepUpPasskeyVerifyInput(current.currentSession.userId, payload, dependencies))
|
|
2493
3116
|
.pipe(Effect.mapError(passkeyVerificationHttpError));
|
|
3117
|
+
if (finished.userVerification !== "verified") {
|
|
3118
|
+
return yield* stepUpPolicyDenied("Passkey user verification was not confirmed");
|
|
3119
|
+
}
|
|
2494
3120
|
if (finished.userId !== current.currentSession.userId) {
|
|
2495
3121
|
return yield* stepUpPolicyDenied("Passkey belongs to a different user");
|
|
2496
3122
|
}
|
|
2497
|
-
return yield* upgradeStepUpSession(dependencies, current,
|
|
3123
|
+
return yield* upgradeStepUpSession(dependencies, current, passkeyEvidence({
|
|
3124
|
+
credentialId: CredentialId(finished.credential.id),
|
|
3125
|
+
verifiedAt: yield* currentUnixMillis,
|
|
3126
|
+
userVerification: finished.userVerification,
|
|
3127
|
+
...(finished.authenticatorAttachment === undefined
|
|
3128
|
+
? {}
|
|
3129
|
+
: { authenticatorAttachment: finished.authenticatorAttachment }),
|
|
3130
|
+
...(finished.backedUp === undefined
|
|
3131
|
+
? {}
|
|
3132
|
+
: { backedUp: finished.backedUp }),
|
|
3133
|
+
...(finished.backupEligible === undefined
|
|
3134
|
+
? {}
|
|
3135
|
+
: { backupEligible: finished.backupEligible }),
|
|
3136
|
+
signCount: finished.signCount,
|
|
3137
|
+
...(finished.aaguid === undefined ? {} : { aaguid: finished.aaguid }),
|
|
3138
|
+
}));
|
|
2498
3139
|
});
|
|
2499
|
-
export const makeLoginApprovalApproveHandler = (dependencies) =>
|
|
3140
|
+
export const makeLoginApprovalApproveHandler = (dependencies) =>
|
|
3141
|
+
// oxlint-disable-next-line eslint/complexity -- approval preflight intentionally validates every binding before either one-time state is consumed.
|
|
3142
|
+
Effect.fn("auth.http.login_approval.approve")(function* ({ payload, request, }) {
|
|
2500
3143
|
yield* Effect.annotateCurrentSpan("auth.http.endpoint", "login_approval.approve");
|
|
2501
3144
|
const input = loginApprovalApproveInput(payload);
|
|
2502
|
-
const
|
|
2503
|
-
.
|
|
3145
|
+
const inspectedApproval = yield* dependencies.loginApproval
|
|
3146
|
+
.inspect(input.approval)
|
|
2504
3147
|
.pipe(Effect.mapError(() => loginApprovalBadRequest()));
|
|
2505
|
-
const approvedFlowId = metadataString(
|
|
3148
|
+
const approvedFlowId = metadataString(inspectedApproval.metadata, "flowId");
|
|
2506
3149
|
if (approvedFlowId !== input.flowId) {
|
|
2507
3150
|
return yield* loginApprovalBadRequest();
|
|
2508
3151
|
}
|
|
2509
|
-
if (
|
|
3152
|
+
if (inspectedApproval.sessionBinding === "none") {
|
|
2510
3153
|
return yield* loginApprovalNoSessionBindingDenied();
|
|
2511
3154
|
}
|
|
2512
|
-
const sameDeviceSecret =
|
|
3155
|
+
const sameDeviceSecret = inspectedApproval.sameDeviceRequired
|
|
2513
3156
|
? yield* dependencies.loginApprovalPendingCookie
|
|
2514
3157
|
.read(new Request("http://localhost", { headers: request.headers }))
|
|
2515
3158
|
.pipe(Effect.flatMap((secret) => Option.isSome(secret)
|
|
2516
3159
|
? Effect.succeed(secret.value)
|
|
2517
3160
|
: Effect.fail(loginApprovalSameDeviceDenied())))
|
|
2518
3161
|
: undefined;
|
|
3162
|
+
const inspectedFlow = yield* dependencies.authFlowState
|
|
3163
|
+
.inspect(input.flowId, sameDeviceSecret)
|
|
3164
|
+
.pipe(Effect.mapError(() => inspectedApproval.sameDeviceRequired
|
|
3165
|
+
? loginApprovalSameDeviceDenied()
|
|
3166
|
+
: loginApprovalBadRequest()));
|
|
3167
|
+
if (inspectedFlow.userId !== inspectedApproval.userId) {
|
|
3168
|
+
return yield* loginApprovalBadRequest();
|
|
3169
|
+
}
|
|
3170
|
+
const identity = inspectedApproval.markIdentityVerified === true
|
|
3171
|
+
? inspectedApproval.identityId === undefined
|
|
3172
|
+
? Option.none()
|
|
3173
|
+
: yield* dependencies.identities
|
|
3174
|
+
.findById(inspectedApproval.identityId)
|
|
3175
|
+
.pipe(Effect.mapError(() => passwordInternalError("Failed to load identity for verification")))
|
|
3176
|
+
: Option.none();
|
|
3177
|
+
if (inspectedApproval.markIdentityVerified === true &&
|
|
3178
|
+
(Option.isNone(identity) ||
|
|
3179
|
+
identity.value.userId !== inspectedApproval.userId)) {
|
|
3180
|
+
return yield* loginApprovalBadRequest();
|
|
3181
|
+
}
|
|
3182
|
+
const approval = yield* dependencies.loginApproval
|
|
3183
|
+
.verify(input.approval)
|
|
3184
|
+
.pipe(Effect.mapError(() => loginApprovalBadRequest()));
|
|
3185
|
+
if (metadataString(approval.metadata, "flowId") !== input.flowId ||
|
|
3186
|
+
approval.userId !== inspectedApproval.userId ||
|
|
3187
|
+
approval.sessionBinding !== inspectedApproval.sessionBinding ||
|
|
3188
|
+
approval.sameDeviceRequired !== inspectedApproval.sameDeviceRequired ||
|
|
3189
|
+
approval.markIdentityVerified !==
|
|
3190
|
+
inspectedApproval.markIdentityVerified ||
|
|
3191
|
+
approval.identityId !== inspectedApproval.identityId) {
|
|
3192
|
+
return yield* loginApprovalBadRequest();
|
|
3193
|
+
}
|
|
2519
3194
|
const consumed = yield* dependencies.authFlowState
|
|
2520
3195
|
.consume(input.flowId, sameDeviceSecret)
|
|
2521
3196
|
.pipe(Effect.mapError(() => approval.sameDeviceRequired
|
|
2522
3197
|
? loginApprovalSameDeviceDenied()
|
|
2523
3198
|
: loginApprovalBadRequest()));
|
|
2524
|
-
if (consumed.userId !== approval.userId
|
|
3199
|
+
if (consumed.userId !== approval.userId ||
|
|
3200
|
+
consumed.userId !== inspectedFlow.userId) {
|
|
2525
3201
|
return yield* loginApprovalBadRequest();
|
|
2526
3202
|
}
|
|
2527
|
-
if (approval.
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
3203
|
+
if (approval.markIdentityVerified === true) {
|
|
3204
|
+
if (approval.identityId === undefined || Option.isNone(identity)) {
|
|
3205
|
+
return yield* loginApprovalBadRequest();
|
|
3206
|
+
}
|
|
3207
|
+
const updated = yield* dependencies.identities
|
|
3208
|
+
.markVerified({
|
|
3209
|
+
id: approval.identityId,
|
|
3210
|
+
expectedNormalizedValue: identity.value.normalizedValue,
|
|
3211
|
+
verifiedAt: yield* currentUnixMillis,
|
|
2532
3212
|
})
|
|
2533
|
-
.pipe(Effect.mapError(() => passwordInternalError("Failed to mark
|
|
3213
|
+
.pipe(Effect.mapError(() => passwordInternalError("Failed to mark identity verified")));
|
|
2534
3214
|
if (Option.isNone(updated)) {
|
|
2535
3215
|
return yield* loginApprovalBadRequest();
|
|
2536
3216
|
}
|
|
2537
3217
|
}
|
|
2538
|
-
const result = yield* dependencies
|
|
2539
|
-
.
|
|
2540
|
-
.pipe(Effect.
|
|
3218
|
+
const result = yield* dependencies
|
|
3219
|
+
.finalizeAuthFlow(consumed)
|
|
3220
|
+
.pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to complete login approval") ??
|
|
3221
|
+
Effect.fail(passwordInternalError("Failed to complete login approval"))));
|
|
3222
|
+
if (result._tag === "PolicyDenied") {
|
|
3223
|
+
return yield* loginApprovalPolicyDenied();
|
|
3224
|
+
}
|
|
2541
3225
|
const setCookies = yield* trustedDeviceSetCookies({
|
|
2542
3226
|
trustedDevice: dependencies.trustedDevice,
|
|
2543
3227
|
trustedDeviceCookie: dependencies.trustedDeviceCookie,
|
|
@@ -2586,9 +3270,10 @@ export const makeLoginApprovalFinalizeHandler = (dependencies) => Effect.fn("aut
|
|
|
2586
3270
|
? { sameDeviceSecret: sameDeviceSecret.value }
|
|
2587
3271
|
: {}),
|
|
2588
3272
|
})
|
|
2589
|
-
.pipe(Effect.
|
|
2590
|
-
|
|
2591
|
-
|
|
3273
|
+
.pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to finalize login approval") ??
|
|
3274
|
+
Effect.fail(error._tag === "AuthFlowStateError"
|
|
3275
|
+
? loginApprovalSameDeviceDenied()
|
|
3276
|
+
: passwordInternalError("Failed to finalize login approval"))));
|
|
2592
3277
|
if (result._tag === "PolicyDenied") {
|
|
2593
3278
|
return yield* loginApprovalPolicyDenied(result.reason);
|
|
2594
3279
|
}
|
|
@@ -2600,427 +3285,1006 @@ export const makeLoginApprovalFinalizeHandler = (dependencies) => Effect.fn("aut
|
|
|
2600
3285
|
});
|
|
2601
3286
|
return yield* dependencies.authHttp.commitAuthenticatedSession(result.session, { setCookies });
|
|
2602
3287
|
});
|
|
2603
|
-
export
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
.
|
|
2608
|
-
}
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
}
|
|
2613
|
-
|
|
3288
|
+
export const SessionHttpOperationsLive = Layer.effect(SessionHttpOperations, Effect.gen(function* () {
|
|
3289
|
+
const sessions = yield* Sessions;
|
|
3290
|
+
const sessionCookie = yield* SessionCookie;
|
|
3291
|
+
const authHttp = yield* AuthHttp;
|
|
3292
|
+
return SessionHttpOperations.of({
|
|
3293
|
+
current: makeCurrentSessionHandler({ sessions, sessionCookie, authHttp }),
|
|
3294
|
+
refresh: makeRefreshSessionHandler({ sessions, sessionCookie, authHttp }),
|
|
3295
|
+
logout: makeLogoutHandler({ sessions, sessionCookie, authHttp }),
|
|
3296
|
+
list: makeListSessionsHandler({ sessions, sessionCookie }),
|
|
3297
|
+
revoke: makeRevokeSessionHandler({ sessions, sessionCookie, authHttp }),
|
|
3298
|
+
revokeOthers: makeRevokeOtherSessionsHandler({ sessions, sessionCookie }),
|
|
3299
|
+
});
|
|
3300
|
+
}));
|
|
3301
|
+
export const EmailVerificationHttpOperationsLive = Layer.effect(EmailVerificationHttpOperations, Effect.gen(function* () {
|
|
3302
|
+
const emailVerificationFlow = yield* EmailVerificationFlow;
|
|
3303
|
+
const emailVerification = yield* EmailVerification;
|
|
3304
|
+
const identities = yield* IdentityStore;
|
|
3305
|
+
const sessions = yield* Sessions;
|
|
3306
|
+
const sessionCookie = yield* SessionCookie;
|
|
3307
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3308
|
+
const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
|
|
3309
|
+
const guardServices = {
|
|
3310
|
+
authRateLimit,
|
|
3311
|
+
identities,
|
|
3312
|
+
...(Option.isSome(botChallengeVerifier)
|
|
3313
|
+
? { botChallengeVerifier: botChallengeVerifier.value }
|
|
3314
|
+
: {}),
|
|
3315
|
+
};
|
|
3316
|
+
return EmailVerificationHttpOperations.of({
|
|
3317
|
+
start: provideRequestGuardServices(guardServices, makeEmailVerificationStartHandler({
|
|
3318
|
+
emailVerificationFlow,
|
|
3319
|
+
})),
|
|
3320
|
+
verify: makeEmailVerificationVerifyHandler({
|
|
3321
|
+
emailVerification,
|
|
3322
|
+
sessions,
|
|
3323
|
+
sessionCookie,
|
|
3324
|
+
}),
|
|
3325
|
+
});
|
|
3326
|
+
}));
|
|
3327
|
+
export const EmailOtpHttpOperationsLive = Layer.effect(EmailOtpHttpOperations, Effect.gen(function* () {
|
|
3328
|
+
const emailOtp = yield* EmailOtpLogin;
|
|
3329
|
+
const authHttp = yield* AuthHttp;
|
|
3330
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3331
|
+
const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
|
|
3332
|
+
const cookie = yield* Effect.serviceOption(TrustedDeviceCookie);
|
|
3333
|
+
const guardServices = {
|
|
3334
|
+
authRateLimit,
|
|
3335
|
+
...(Option.isSome(botChallengeVerifier)
|
|
3336
|
+
? { botChallengeVerifier: botChallengeVerifier.value }
|
|
3337
|
+
: {}),
|
|
3338
|
+
...(Option.isSome(cookie) ? { trustedDeviceCookie: cookie.value } : {}),
|
|
3339
|
+
};
|
|
3340
|
+
return EmailOtpHttpOperations.of({
|
|
3341
|
+
start: provideRequestGuardServices(guardServices, makeEmailOtpStartHandler({ emailOtp })),
|
|
3342
|
+
verify: provideRequestGuardServices(guardServices, makeEmailOtpVerifyHandler({
|
|
3343
|
+
emailOtp,
|
|
3344
|
+
authHttp,
|
|
3345
|
+
})),
|
|
3346
|
+
});
|
|
3347
|
+
}));
|
|
3348
|
+
export const EmailAuthHttpOperationsLive = Layer.effect(EmailAuthHttpOperations, Effect.gen(function* () {
|
|
3349
|
+
const emailAuth = yield* EmailAuth;
|
|
3350
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3351
|
+
const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
|
|
3352
|
+
const guardServices = {
|
|
3353
|
+
authRateLimit,
|
|
3354
|
+
...(Option.isSome(botChallengeVerifier)
|
|
3355
|
+
? { botChallengeVerifier: botChallengeVerifier.value }
|
|
3356
|
+
: {}),
|
|
3357
|
+
};
|
|
3358
|
+
return EmailAuthHttpOperations.of({
|
|
3359
|
+
start: provideRequestGuardServices(guardServices, makeEmailAuthStartHandler({ emailAuth })),
|
|
3360
|
+
});
|
|
3361
|
+
}));
|
|
3362
|
+
export const MagicLinkHttpOperationsLive = Layer.effect(MagicLinkHttpOperations, Effect.gen(function* () {
|
|
3363
|
+
const magicLink = yield* MagicLinkLogin;
|
|
3364
|
+
const authHttp = yield* AuthHttp;
|
|
3365
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3366
|
+
const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
|
|
3367
|
+
const cookie = yield* Effect.serviceOption(TrustedDeviceCookie);
|
|
3368
|
+
const guardServices = {
|
|
3369
|
+
authRateLimit,
|
|
3370
|
+
...(Option.isSome(botChallengeVerifier)
|
|
3371
|
+
? { botChallengeVerifier: botChallengeVerifier.value }
|
|
3372
|
+
: {}),
|
|
3373
|
+
...(Option.isSome(cookie) ? { trustedDeviceCookie: cookie.value } : {}),
|
|
3374
|
+
};
|
|
3375
|
+
return MagicLinkHttpOperations.of({
|
|
3376
|
+
start: provideRequestGuardServices(guardServices, makeMagicLinkStartHandler({ magicLink })),
|
|
3377
|
+
verify: provideRequestGuardServices(guardServices, makeMagicLinkVerifyHandler({
|
|
3378
|
+
magicLink,
|
|
3379
|
+
authHttp,
|
|
3380
|
+
})),
|
|
3381
|
+
});
|
|
3382
|
+
}));
|
|
3383
|
+
export const PasskeyHttpOperationsLive = Layer.effect(PasskeyHttpOperations, Effect.gen(function* () {
|
|
3384
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3385
|
+
const config = yield* PasskeyHttpConfig;
|
|
3386
|
+
const passkeyOptions = yield* PasskeyOptions;
|
|
3387
|
+
const passkeyVerification = yield* PasskeyVerification;
|
|
3388
|
+
const passkeyCredentialManagement = yield* PasskeyCredentialManagement;
|
|
3389
|
+
const sessions = yield* Sessions;
|
|
3390
|
+
const sessionCookie = yield* SessionCookie;
|
|
3391
|
+
const authHttp = yield* AuthHttp;
|
|
3392
|
+
const users = yield* UserStore;
|
|
3393
|
+
const identities = yield* IdentityStore;
|
|
3394
|
+
const policy = yield* Effect.serviceOption(StrongFactorRemovalPolicy);
|
|
3395
|
+
const resolveUser = makePasskeyRegistrationUserResolver({
|
|
3396
|
+
users,
|
|
3397
|
+
identities,
|
|
3398
|
+
});
|
|
3399
|
+
return PasskeyHttpOperations.of({
|
|
3400
|
+
registerStart: provideHandlerAuthRateLimit(authRateLimit, makePasskeyRegistrationStartHandler({
|
|
3401
|
+
passkeyOptions,
|
|
3402
|
+
sessions,
|
|
3403
|
+
sessionCookie,
|
|
3404
|
+
resolveUser,
|
|
3405
|
+
...passkeyRegistrationStartHttpOptions(config),
|
|
3406
|
+
})),
|
|
3407
|
+
registerFinish: provideHandlerAuthRateLimit(authRateLimit, makePasskeyRegistrationFinishHandler({
|
|
3408
|
+
passkeyVerification,
|
|
3409
|
+
sessions,
|
|
3410
|
+
sessionCookie,
|
|
3411
|
+
resolveUser,
|
|
3412
|
+
...passkeyFinishHttpOptions(config),
|
|
3413
|
+
})),
|
|
3414
|
+
authenticateStart: provideHandlerAuthRateLimit(authRateLimit, makePasskeyAuthenticationStartHandler({
|
|
3415
|
+
passkeyOptions,
|
|
3416
|
+
...passkeyAuthenticationStartHttpOptions(config),
|
|
3417
|
+
})),
|
|
3418
|
+
authenticateFinish: provideHandlerAuthRateLimit(authRateLimit, makePasskeyAuthenticationFinishHandler({
|
|
3419
|
+
passkeyVerification,
|
|
3420
|
+
sessions,
|
|
3421
|
+
authHttp,
|
|
3422
|
+
makeSessionInput: passkeyAuthenticationSessionInput,
|
|
3423
|
+
...passkeyFinishHttpOptions(config),
|
|
3424
|
+
})),
|
|
3425
|
+
listCredentials: provideHandlerAuthRateLimit(authRateLimit, makePasskeyCredentialListHandler({
|
|
3426
|
+
passkeyCredentialManagement,
|
|
3427
|
+
sessions,
|
|
3428
|
+
sessionCookie,
|
|
3429
|
+
})),
|
|
3430
|
+
revokeCredential: provideHandlerAuthRateLimit(authRateLimit, makePasskeyCredentialRevokeHandler({
|
|
3431
|
+
passkeyCredentialManagement,
|
|
3432
|
+
sessions,
|
|
3433
|
+
sessionCookie,
|
|
3434
|
+
...(Option.isSome(policy)
|
|
3435
|
+
? { strongFactorRemovalPolicy: policy.value }
|
|
3436
|
+
: {}),
|
|
3437
|
+
})),
|
|
3438
|
+
});
|
|
3439
|
+
}));
|
|
3440
|
+
export const IdentityHttpOperationsLive = Layer.effect(IdentityHttpOperations, Effect.gen(function* () {
|
|
3441
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3442
|
+
const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
|
|
3443
|
+
const identityManagement = yield* IdentityManagement;
|
|
3444
|
+
const sessions = yield* Sessions;
|
|
3445
|
+
const sessionCookie = yield* SessionCookie;
|
|
3446
|
+
const dependencies = {
|
|
3447
|
+
identityManagement,
|
|
3448
|
+
sessions,
|
|
3449
|
+
sessionCookie,
|
|
3450
|
+
};
|
|
3451
|
+
const availabilityGuardServices = {
|
|
3452
|
+
authRateLimit,
|
|
3453
|
+
sessions,
|
|
3454
|
+
sessionCookie,
|
|
3455
|
+
...(Option.isSome(botChallengeVerifier)
|
|
3456
|
+
? { botChallengeVerifier: botChallengeVerifier.value }
|
|
3457
|
+
: {}),
|
|
3458
|
+
};
|
|
3459
|
+
return IdentityHttpOperations.of({
|
|
3460
|
+
availability: provideRequestGuardServices(availabilityGuardServices, makeIdentityAvailabilityHandler(dependencies)),
|
|
3461
|
+
list: provideHandlerAuthRateLimit(authRateLimit, makeIdentityListHandler(dependencies)),
|
|
3462
|
+
add: provideHandlerAuthRateLimit(authRateLimit, makeIdentityAddHandler(dependencies)),
|
|
3463
|
+
replace: provideHandlerAuthRateLimit(authRateLimit, makeIdentityReplaceHandler(dependencies)),
|
|
3464
|
+
revoke: provideHandlerAuthRateLimit(authRateLimit, makeIdentityRevokeHandler(dependencies)),
|
|
3465
|
+
primary: provideHandlerAuthRateLimit(authRateLimit, makeIdentityPrimaryHandler(dependencies)),
|
|
3466
|
+
});
|
|
3467
|
+
}));
|
|
3468
|
+
export const TotpHttpOperationsLive = Layer.effect(TotpHttpOperations, Effect.gen(function* () {
|
|
3469
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3470
|
+
const config = yield* TotpHttpConfig;
|
|
3471
|
+
const totpFactorManagement = yield* TotpFactorManagement;
|
|
3472
|
+
const sessions = yield* Sessions;
|
|
3473
|
+
const sessionCookie = yield* SessionCookie;
|
|
3474
|
+
const policy = yield* Effect.serviceOption(StrongFactorRemovalPolicy);
|
|
3475
|
+
return TotpHttpOperations.of({
|
|
3476
|
+
startEnrollment: provideHandlerAuthRateLimit(authRateLimit, makeTotpEnrollmentStartHandler({
|
|
3477
|
+
totpFactorManagement,
|
|
3478
|
+
sessions,
|
|
3479
|
+
sessionCookie,
|
|
3480
|
+
...config,
|
|
3481
|
+
})),
|
|
3482
|
+
confirmEnrollment: provideHandlerAuthRateLimit(authRateLimit, makeTotpEnrollmentConfirmHandler({
|
|
3483
|
+
totpFactorManagement,
|
|
3484
|
+
sessions,
|
|
3485
|
+
sessionCookie,
|
|
3486
|
+
...config,
|
|
3487
|
+
})),
|
|
3488
|
+
verify: provideHandlerAuthRateLimit(authRateLimit, makeTotpVerifyHandler({
|
|
3489
|
+
totpFactorManagement,
|
|
3490
|
+
sessions,
|
|
3491
|
+
sessionCookie,
|
|
3492
|
+
...config,
|
|
3493
|
+
})),
|
|
3494
|
+
listFactors: provideHandlerAuthRateLimit(authRateLimit, makeTotpFactorListHandler({
|
|
3495
|
+
totpFactorManagement,
|
|
3496
|
+
sessions,
|
|
3497
|
+
sessionCookie,
|
|
3498
|
+
})),
|
|
3499
|
+
revokeFactor: provideHandlerAuthRateLimit(authRateLimit, makeTotpFactorRevokeHandler({
|
|
3500
|
+
totpFactorManagement,
|
|
3501
|
+
sessions,
|
|
3502
|
+
sessionCookie,
|
|
3503
|
+
...(Option.isSome(policy)
|
|
3504
|
+
? { strongFactorRemovalPolicy: policy.value }
|
|
3505
|
+
: {}),
|
|
3506
|
+
})),
|
|
3507
|
+
});
|
|
3508
|
+
}));
|
|
3509
|
+
export const RecoveryCodesHttpOperationsLive = Layer.effect(RecoveryCodesHttpOperations, Effect.gen(function* () {
|
|
3510
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3511
|
+
const config = yield* RecoveryCodeHttpConfig;
|
|
3512
|
+
const recoveryCodeManagement = yield* RecoveryCodeManagement;
|
|
3513
|
+
const sessions = yield* Sessions;
|
|
3514
|
+
const sessionCookie = yield* SessionCookie;
|
|
3515
|
+
const policy = yield* Effect.serviceOption(StrongFactorRemovalPolicy);
|
|
3516
|
+
return RecoveryCodesHttpOperations.of({
|
|
3517
|
+
generate: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeGenerateHandler({
|
|
3518
|
+
recoveryCodeManagement,
|
|
3519
|
+
sessions,
|
|
3520
|
+
sessionCookie,
|
|
3521
|
+
...config,
|
|
3522
|
+
})),
|
|
3523
|
+
regenerate: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeRegenerateHandler({
|
|
3524
|
+
recoveryCodeManagement,
|
|
3525
|
+
sessions,
|
|
3526
|
+
sessionCookie,
|
|
3527
|
+
...config,
|
|
3528
|
+
})),
|
|
3529
|
+
verify: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeVerifyHandler({
|
|
3530
|
+
recoveryCodeManagement,
|
|
3531
|
+
sessions,
|
|
3532
|
+
sessionCookie,
|
|
3533
|
+
})),
|
|
3534
|
+
list: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeListHandler({
|
|
3535
|
+
recoveryCodeManagement,
|
|
3536
|
+
sessions,
|
|
3537
|
+
sessionCookie,
|
|
3538
|
+
})),
|
|
3539
|
+
revoke: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeRevokeHandler({
|
|
3540
|
+
recoveryCodeManagement,
|
|
3541
|
+
sessions,
|
|
3542
|
+
sessionCookie,
|
|
3543
|
+
...(Option.isSome(policy)
|
|
3544
|
+
? { strongFactorRemovalPolicy: policy.value }
|
|
3545
|
+
: {}),
|
|
3546
|
+
})),
|
|
3547
|
+
});
|
|
3548
|
+
}));
|
|
3549
|
+
export const MfaHttpOperationsLive = Layer.effect(MfaHttpOperations, Effect.gen(function* () {
|
|
3550
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3551
|
+
const passkeyConfig = yield* PasskeyHttpConfig;
|
|
3552
|
+
const totpConfig = yield* TotpHttpConfig;
|
|
3553
|
+
const authFlowState = yield* AuthFlowState;
|
|
3554
|
+
const authFlow = yield* AuthFlow;
|
|
3555
|
+
const authHttp = yield* AuthHttp;
|
|
3556
|
+
const totpFactorManagement = yield* TotpFactorManagement;
|
|
3557
|
+
const recoveryCodeManagement = yield* RecoveryCodeManagement;
|
|
3558
|
+
const verificationStore = yield* VerificationStore;
|
|
3559
|
+
const recoveryCodeLoginCommitStore = yield* RecoveryCodeLoginCommitStore;
|
|
3560
|
+
const totpLoginCommitStore = yield* TotpLoginCommitStore;
|
|
3561
|
+
const users = yield* UserStore;
|
|
3562
|
+
const passkeyCredentialManagement = yield* PasskeyCredentialManagement;
|
|
3563
|
+
const passkeyOptions = yield* PasskeyOptions;
|
|
3564
|
+
const passkeyVerification = yield* PasskeyVerification;
|
|
3565
|
+
return MfaHttpOperations.of({
|
|
3566
|
+
options: provideHandlerAuthRateLimit(authRateLimit, makeMfaOptionsHandler({
|
|
3567
|
+
authFlowState,
|
|
3568
|
+
totpFactorManagement,
|
|
3569
|
+
recoveryCodeManagement,
|
|
3570
|
+
passkeyCredentialManagement,
|
|
3571
|
+
})),
|
|
3572
|
+
verifyTotp: provideHandlerAuthRateLimit(authRateLimit, makeTotpMfaVerifyHandler({
|
|
3573
|
+
totpFactorManagement,
|
|
3574
|
+
authFlowState,
|
|
3575
|
+
authFlow,
|
|
3576
|
+
authHttp,
|
|
3577
|
+
...totpConfig,
|
|
3578
|
+
})),
|
|
3579
|
+
verifyTotpForFlow: provideHandlerAuthRateLimit(authRateLimit, makeTotpMfaVerifyForFlowHandler({
|
|
3580
|
+
totpFactorManagement,
|
|
3581
|
+
authFlowState,
|
|
3582
|
+
authFlow,
|
|
3583
|
+
authHttp,
|
|
3584
|
+
verificationStore,
|
|
3585
|
+
totpLoginCommitStore,
|
|
3586
|
+
users,
|
|
3587
|
+
...totpConfig,
|
|
3588
|
+
})),
|
|
3589
|
+
verifyRecoveryCode: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeMfaVerifyHandler({
|
|
3590
|
+
recoveryCodeManagement,
|
|
3591
|
+
authFlowState,
|
|
3592
|
+
authFlow,
|
|
3593
|
+
authHttp,
|
|
3594
|
+
})),
|
|
3595
|
+
verifyRecoveryCodeForFlow: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeMfaVerifyForFlowHandler({
|
|
3596
|
+
recoveryCodeManagement,
|
|
3597
|
+
authFlowState,
|
|
3598
|
+
authFlow,
|
|
3599
|
+
authHttp,
|
|
3600
|
+
verificationStore,
|
|
3601
|
+
recoveryCodeLoginCommitStore,
|
|
3602
|
+
users,
|
|
3603
|
+
})),
|
|
3604
|
+
startPasskey: provideHandlerAuthRateLimit(authRateLimit, makePasskeyMfaStartHandler({
|
|
3605
|
+
passkeyOptions,
|
|
3606
|
+
authFlowState,
|
|
3607
|
+
...passkeyAuthenticationStartHttpOptions(passkeyConfig),
|
|
3608
|
+
})),
|
|
3609
|
+
verifyPasskey: provideHandlerAuthRateLimit(authRateLimit, makePasskeyMfaVerifyHandler({
|
|
3610
|
+
passkeyVerification,
|
|
3611
|
+
authFlowState,
|
|
3612
|
+
authFlow,
|
|
3613
|
+
authHttp,
|
|
3614
|
+
...passkeyFinishHttpOptions(passkeyConfig),
|
|
3615
|
+
})),
|
|
3616
|
+
});
|
|
3617
|
+
}));
|
|
3618
|
+
export const StepUpHttpOperationsLive = Layer.effect(StepUpHttpOperations, Effect.gen(function* () {
|
|
3619
|
+
const authRateLimit = yield* AuthRateLimit;
|
|
3620
|
+
const passkeyConfig = yield* PasskeyHttpConfig;
|
|
3621
|
+
const totpConfig = yield* TotpHttpConfig;
|
|
3622
|
+
const sessions = yield* Sessions;
|
|
3623
|
+
const sessionCookie = yield* SessionCookie;
|
|
3624
|
+
const credentials = yield* CredentialStore;
|
|
3625
|
+
const hasher = yield* PasswordHasher;
|
|
3626
|
+
const totpFactorManagement = yield* TotpFactorManagement;
|
|
3627
|
+
const recoveryCodeManagement = yield* RecoveryCodeManagement;
|
|
3628
|
+
const recoveryCodeSessionRotation = yield* RecoveryCodeSessionRotation;
|
|
3629
|
+
const totpSessionRotation = yield* TotpSessionRotation;
|
|
3630
|
+
const passkeyCredentialManagement = yield* PasskeyCredentialManagement;
|
|
3631
|
+
const passkeyOptions = yield* PasskeyOptions;
|
|
3632
|
+
const passkeyVerification = yield* PasskeyVerification;
|
|
3633
|
+
return StepUpHttpOperations.of({
|
|
3634
|
+
options: provideHandlerAuthRateLimit(authRateLimit, makeStepUpOptionsHandler({
|
|
3635
|
+
sessions,
|
|
3636
|
+
sessionCookie,
|
|
3637
|
+
credentials,
|
|
3638
|
+
totpFactorManagement,
|
|
3639
|
+
recoveryCodeManagement,
|
|
3640
|
+
passkeyCredentialManagement,
|
|
3641
|
+
})),
|
|
3642
|
+
verifyTotp: provideHandlerAuthRateLimit(authRateLimit, makeStepUpTotpVerifyHandler({
|
|
3643
|
+
totpFactorManagement,
|
|
3644
|
+
sessions,
|
|
3645
|
+
sessionCookie,
|
|
3646
|
+
totpSessionRotation,
|
|
3647
|
+
...totpConfig,
|
|
3648
|
+
})),
|
|
3649
|
+
verifyPassword: provideHandlerAuthRateLimit(authRateLimit, makeStepUpPasswordVerifyHandler({
|
|
3650
|
+
credentials,
|
|
3651
|
+
hasher,
|
|
3652
|
+
sessions,
|
|
3653
|
+
sessionCookie,
|
|
3654
|
+
})),
|
|
3655
|
+
verifyRecoveryCode: provideHandlerAuthRateLimit(authRateLimit, makeStepUpRecoveryCodeVerifyHandler({
|
|
3656
|
+
recoveryCodeManagement,
|
|
3657
|
+
recoveryCodeSessionRotation,
|
|
3658
|
+
sessions,
|
|
3659
|
+
sessionCookie,
|
|
3660
|
+
})),
|
|
3661
|
+
startPasskey: provideHandlerAuthRateLimit(authRateLimit, makeStepUpPasskeyStartHandler({
|
|
3662
|
+
passkeyOptions,
|
|
3663
|
+
sessions,
|
|
3664
|
+
sessionCookie,
|
|
3665
|
+
...passkeyAuthenticationStartHttpOptions(passkeyConfig),
|
|
3666
|
+
})),
|
|
3667
|
+
verifyPasskey: provideHandlerAuthRateLimit(authRateLimit, makeStepUpPasskeyVerifyHandler({
|
|
3668
|
+
passkeyVerification,
|
|
3669
|
+
sessions,
|
|
3670
|
+
sessionCookie,
|
|
3671
|
+
...passkeyFinishHttpOptions(passkeyConfig),
|
|
3672
|
+
})),
|
|
3673
|
+
});
|
|
3674
|
+
}));
|
|
3675
|
+
export const AdminSessionHttpOperationsLive = Layer.effect(AdminSessionHttpOperations, Effect.gen(function* () {
|
|
3676
|
+
const sessions = yield* Sessions;
|
|
3677
|
+
const sessionCookie = yield* SessionCookie;
|
|
3678
|
+
const authorization = yield* AdminSessionAuthorization;
|
|
3679
|
+
return AdminSessionHttpOperations.of({
|
|
3680
|
+
list: makeAdminSessionListHandler({
|
|
3681
|
+
sessions,
|
|
3682
|
+
sessionCookie,
|
|
3683
|
+
authorization,
|
|
3684
|
+
}),
|
|
3685
|
+
revoke: makeAdminSessionRevokeHandler({
|
|
3686
|
+
sessions,
|
|
3687
|
+
sessionCookie,
|
|
3688
|
+
authorization,
|
|
3689
|
+
}),
|
|
3690
|
+
revokeAll: makeAdminSessionRevokeAllHandler({
|
|
3691
|
+
sessions,
|
|
3692
|
+
sessionCookie,
|
|
3693
|
+
authorization,
|
|
3694
|
+
}),
|
|
3695
|
+
});
|
|
3696
|
+
}));
|
|
3697
|
+
export const AdminPermissionDefinitionHttpOperationsLive = Layer.succeed(AdminPermissionDefinitionHttpOperations, AdminPermissionDefinitionHttpOperations.of({
|
|
3698
|
+
create: adminPermissionDefinitionCreateOperation,
|
|
3699
|
+
get: adminPermissionDefinitionGetOperation,
|
|
3700
|
+
list: adminPermissionDefinitionListOperation,
|
|
3701
|
+
update: adminPermissionDefinitionUpdateOperation,
|
|
3702
|
+
disable: adminPermissionDefinitionDisableOperation,
|
|
3703
|
+
enable: adminPermissionDefinitionEnableOperation,
|
|
3704
|
+
delete: adminPermissionDefinitionDeleteOperation,
|
|
3705
|
+
}));
|
|
3706
|
+
export const LoginNotificationHttpOperationsLive = Layer.effect(LoginNotificationHttpOperations, Effect.gen(function* () {
|
|
3707
|
+
const loginNotification = yield* Effect.serviceOption(LoginNotification);
|
|
3708
|
+
return LoginNotificationHttpOperations.of({
|
|
3709
|
+
reportLogin: makeLoginNotificationReportHandler(Option.isSome(loginNotification)
|
|
3710
|
+
? { loginNotification: loginNotification.value }
|
|
3711
|
+
: {}),
|
|
3712
|
+
});
|
|
3713
|
+
}));
|
|
3714
|
+
export const SecurityTimelineHttpOperationsLive = Layer.effect(SecurityTimelineHttpOperations, Effect.gen(function* () {
|
|
3715
|
+
const sessions = yield* Sessions;
|
|
3716
|
+
const sessionCookie = yield* SessionCookie;
|
|
3717
|
+
const securityTimeline = yield* SecurityTimelineStore;
|
|
3718
|
+
return SecurityTimelineHttpOperations.of({
|
|
3719
|
+
list: makeSecurityTimelineListHandler({
|
|
3720
|
+
sessions,
|
|
3721
|
+
sessionCookie,
|
|
3722
|
+
securityTimeline,
|
|
3723
|
+
}),
|
|
3724
|
+
});
|
|
3725
|
+
}));
|
|
3726
|
+
export const AdminSecurityTimelineHttpOperationsLive = Layer.effect(AdminSecurityTimelineHttpOperations, Effect.gen(function* () {
|
|
3727
|
+
const sessions = yield* Sessions;
|
|
3728
|
+
const sessionCookie = yield* SessionCookie;
|
|
3729
|
+
const securityTimeline = yield* SecurityTimelineStore;
|
|
3730
|
+
const authorization = yield* AdminSecurityTimelineAuthorization;
|
|
3731
|
+
return AdminSecurityTimelineHttpOperations.of({
|
|
3732
|
+
list: makeAdminSecurityTimelineListHandler({
|
|
3733
|
+
sessions,
|
|
3734
|
+
sessionCookie,
|
|
3735
|
+
securityTimeline,
|
|
3736
|
+
authorization,
|
|
3737
|
+
}),
|
|
3738
|
+
});
|
|
3739
|
+
}));
|
|
3740
|
+
export const TrustedDeviceHttpOperationsLive = Layer.effect(TrustedDeviceHttpOperations, Effect.gen(function* () {
|
|
3741
|
+
const sessions = yield* Sessions;
|
|
3742
|
+
const sessionCookie = yield* SessionCookie;
|
|
3743
|
+
const trustedDevices = yield* TrustedDeviceStore;
|
|
3744
|
+
return TrustedDeviceHttpOperations.of({
|
|
3745
|
+
list: makeTrustedDeviceListHandler({
|
|
3746
|
+
sessions,
|
|
3747
|
+
sessionCookie,
|
|
3748
|
+
trustedDevices,
|
|
3749
|
+
}),
|
|
3750
|
+
revoke: makeTrustedDeviceRevokeHandler({
|
|
3751
|
+
sessions,
|
|
3752
|
+
sessionCookie,
|
|
3753
|
+
trustedDevices,
|
|
3754
|
+
}),
|
|
3755
|
+
});
|
|
3756
|
+
}));
|
|
3757
|
+
export const AdminTrustedDeviceHttpOperationsLive = Layer.effect(AdminTrustedDeviceHttpOperations, Effect.gen(function* () {
|
|
3758
|
+
const sessions = yield* Sessions;
|
|
3759
|
+
const sessionCookie = yield* SessionCookie;
|
|
3760
|
+
const trustedDevices = yield* TrustedDeviceStore;
|
|
3761
|
+
const authorization = yield* AdminTrustedDeviceAuthorization;
|
|
3762
|
+
return AdminTrustedDeviceHttpOperations.of({
|
|
3763
|
+
list: makeAdminTrustedDeviceListHandler({
|
|
3764
|
+
sessions,
|
|
3765
|
+
sessionCookie,
|
|
3766
|
+
trustedDevices,
|
|
3767
|
+
authorization,
|
|
3768
|
+
}),
|
|
3769
|
+
revoke: makeAdminTrustedDeviceRevokeHandler({
|
|
3770
|
+
sessions,
|
|
3771
|
+
sessionCookie,
|
|
3772
|
+
trustedDevices,
|
|
3773
|
+
authorization,
|
|
3774
|
+
}),
|
|
3775
|
+
});
|
|
3776
|
+
}));
|
|
3777
|
+
export const OAuthHttpOperationsLive = Layer.effect(OAuthHttpOperations, Effect.gen(function* () {
|
|
3778
|
+
const oauthProviders = yield* OAuthProviders;
|
|
3779
|
+
const oauthState = yield* OAuthState;
|
|
3780
|
+
const oauthAccountUnlinking = yield* OAuthAccountUnlinking;
|
|
3781
|
+
const oauthLinkConfirmation = yield* OAuthLinkConfirmation;
|
|
3782
|
+
const sessions = yield* Sessions;
|
|
3783
|
+
const sessionCookie = yield* SessionCookie;
|
|
3784
|
+
const config = yield* OAuthHttpConfig;
|
|
3785
|
+
return OAuthHttpOperations.of({
|
|
3786
|
+
authorizationStart: makeOAuthAuthorizationStartHandler({
|
|
3787
|
+
oauthProviders,
|
|
3788
|
+
oauthState,
|
|
3789
|
+
...config,
|
|
3790
|
+
}),
|
|
3791
|
+
accountUnlink: makeOAuthAccountUnlinkHandler({
|
|
3792
|
+
oauthAccountUnlinking,
|
|
3793
|
+
sessions,
|
|
3794
|
+
sessionCookie,
|
|
3795
|
+
...config,
|
|
3796
|
+
}),
|
|
3797
|
+
linkConfirmationStart: makeOAuthLinkConfirmationStartHandler({
|
|
3798
|
+
oauthLinkConfirmation,
|
|
3799
|
+
...config,
|
|
3800
|
+
}),
|
|
3801
|
+
linkConfirmationInspect: makeOAuthLinkConfirmationInspectHandler({
|
|
3802
|
+
oauthLinkConfirmation,
|
|
3803
|
+
}),
|
|
3804
|
+
linkConfirmationConfirm: makeOAuthLinkConfirmationConfirmHandler({
|
|
3805
|
+
oauthLinkConfirmation,
|
|
3806
|
+
...config,
|
|
3807
|
+
}),
|
|
3808
|
+
});
|
|
3809
|
+
}));
|
|
3810
|
+
export const OAuthProviderAuthorizationHttpOperationsLive = Layer.effect(OAuthProviderAuthorizationHttpOperations, Effect.gen(function* () {
|
|
3811
|
+
const authorization = yield* OAuthProviderAuthorization;
|
|
3812
|
+
return OAuthProviderAuthorizationHttpOperations.of({
|
|
3813
|
+
authorize: makeOAuthProviderAuthorizationHandler({ authorization }),
|
|
3814
|
+
});
|
|
3815
|
+
}));
|
|
3816
|
+
export const OAuthTokenHttpOperationsLive = Layer.effect(OAuthTokenHttpOperations, Effect.gen(function* () {
|
|
3817
|
+
const tokenGrant = yield* OAuthAuthorizationCodeTokenGrant;
|
|
3818
|
+
const refreshTokenGrant = yield* Effect.serviceOption(OAuthRefreshTokenGrant);
|
|
3819
|
+
const clientCredentialsGrant = yield* Effect.serviceOption(OAuthClientCredentialsGrant);
|
|
3820
|
+
const tokenIntrospection = yield* Effect.serviceOption(OAuthTokenIntrospection);
|
|
3821
|
+
const tokenRevocation = yield* Effect.serviceOption(OAuthTokenRevocation);
|
|
3822
|
+
const config = yield* OAuthTokenHttpConfig;
|
|
3823
|
+
return OAuthTokenHttpOperations.of({
|
|
3824
|
+
token: makeOAuthAuthorizationCodeTokenHandler({
|
|
3825
|
+
tokenGrant,
|
|
3826
|
+
...config,
|
|
3827
|
+
...(Option.isSome(refreshTokenGrant)
|
|
3828
|
+
? { refreshTokenGrant: refreshTokenGrant.value }
|
|
3829
|
+
: {}),
|
|
3830
|
+
...(Option.isSome(clientCredentialsGrant)
|
|
3831
|
+
? { clientCredentialsGrant: clientCredentialsGrant.value }
|
|
3832
|
+
: {}),
|
|
3833
|
+
}),
|
|
3834
|
+
introspect: Option.isNone(tokenIntrospection)
|
|
3835
|
+
? makeOAuthTokenIntrospectionNotConfiguredHandler()
|
|
3836
|
+
: makeOAuthTokenIntrospectionHandler({
|
|
3837
|
+
tokenIntrospection: tokenIntrospection.value,
|
|
3838
|
+
...config,
|
|
3839
|
+
}),
|
|
3840
|
+
revoke: Option.isNone(tokenRevocation)
|
|
3841
|
+
? makeOAuthTokenRevocationNotConfiguredHandler()
|
|
3842
|
+
: makeOAuthTokenRevocationHandler({
|
|
3843
|
+
tokenRevocation: tokenRevocation.value,
|
|
3844
|
+
...config,
|
|
3845
|
+
}),
|
|
3846
|
+
});
|
|
3847
|
+
}));
|
|
3848
|
+
export const LoginApprovalHttpOperationsLive = Layer.effect(LoginApprovalHttpOperations, Effect.gen(function* () {
|
|
3849
|
+
const loginApproval = yield* LoginApproval;
|
|
3850
|
+
const authFlowState = yield* AuthFlowState;
|
|
3851
|
+
const authFlowFinalizer = yield* AuthFlowFinalizer;
|
|
3852
|
+
const identities = yield* IdentityStore;
|
|
3853
|
+
const authHttp = yield* AuthHttp;
|
|
3854
|
+
const loginApprovalReview = yield* Effect.serviceOption(LoginApprovalReview);
|
|
3855
|
+
const loginApprovalFinalize = yield* Effect.serviceOption(LoginApprovalFinalize);
|
|
3856
|
+
const pendingCookie = yield* Effect.serviceOption(LoginApprovalPendingCookie);
|
|
3857
|
+
const trustedDevice = yield* Effect.serviceOption(TrustedDevice);
|
|
3858
|
+
const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
|
|
3859
|
+
const loginApprovalPendingCookie = Option.isSome(pendingCookie)
|
|
3860
|
+
? pendingCookie.value
|
|
3861
|
+
: makeLoginApprovalPendingCookie();
|
|
3862
|
+
return LoginApprovalHttpOperations.of({
|
|
3863
|
+
approve: makeLoginApprovalApproveHandler({
|
|
3864
|
+
loginApproval,
|
|
3865
|
+
authFlowState,
|
|
3866
|
+
finalizeAuthFlow: authFlowFinalizer.complete,
|
|
3867
|
+
identities,
|
|
3868
|
+
authHttp,
|
|
3869
|
+
loginApprovalPendingCookie,
|
|
3870
|
+
...(Option.isSome(trustedDevice)
|
|
3871
|
+
? { trustedDevice: trustedDevice.value }
|
|
3872
|
+
: {}),
|
|
3873
|
+
...(Option.isSome(trustedDeviceCookie)
|
|
3874
|
+
? { trustedDeviceCookie: trustedDeviceCookie.value }
|
|
3875
|
+
: {}),
|
|
3876
|
+
}),
|
|
3877
|
+
status: makeLoginApprovalStatusHandler(Option.isSome(loginApprovalReview)
|
|
3878
|
+
? { loginApprovalReview: loginApprovalReview.value }
|
|
3879
|
+
: {}),
|
|
3880
|
+
finalize: makeLoginApprovalFinalizeHandler({
|
|
3881
|
+
authHttp,
|
|
3882
|
+
loginApprovalPendingCookie,
|
|
3883
|
+
...(Option.isSome(loginApprovalFinalize)
|
|
3884
|
+
? { loginApprovalFinalize: loginApprovalFinalize.value }
|
|
3885
|
+
: {}),
|
|
3886
|
+
...(Option.isSome(trustedDevice)
|
|
3887
|
+
? { trustedDevice: trustedDevice.value }
|
|
3888
|
+
: {}),
|
|
3889
|
+
...(Option.isSome(trustedDeviceCookie)
|
|
3890
|
+
? { trustedDeviceCookie: trustedDeviceCookie.value }
|
|
3891
|
+
: {}),
|
|
3892
|
+
}),
|
|
3893
|
+
});
|
|
3894
|
+
})).pipe(Layer.provide(AuthFlowFinalizerLive));
|
|
3895
|
+
export const ApiKeyHttpOperationsLive = Layer.effect(ApiKeyHttpOperations, Effect.gen(function* () {
|
|
3896
|
+
const apiKeyManagement = yield* ApiKeyManagement;
|
|
3897
|
+
const sessions = yield* Sessions;
|
|
3898
|
+
const sessionCookie = yield* SessionCookie;
|
|
3899
|
+
const dependencies = { apiKeyManagement, sessions, sessionCookie };
|
|
3900
|
+
return ApiKeyHttpOperations.of({
|
|
3901
|
+
create: makeApiKeyCreateHandler(dependencies),
|
|
3902
|
+
list: makeApiKeyListHandler(dependencies),
|
|
3903
|
+
revoke: makeApiKeyRevokeHandler(dependencies),
|
|
3904
|
+
});
|
|
3905
|
+
}));
|
|
3906
|
+
export const RefreshTokenHttpOperationsLive = Layer.effect(RefreshTokenHttpOperations, Effect.gen(function* () {
|
|
3907
|
+
const refreshTokenManagement = yield* RefreshTokenManagement;
|
|
3908
|
+
const jwtIssuer = yield* JwtIssuer;
|
|
3909
|
+
const config = yield* RefreshTokenHttpConfig;
|
|
3910
|
+
return RefreshTokenHttpOperations.of({
|
|
3911
|
+
refresh: makeRefreshTokenRefreshHandler({
|
|
3912
|
+
refreshTokenManagement,
|
|
3913
|
+
jwtIssuer,
|
|
3914
|
+
...config,
|
|
3915
|
+
}),
|
|
3916
|
+
});
|
|
3917
|
+
}));
|
|
3918
|
+
export const JwtHttpOperationsLive = Layer.effect(JwtHttpOperations, Effect.gen(function* () {
|
|
3919
|
+
const jwtRevocation = yield* JwtRevocation;
|
|
3920
|
+
const config = yield* JwtHttpConfig;
|
|
3921
|
+
return JwtHttpOperations.of({
|
|
3922
|
+
introspect: makeJwtIntrospectHandler({ jwtRevocation, ...config }),
|
|
3923
|
+
revoke: makeJwtRevokeHandler({ jwtRevocation }),
|
|
3924
|
+
});
|
|
3925
|
+
}));
|
|
3926
|
+
export const JwtDiscoveryHttpOperationsLive = Layer.effect(JwtDiscoveryHttpOperations, Effect.gen(function* () {
|
|
3927
|
+
const jwks = yield* Jwks;
|
|
3928
|
+
return JwtDiscoveryHttpOperations.of({
|
|
3929
|
+
jwks: makeJwtJwksHandler({ jwks }),
|
|
3930
|
+
});
|
|
3931
|
+
}));
|
|
3932
|
+
export const OidcDiscoveryHttpOperationsLive = Layer.effect(OidcDiscoveryHttpOperations, Effect.gen(function* () {
|
|
3933
|
+
const metadata = yield* OidcDiscoveryMetadata;
|
|
3934
|
+
return OidcDiscoveryHttpOperations.of({
|
|
3935
|
+
openidConfiguration: makeOidcDiscoveryMetadataHandler({ metadata }),
|
|
3936
|
+
});
|
|
3937
|
+
}));
|
|
3938
|
+
export class AdminSessionHttpApiGroup extends HttpApiGroup.make("adminSession")
|
|
2614
3939
|
.add(adminSessionListEndpoint, adminSessionRevokeEndpoint, adminSessionRevokeAllEndpoint)
|
|
2615
3940
|
.prefix("/auth/admin/sessions")
|
|
2616
3941
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2617
3942
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2618
3943
|
}
|
|
2619
|
-
export class AdminSessionHttpApi extends HttpApi.make("AdminSessionHttpApi").add(
|
|
3944
|
+
export class AdminSessionHttpApi extends HttpApi.make("AdminSessionHttpApi").add(AdminSessionHttpApiGroup) {
|
|
2620
3945
|
}
|
|
2621
|
-
export class
|
|
2622
|
-
.add(
|
|
2623
|
-
.prefix("/auth/
|
|
3946
|
+
export class AdminPermissionDefinitionHttpApiGroup extends HttpApiGroup.make("adminPermissionDefinition")
|
|
3947
|
+
.add(adminPermissionDefinitionCreateEndpoint, adminPermissionDefinitionGetEndpoint, adminPermissionDefinitionListEndpoint, adminPermissionDefinitionUpdateEndpoint, adminPermissionDefinitionDisableEndpoint, adminPermissionDefinitionEnableEndpoint, adminPermissionDefinitionDeleteEndpoint)
|
|
3948
|
+
.prefix("/auth/admin")
|
|
2624
3949
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2625
3950
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2626
3951
|
}
|
|
2627
|
-
export class
|
|
2628
|
-
.add(emailOtpStartEndpoint.middleware(AuthRateLimitMiddleware), emailOtpVerifyEndpoint.middleware(AuthRateLimitMiddleware))
|
|
2629
|
-
.prefix("/auth/email-otp")
|
|
2630
|
-
.middleware(AuthSchemaErrorMiddleware)
|
|
2631
|
-
.middleware(AuthOriginCheckMiddleware) {
|
|
3952
|
+
export class AdminPermissionDefinitionHttpApi extends HttpApi.make("AdminPermissionDefinitionHttpApi").add(AdminPermissionDefinitionHttpApiGroup) {
|
|
2632
3953
|
}
|
|
2633
|
-
export class
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
3954
|
+
export class EmailAuthHttpApi extends HttpApi.make("EmailAuthHttpApi").add(EmailAuthHttpApiGroup) {
|
|
3955
|
+
}
|
|
3956
|
+
export class PasskeyHttpApi extends HttpApi.make("PasskeyHttpApi").add(PasskeyHttpApiGroup) {
|
|
3957
|
+
}
|
|
3958
|
+
export class IdentityHttpApi extends HttpApi.make("IdentityHttpApi").add(IdentityHttpApiGroup) {
|
|
3959
|
+
}
|
|
3960
|
+
export class TotpHttpApi extends HttpApi.make("TotpHttpApi").add(TotpHttpApiGroup) {
|
|
2638
3961
|
}
|
|
2639
|
-
export class
|
|
3962
|
+
export class RecoveryCodesHttpApi extends HttpApi.make("RecoveryCodesHttpApi").add(RecoveryCodesHttpApiGroup) {
|
|
3963
|
+
}
|
|
3964
|
+
export class OAuthHttpApiGroup extends HttpApiGroup.make("oauth")
|
|
2640
3965
|
.add(oauthAuthorizationStartEndpoint, oauthAccountUnlinkEndpoint, oauthLinkConfirmationStartEndpoint, oauthLinkConfirmationInspectEndpoint, oauthLinkConfirmationConfirmEndpoint)
|
|
2641
3966
|
.prefix("/auth/oauth")
|
|
2642
3967
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2643
3968
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2644
3969
|
}
|
|
2645
|
-
export class
|
|
3970
|
+
export class OAuthHttpApi extends HttpApi.make("OAuthHttpApi").add(OAuthHttpApiGroup) {
|
|
3971
|
+
}
|
|
3972
|
+
export class OAuthTokenHttpApiGroup extends HttpApiGroup.make("oauthToken")
|
|
2646
3973
|
.add(oauthTokenEndpoint, oauthTokenIntrospectionEndpoint, oauthTokenRevocationEndpoint)
|
|
2647
3974
|
.prefix("/auth/oauth")
|
|
2648
3975
|
.middleware(AuthSchemaErrorMiddleware) {
|
|
2649
3976
|
}
|
|
2650
|
-
export class OAuthTokenHttpApi extends HttpApi.make("OAuthTokenHttpApi").add(
|
|
3977
|
+
export class OAuthTokenHttpApi extends HttpApi.make("OAuthTokenHttpApi").add(OAuthTokenHttpApiGroup) {
|
|
2651
3978
|
}
|
|
2652
|
-
export class
|
|
3979
|
+
export class OAuthProviderAuthorizationHttpApiGroup extends HttpApiGroup.make("oauthProviderAuthorization")
|
|
2653
3980
|
.add(oauthProviderAuthorizeEndpoint)
|
|
2654
3981
|
.prefix("/auth/oauth")
|
|
2655
3982
|
.middleware(AuthSchemaErrorMiddleware) {
|
|
2656
3983
|
}
|
|
2657
|
-
export class OAuthProviderAuthorizationHttpApi extends HttpApi.make("OAuthProviderAuthorizationHttpApi").add(
|
|
3984
|
+
export class OAuthProviderAuthorizationHttpApi extends HttpApi.make("OAuthProviderAuthorizationHttpApi").add(OAuthProviderAuthorizationHttpApiGroup) {
|
|
2658
3985
|
}
|
|
2659
|
-
export class
|
|
2660
|
-
.add(loginApprovalApproveEndpoint, loginApprovalStatusEndpoint, loginApprovalFinalizeEndpoint)
|
|
2661
|
-
.prefix("/auth/login-approval")
|
|
2662
|
-
.middleware(AuthSchemaErrorMiddleware)
|
|
2663
|
-
.middleware(AuthOriginCheckMiddleware) {
|
|
3986
|
+
export class MfaHttpApi extends HttpApi.make("MfaHttpApi").add(MfaHttpApiGroup) {
|
|
2664
3987
|
}
|
|
2665
|
-
export class
|
|
2666
|
-
.add(mfaOptionsEndpoint, totpMfaVerifyEndpoint, totpMfaVerifyForFlowEndpoint, recoveryCodeMfaVerifyEndpoint, recoveryCodeMfaVerifyForFlowEndpoint, passkeyMfaStartEndpoint, passkeyMfaVerifyEndpoint)
|
|
2667
|
-
.prefix("/auth/mfa")
|
|
2668
|
-
.middleware(AuthSchemaErrorMiddleware)
|
|
2669
|
-
.middleware(AuthOriginCheckMiddleware) {
|
|
3988
|
+
export class StepUpHttpApi extends HttpApi.make("StepUpHttpApi").add(StepUpHttpApiGroup) {
|
|
2670
3989
|
}
|
|
2671
|
-
export class
|
|
2672
|
-
.add(stepUpOptionsEndpoint, stepUpTotpVerifyEndpoint, stepUpRecoveryCodeVerifyEndpoint, stepUpPasskeyStartEndpoint, stepUpPasskeyVerifyEndpoint)
|
|
2673
|
-
.prefix("/auth/step-up")
|
|
2674
|
-
.middleware(AuthSchemaErrorMiddleware)
|
|
2675
|
-
.middleware(AuthOriginCheckMiddleware) {
|
|
2676
|
-
}
|
|
2677
|
-
export class ApiKeyApi extends HttpApiGroup.make("apiKey")
|
|
3990
|
+
export class ApiKeyHttpApiGroup extends HttpApiGroup.make("apiKey")
|
|
2678
3991
|
.add(apiKeyCreateEndpoint, apiKeyListEndpoint, apiKeyRevokeEndpoint)
|
|
2679
3992
|
.prefix("/auth/api-keys")
|
|
2680
3993
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2681
3994
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2682
3995
|
}
|
|
2683
|
-
export class
|
|
3996
|
+
export class ApiKeyHttpApi extends HttpApi.make("ApiKeyHttpApi").add(ApiKeyHttpApiGroup) {
|
|
3997
|
+
}
|
|
3998
|
+
export class RefreshTokenHttpApiGroup extends HttpApiGroup.make("refreshToken")
|
|
2684
3999
|
.add(refreshTokenRefreshEndpoint)
|
|
2685
4000
|
.prefix("/auth/token")
|
|
2686
4001
|
.middleware(AuthSchemaErrorMiddleware) {
|
|
2687
4002
|
}
|
|
2688
|
-
export class
|
|
4003
|
+
export class RefreshTokenHttpApi extends HttpApi.make("RefreshTokenHttpApi").add(RefreshTokenHttpApiGroup) {
|
|
4004
|
+
}
|
|
4005
|
+
export class JwtHttpApiGroup extends HttpApiGroup.make("jwt")
|
|
2689
4006
|
.add(jwtIntrospectEndpoint, jwtRevokeEndpoint)
|
|
2690
4007
|
.prefix("/auth/jwt")
|
|
2691
4008
|
.middleware(AuthSchemaErrorMiddleware) {
|
|
2692
4009
|
}
|
|
2693
|
-
export class
|
|
4010
|
+
export class JwtHttpApi extends HttpApi.make("JwtHttpApi").add(JwtHttpApiGroup) {
|
|
4011
|
+
}
|
|
4012
|
+
export class JwtDiscoveryHttpApiGroup extends HttpApiGroup.make("jwtDiscovery")
|
|
2694
4013
|
.add(jwtJwksEndpoint)
|
|
2695
4014
|
.prefix("/.well-known")
|
|
2696
4015
|
.middleware(AuthSchemaErrorMiddleware) {
|
|
2697
4016
|
}
|
|
2698
|
-
export class JwtDiscoveryHttpApi extends HttpApi.make("JwtDiscoveryHttpApi").add(
|
|
4017
|
+
export class JwtDiscoveryHttpApi extends HttpApi.make("JwtDiscoveryHttpApi").add(JwtDiscoveryHttpApiGroup) {
|
|
2699
4018
|
}
|
|
2700
|
-
export class
|
|
4019
|
+
export class OidcDiscoveryHttpApiGroup extends HttpApiGroup.make("oidcDiscovery")
|
|
2701
4020
|
.add(oidcDiscoveryMetadataEndpoint)
|
|
2702
4021
|
.prefix("/.well-known")
|
|
2703
4022
|
.middleware(AuthSchemaErrorMiddleware) {
|
|
2704
4023
|
}
|
|
2705
|
-
export class OidcDiscoveryHttpApi extends HttpApi.make("OidcDiscoveryHttpApi").add(
|
|
2706
|
-
}
|
|
2707
|
-
export class SecurityApi extends HttpApiGroup.make("security")
|
|
2708
|
-
.add(loginNotificationReportEndpoint)
|
|
2709
|
-
.prefix("/auth/security")
|
|
2710
|
-
.middleware(AuthSchemaErrorMiddleware)
|
|
2711
|
-
.middleware(AuthOriginCheckMiddleware) {
|
|
4024
|
+
export class OidcDiscoveryHttpApi extends HttpApi.make("OidcDiscoveryHttpApi").add(OidcDiscoveryHttpApiGroup) {
|
|
2712
4025
|
}
|
|
2713
|
-
export class
|
|
4026
|
+
export class SecurityTimelineHttpApiGroup extends HttpApiGroup.make("securityTimeline")
|
|
2714
4027
|
.add(securityTimelineListEndpoint)
|
|
2715
4028
|
.prefix("/auth/security")
|
|
2716
4029
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2717
4030
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2718
4031
|
}
|
|
2719
|
-
export class SecurityTimelineHttpApi extends HttpApi.make("SecurityTimelineHttpApi")
|
|
2720
|
-
.add(SecurityTimelineApi) {
|
|
4032
|
+
export class SecurityTimelineHttpApi extends HttpApi.make("SecurityTimelineHttpApi").add(SecurityTimelineHttpApiGroup) {
|
|
2721
4033
|
}
|
|
2722
|
-
export class
|
|
4034
|
+
export class AdminSecurityTimelineHttpApiGroup extends HttpApiGroup.make("adminSecurityTimeline")
|
|
2723
4035
|
.add(adminSecurityTimelineListEndpoint)
|
|
2724
4036
|
.prefix("/auth/admin/security")
|
|
2725
4037
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2726
4038
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2727
4039
|
}
|
|
2728
|
-
export class AdminSecurityTimelineHttpApi extends HttpApi.make("AdminSecurityTimelineHttpApi").add(
|
|
4040
|
+
export class AdminSecurityTimelineHttpApi extends HttpApi.make("AdminSecurityTimelineHttpApi").add(AdminSecurityTimelineHttpApiGroup) {
|
|
2729
4041
|
}
|
|
2730
|
-
export class
|
|
4042
|
+
export class TrustedDeviceHttpApiGroup extends HttpApiGroup.make("trustedDevice")
|
|
2731
4043
|
.add(trustedDeviceListEndpoint, trustedDeviceRevokeEndpoint)
|
|
2732
4044
|
.prefix("/auth/trusted-devices")
|
|
2733
4045
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2734
4046
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2735
4047
|
}
|
|
2736
|
-
export class TrustedDeviceHttpApi extends HttpApi.make("TrustedDeviceHttpApi")
|
|
2737
|
-
.add(TrustedDeviceApi) {
|
|
4048
|
+
export class TrustedDeviceHttpApi extends HttpApi.make("TrustedDeviceHttpApi").add(TrustedDeviceHttpApiGroup) {
|
|
2738
4049
|
}
|
|
2739
|
-
export class
|
|
4050
|
+
export class AdminTrustedDeviceHttpApiGroup extends HttpApiGroup.make("adminTrustedDevice")
|
|
2740
4051
|
.add(adminTrustedDeviceListEndpoint, adminTrustedDeviceRevokeEndpoint)
|
|
2741
4052
|
.prefix("/auth/admin/trusted-devices")
|
|
2742
4053
|
.middleware(AuthSchemaErrorMiddleware)
|
|
2743
4054
|
.middleware(AuthOriginCheckMiddleware) {
|
|
2744
4055
|
}
|
|
2745
|
-
export class AdminTrustedDeviceHttpApi extends HttpApi.make("AdminTrustedDeviceHttpApi").add(
|
|
4056
|
+
export class AdminTrustedDeviceHttpApi extends HttpApi.make("AdminTrustedDeviceHttpApi").add(AdminTrustedDeviceHttpApiGroup) {
|
|
2746
4057
|
}
|
|
2747
|
-
export class
|
|
2748
|
-
.add(
|
|
2749
|
-
.add(
|
|
2750
|
-
.add(
|
|
2751
|
-
.add(
|
|
2752
|
-
.add(
|
|
2753
|
-
.add(
|
|
2754
|
-
.add(
|
|
4058
|
+
export class CoreAuthHttpApi extends HttpApi.make("AuthApi")
|
|
4059
|
+
.add(PasswordHttpApiGroup)
|
|
4060
|
+
.add(SessionHttpApiGroup)
|
|
4061
|
+
.add(EmailVerificationHttpApiGroup)
|
|
4062
|
+
.add(EmailOtpHttpApiGroup)
|
|
4063
|
+
.add(MagicLinkHttpApiGroup)
|
|
4064
|
+
.add(LoginApprovalHttpApiGroup)
|
|
4065
|
+
.add(LoginNotificationHttpApiGroup) {
|
|
2755
4066
|
}
|
|
2756
|
-
export const
|
|
2757
|
-
|
|
2758
|
-
const
|
|
2759
|
-
const passwordReset = yield* PasswordReset;
|
|
2760
|
-
const passwordManagement = yield* PasswordManagement;
|
|
2761
|
-
const authHttp = yield* AuthHttp;
|
|
2762
|
-
const emailVerificationFlow = yield* EmailVerificationFlow;
|
|
2763
|
-
const sessions = yield* Sessions;
|
|
2764
|
-
const sessionCookie = yield* SessionCookie;
|
|
2765
|
-
const authApiRateLimit = yield* AuthApiRateLimit;
|
|
2766
|
-
const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
|
|
4067
|
+
export const CoreAuthPasswordGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "password", passwordGroupHandlers);
|
|
4068
|
+
export const CoreAuthSessionGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "session", Effect.fn("auth.http.session.group")(function* (handlers) {
|
|
4069
|
+
const operations = yield* SessionHttpOperations;
|
|
2767
4070
|
return handlers
|
|
2768
|
-
.handle("
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
? { trustedDeviceCookie: trustedDeviceCookie.value }
|
|
2775
|
-
: {}),
|
|
2776
|
-
}))
|
|
2777
|
-
.handle("signUp", makePasswordSignUpHandler({
|
|
2778
|
-
registration,
|
|
2779
|
-
authHttp,
|
|
2780
|
-
emailVerificationFlow,
|
|
2781
|
-
authApiRateLimit,
|
|
2782
|
-
}))
|
|
2783
|
-
.handle("resetStart", makePasswordResetStartHandler({
|
|
2784
|
-
passwordReset,
|
|
2785
|
-
authApiRateLimit,
|
|
2786
|
-
}))
|
|
2787
|
-
.handle("resetVerify", makePasswordResetVerifyHandler({
|
|
2788
|
-
passwordReset,
|
|
2789
|
-
}))
|
|
2790
|
-
.handle("set", makePasswordSetHandler({
|
|
2791
|
-
passwordManagement,
|
|
2792
|
-
sessions,
|
|
2793
|
-
sessionCookie,
|
|
2794
|
-
}))
|
|
2795
|
-
.handle("change", makePasswordChangeHandler({
|
|
2796
|
-
passwordManagement,
|
|
2797
|
-
sessions,
|
|
2798
|
-
sessionCookie,
|
|
2799
|
-
}));
|
|
4071
|
+
.handle("current", operations.current)
|
|
4072
|
+
.handle("refresh", operations.refresh)
|
|
4073
|
+
.handle("logout", operations.logout)
|
|
4074
|
+
.handle("list", operations.list)
|
|
4075
|
+
.handle("revoke", operations.revoke)
|
|
4076
|
+
.handle("revokeOthers", operations.revokeOthers);
|
|
2800
4077
|
}));
|
|
2801
|
-
export const
|
|
2802
|
-
const
|
|
2803
|
-
const sessionCookie = yield* SessionCookie;
|
|
2804
|
-
const authHttp = yield* AuthHttp;
|
|
4078
|
+
export const CoreAuthEmailVerificationGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "emailVerification", Effect.fn("auth.http.email_verification.group")(function* (handlers) {
|
|
4079
|
+
const operations = yield* EmailVerificationHttpOperations;
|
|
2805
4080
|
return handlers
|
|
2806
|
-
.handle("
|
|
2807
|
-
.handle("
|
|
2808
|
-
.handle("logout", makeLogoutHandler({ sessions, sessionCookie, authHttp }))
|
|
2809
|
-
.handle("list", makeListSessionsHandler({ sessions, sessionCookie }))
|
|
2810
|
-
.handle("revoke", makeRevokeSessionHandler({ sessions, sessionCookie, authHttp }))
|
|
2811
|
-
.handle("revokeOthers", makeRevokeOtherSessionsHandler({ sessions, sessionCookie }));
|
|
4081
|
+
.handle("start", operations.start)
|
|
4082
|
+
.handle("verify", operations.verify);
|
|
2812
4083
|
}));
|
|
2813
|
-
export const
|
|
2814
|
-
const
|
|
2815
|
-
const sessionCookie = yield* SessionCookie;
|
|
2816
|
-
const authorization = yield* AdminSessionAuthorization;
|
|
4084
|
+
export const CoreAuthEmailOtpGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "emailOtp", Effect.fn("auth.http.email_otp.group")(function* (handlers) {
|
|
4085
|
+
const operations = yield* EmailOtpHttpOperations;
|
|
2817
4086
|
return handlers
|
|
2818
|
-
.handle("
|
|
2819
|
-
.handle("
|
|
2820
|
-
.handle("revokeAll", makeAdminSessionRevokeAllHandler({
|
|
2821
|
-
sessions,
|
|
2822
|
-
sessionCookie,
|
|
2823
|
-
authorization,
|
|
2824
|
-
}));
|
|
4087
|
+
.handle("start", operations.start)
|
|
4088
|
+
.handle("verify", operations.verify);
|
|
2825
4089
|
}));
|
|
2826
|
-
export const
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
const
|
|
2832
|
-
const authApiRateLimit = yield* AuthApiRateLimit;
|
|
4090
|
+
export const EmailAuthHttpApiGroupLive = HttpApiBuilder.group(EmailAuthHttpApi, "emailAuth", Effect.fn("auth.http.email.group")(function* (handlers) {
|
|
4091
|
+
const operations = yield* EmailAuthHttpOperations;
|
|
4092
|
+
return handlers.handle("start", operations.start);
|
|
4093
|
+
}));
|
|
4094
|
+
export const CoreAuthMagicLinkGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "magicLink", Effect.fn("auth.http.magic_link.group")(function* (handlers) {
|
|
4095
|
+
const operations = yield* MagicLinkHttpOperations;
|
|
2833
4096
|
return handlers
|
|
2834
|
-
.handle("start",
|
|
2835
|
-
|
|
2836
|
-
authApiRateLimit,
|
|
2837
|
-
}))
|
|
2838
|
-
.handle("verify", makeEmailVerificationVerifyHandler({
|
|
2839
|
-
emailVerification,
|
|
2840
|
-
sessions,
|
|
2841
|
-
sessionCookie,
|
|
2842
|
-
}));
|
|
4097
|
+
.handle("start", operations.start)
|
|
4098
|
+
.handle("verify", operations.verify);
|
|
2843
4099
|
}));
|
|
2844
|
-
export const
|
|
2845
|
-
const
|
|
2846
|
-
const authHttp = yield* AuthHttp;
|
|
2847
|
-
const authApiRateLimit = yield* AuthApiRateLimit;
|
|
2848
|
-
const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
|
|
4100
|
+
export const PasskeyHttpApiGroupLive = HttpApiBuilder.group(PasskeyHttpApi, "passkey", Effect.fn("auth.http.passkey.group")(function* (handlers) {
|
|
4101
|
+
const operations = yield* PasskeyHttpOperations;
|
|
2849
4102
|
return handlers
|
|
2850
|
-
.handle("
|
|
2851
|
-
.handle("
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
: {}),
|
|
2857
|
-
}));
|
|
4103
|
+
.handle("registerStart", operations.registerStart)
|
|
4104
|
+
.handle("registerFinish", operations.registerFinish)
|
|
4105
|
+
.handle("authenticateStart", operations.authenticateStart)
|
|
4106
|
+
.handle("authenticateFinish", operations.authenticateFinish)
|
|
4107
|
+
.handle("listCredentials", operations.listCredentials)
|
|
4108
|
+
.handle("revokeCredential", operations.revokeCredential);
|
|
2858
4109
|
}));
|
|
2859
|
-
export const
|
|
2860
|
-
const
|
|
2861
|
-
const authHttp = yield* AuthHttp;
|
|
2862
|
-
const authApiRateLimit = yield* AuthApiRateLimit;
|
|
2863
|
-
const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
|
|
4110
|
+
export const IdentityHttpApiGroupLive = HttpApiBuilder.group(IdentityHttpApi, "identity", Effect.fn("auth.http.identity.group")(function* (handlers) {
|
|
4111
|
+
const operations = yield* IdentityHttpOperations;
|
|
2864
4112
|
return handlers
|
|
2865
|
-
.handle("
|
|
2866
|
-
.handle("
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
: {}),
|
|
2872
|
-
}));
|
|
4113
|
+
.handle("availability", operations.availability)
|
|
4114
|
+
.handle("list", operations.list)
|
|
4115
|
+
.handle("add", operations.add)
|
|
4116
|
+
.handle("replace", operations.replace)
|
|
4117
|
+
.handle("revoke", operations.revoke)
|
|
4118
|
+
.handle("primary", operations.primary);
|
|
2873
4119
|
}));
|
|
2874
|
-
export const
|
|
2875
|
-
const
|
|
2876
|
-
const authFlowState = yield* AuthFlowState;
|
|
2877
|
-
const authFlow = yield* AuthFlow;
|
|
2878
|
-
const users = yield* UserStore;
|
|
2879
|
-
const authHttp = yield* AuthHttp;
|
|
2880
|
-
const loginApprovalReview = yield* Effect.serviceOption(LoginApprovalReview);
|
|
2881
|
-
const loginApprovalFinalize = yield* Effect.serviceOption(LoginApprovalFinalize);
|
|
2882
|
-
const pendingCookieOption = yield* Effect.serviceOption(LoginApprovalPendingCookie);
|
|
2883
|
-
const trustedDevice = yield* Effect.serviceOption(TrustedDevice);
|
|
2884
|
-
const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
|
|
2885
|
-
const loginApprovalPendingCookie = Option.isSome(pendingCookieOption)
|
|
2886
|
-
? pendingCookieOption.value
|
|
2887
|
-
: makeLoginApprovalPendingCookie();
|
|
4120
|
+
export const TotpHttpApiGroupLive = HttpApiBuilder.group(TotpHttpApi, "totp", Effect.fn("auth.http.totp.group")(function* (handlers) {
|
|
4121
|
+
const operations = yield* TotpHttpOperations;
|
|
2888
4122
|
return handlers
|
|
2889
|
-
.handle("
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
authHttp,
|
|
2895
|
-
loginApprovalPendingCookie,
|
|
2896
|
-
...(Option.isSome(trustedDevice)
|
|
2897
|
-
? { trustedDevice: trustedDevice.value }
|
|
2898
|
-
: {}),
|
|
2899
|
-
...(Option.isSome(trustedDeviceCookie)
|
|
2900
|
-
? { trustedDeviceCookie: trustedDeviceCookie.value }
|
|
2901
|
-
: {}),
|
|
2902
|
-
}))
|
|
2903
|
-
.handle("status", makeLoginApprovalStatusHandler(Option.isSome(loginApprovalReview)
|
|
2904
|
-
? { loginApprovalReview: loginApprovalReview.value }
|
|
2905
|
-
: {}))
|
|
2906
|
-
.handle("finalize", makeLoginApprovalFinalizeHandler({
|
|
2907
|
-
authHttp,
|
|
2908
|
-
loginApprovalPendingCookie,
|
|
2909
|
-
...(Option.isSome(loginApprovalFinalize)
|
|
2910
|
-
? { loginApprovalFinalize: loginApprovalFinalize.value }
|
|
2911
|
-
: {}),
|
|
2912
|
-
...(Option.isSome(trustedDevice)
|
|
2913
|
-
? { trustedDevice: trustedDevice.value }
|
|
2914
|
-
: {}),
|
|
2915
|
-
...(Option.isSome(trustedDeviceCookie)
|
|
2916
|
-
? { trustedDeviceCookie: trustedDeviceCookie.value }
|
|
2917
|
-
: {}),
|
|
2918
|
-
}));
|
|
4123
|
+
.handle("startEnrollment", operations.startEnrollment)
|
|
4124
|
+
.handle("confirmEnrollment", operations.confirmEnrollment)
|
|
4125
|
+
.handle("verify", operations.verify)
|
|
4126
|
+
.handle("listFactors", operations.listFactors)
|
|
4127
|
+
.handle("revokeFactor", operations.revokeFactor);
|
|
2919
4128
|
}));
|
|
2920
|
-
export const
|
|
2921
|
-
const
|
|
2922
|
-
return handlers
|
|
2923
|
-
|
|
2924
|
-
|
|
4129
|
+
export const RecoveryCodesHttpApiGroupLive = HttpApiBuilder.group(RecoveryCodesHttpApi, "recoveryCodes", Effect.fn("auth.http.recovery_codes.group")(function* (handlers) {
|
|
4130
|
+
const operations = yield* RecoveryCodesHttpOperations;
|
|
4131
|
+
return handlers
|
|
4132
|
+
.handle("generateRecoveryCodes", operations.generate)
|
|
4133
|
+
.handle("regenerateRecoveryCodes", operations.regenerate)
|
|
4134
|
+
.handle("verifyRecoveryCode", operations.verify)
|
|
4135
|
+
.handle("listRecoveryCodes", operations.list)
|
|
4136
|
+
.handle("revokeRecoveryCode", operations.revoke);
|
|
2925
4137
|
}));
|
|
2926
|
-
export const
|
|
2927
|
-
const
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
4138
|
+
export const MfaHttpApiGroupLive = HttpApiBuilder.group(MfaHttpApi, "mfa", Effect.fn("auth.http.mfa.group")(function* (handlers) {
|
|
4139
|
+
const operations = yield* MfaHttpOperations;
|
|
4140
|
+
return handlers
|
|
4141
|
+
.handle("options", operations.options)
|
|
4142
|
+
.handle("verifyTotp", operations.verifyTotp)
|
|
4143
|
+
.handle("verifyTotpForFlow", operations.verifyTotpForFlow)
|
|
4144
|
+
.handle("verifyRecoveryCode", operations.verifyRecoveryCode)
|
|
4145
|
+
.handle("verifyRecoveryCodeForFlow", operations.verifyRecoveryCodeForFlow)
|
|
4146
|
+
.handle("startPasskey", operations.startPasskey)
|
|
4147
|
+
.handle("verifyPasskey", operations.verifyPasskey);
|
|
2935
4148
|
}));
|
|
2936
|
-
export const
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
4149
|
+
export const StepUpHttpApiGroupLive = HttpApiBuilder.group(StepUpHttpApi, "stepUp", Effect.fn("auth.http.step_up.group")(function* (handlers) {
|
|
4150
|
+
const operations = yield* StepUpHttpOperations;
|
|
4151
|
+
return handlers
|
|
4152
|
+
.handle("options", operations.options)
|
|
4153
|
+
.handle("verifyTotp", operations.verifyTotp)
|
|
4154
|
+
.handle("verifyPassword", operations.verifyPassword)
|
|
4155
|
+
.handle("verifyRecoveryCode", operations.verifyRecoveryCode)
|
|
4156
|
+
.handle("startPasskey", operations.startPasskey)
|
|
4157
|
+
.handle("verifyPasskey", operations.verifyPasskey);
|
|
2940
4158
|
}));
|
|
2941
|
-
export const
|
|
2942
|
-
|
|
2943
|
-
const tokenGrant = yield* OAuthAuthorizationCodeTokenGrant;
|
|
2944
|
-
const refreshTokenGrant = yield* Effect.serviceOption(OAuthRefreshTokenGrant);
|
|
2945
|
-
const clientCredentialsGrant = yield* Effect.serviceOption(OAuthClientCredentialsGrant);
|
|
2946
|
-
const tokenIntrospection = yield* Effect.serviceOption(OAuthTokenIntrospection);
|
|
2947
|
-
const tokenRevocation = yield* Effect.serviceOption(OAuthTokenRevocation);
|
|
4159
|
+
export const OAuthHttpApiGroupLive = HttpApiBuilder.group(OAuthHttpApi, "oauth", Effect.fn("auth.http.oauth.group")(function* (handlers) {
|
|
4160
|
+
const operations = yield* OAuthHttpOperations;
|
|
2948
4161
|
return handlers
|
|
2949
|
-
.handle("
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
...(Option.isNone(clientCredentialsGrant)
|
|
2955
|
-
? {}
|
|
2956
|
-
: { clientCredentialsGrant: clientCredentialsGrant.value }),
|
|
2957
|
-
}))
|
|
2958
|
-
.handle("introspect", Option.isNone(tokenIntrospection)
|
|
2959
|
-
? makeOAuthTokenIntrospectionNotConfiguredHandler()
|
|
2960
|
-
: makeOAuthTokenIntrospectionHandler({
|
|
2961
|
-
tokenIntrospection: tokenIntrospection.value,
|
|
2962
|
-
}))
|
|
2963
|
-
.handle("revoke", Option.isNone(tokenRevocation)
|
|
2964
|
-
? makeOAuthTokenRevocationNotConfiguredHandler()
|
|
2965
|
-
: makeOAuthTokenRevocationHandler({
|
|
2966
|
-
tokenRevocation: tokenRevocation.value,
|
|
2967
|
-
}));
|
|
4162
|
+
.handle("startAuthorization", operations.authorizationStart)
|
|
4163
|
+
.handle("unlinkAccount", operations.accountUnlink)
|
|
4164
|
+
.handle("startLinkConfirmation", operations.linkConfirmationStart)
|
|
4165
|
+
.handle("inspectLinkConfirmation", operations.linkConfirmationInspect)
|
|
4166
|
+
.handle("confirmLinkConfirmation", operations.linkConfirmationConfirm);
|
|
2968
4167
|
}));
|
|
2969
|
-
export const
|
|
2970
|
-
export const
|
|
2971
|
-
const
|
|
2972
|
-
return handlers
|
|
4168
|
+
export const OAuthHttpApiLive = HttpApiBuilder.layer(OAuthHttpApi).pipe(Layer.provide(OAuthHttpApiGroupLive), Layer.provide(OAuthHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4169
|
+
export const ApiKeyHttpApiGroupLive = HttpApiBuilder.group(ApiKeyHttpApi, "apiKey", Effect.fn("auth.http.api_key.group")(function* (handlers) {
|
|
4170
|
+
const operations = yield* ApiKeyHttpOperations;
|
|
4171
|
+
return handlers
|
|
4172
|
+
.handle("createApiKey", operations.create)
|
|
4173
|
+
.handle("listApiKeys", operations.list)
|
|
4174
|
+
.handle("revokeApiKey", operations.revoke);
|
|
2973
4175
|
}));
|
|
2974
|
-
export const
|
|
2975
|
-
export const
|
|
2976
|
-
const
|
|
2977
|
-
return handlers.handle("
|
|
4176
|
+
export const ApiKeyHttpApiLive = HttpApiBuilder.layer(ApiKeyHttpApi).pipe(Layer.provide(ApiKeyHttpApiGroupLive), Layer.provide(ApiKeyHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4177
|
+
export const RefreshTokenHttpApiGroupLive = HttpApiBuilder.group(RefreshTokenHttpApi, "refreshToken", Effect.fn("auth.http.refresh_token.group")(function* (handlers) {
|
|
4178
|
+
const operations = yield* RefreshTokenHttpOperations;
|
|
4179
|
+
return handlers.handle("refresh", operations.refresh);
|
|
2978
4180
|
}));
|
|
2979
|
-
export const
|
|
2980
|
-
export const
|
|
2981
|
-
const
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
return handlers.handle("list", makeAdminSecurityTimelineListHandler({
|
|
2986
|
-
sessions,
|
|
2987
|
-
sessionCookie,
|
|
2988
|
-
securityTimeline,
|
|
2989
|
-
authorization,
|
|
2990
|
-
}));
|
|
4181
|
+
export const RefreshTokenHttpApiLive = HttpApiBuilder.layer(RefreshTokenHttpApi).pipe(Layer.provide(RefreshTokenHttpApiGroupLive), Layer.provide(RefreshTokenHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4182
|
+
export const JwtHttpApiGroupLive = HttpApiBuilder.group(JwtHttpApi, "jwt", Effect.fn("auth.http.jwt.group")(function* (handlers) {
|
|
4183
|
+
const operations = yield* JwtHttpOperations;
|
|
4184
|
+
return handlers
|
|
4185
|
+
.handle("introspect", operations.introspect)
|
|
4186
|
+
.handle("revoke", operations.revoke);
|
|
2991
4187
|
}));
|
|
2992
|
-
export const
|
|
2993
|
-
export const
|
|
2994
|
-
const
|
|
2995
|
-
const sessionCookie = yield* SessionCookie;
|
|
2996
|
-
const trustedDevices = yield* TrustedDeviceStore;
|
|
4188
|
+
export const JwtHttpApiLive = HttpApiBuilder.layer(JwtHttpApi).pipe(Layer.provide(JwtHttpApiGroupLive), Layer.provide(JwtHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4189
|
+
export const AdminSessionHttpApiGroupLive = HttpApiBuilder.group(AdminSessionHttpApi, "adminSession", Effect.fn("auth.http.admin_session.group")(function* (handlers) {
|
|
4190
|
+
const operations = yield* AdminSessionHttpOperations;
|
|
2997
4191
|
return handlers
|
|
2998
|
-
.handle("list",
|
|
2999
|
-
.handle("revoke",
|
|
4192
|
+
.handle("list", operations.list)
|
|
4193
|
+
.handle("revoke", operations.revoke)
|
|
4194
|
+
.handle("revokeAll", operations.revokeAll);
|
|
3000
4195
|
}));
|
|
3001
|
-
export const
|
|
3002
|
-
export const
|
|
3003
|
-
const
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
const
|
|
4196
|
+
export const AdminSessionHttpApiLive = HttpApiBuilder.layer(AdminSessionHttpApi).pipe(Layer.provide(AdminSessionHttpApiGroupLive), Layer.provide(AdminSessionHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4197
|
+
export const AdminPermissionDefinitionHttpApiGroupLive = HttpApiBuilder.group(AdminPermissionDefinitionHttpApi, "adminPermissionDefinition", Effect.fn("auth.http.admin_permission_definition.group")(function* (handlers) {
|
|
4198
|
+
const operations = yield* AdminPermissionDefinitionHttpOperations;
|
|
4199
|
+
// The standalone API installs a router middleware that provides these
|
|
4200
|
+
// operation requirements for every request.
|
|
4201
|
+
const create = operations.create;
|
|
4202
|
+
const get = operations.get;
|
|
4203
|
+
const list = operations.list;
|
|
4204
|
+
const update = operations.update;
|
|
4205
|
+
const disable = operations.disable;
|
|
4206
|
+
const enable = operations.enable;
|
|
4207
|
+
const remove = operations.delete;
|
|
3007
4208
|
return handlers
|
|
3008
|
-
.handle("
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
.handle("
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
4209
|
+
.handle("create", create)
|
|
4210
|
+
.handle("get", get)
|
|
4211
|
+
.handle("list", list)
|
|
4212
|
+
.handle("update", update)
|
|
4213
|
+
.handle("disable", disable)
|
|
4214
|
+
.handle("enable", enable)
|
|
4215
|
+
.handle("delete", remove);
|
|
4216
|
+
}));
|
|
4217
|
+
export const AdminPermissionDefinitionHttpRequirementsLive = HttpRouter.middleware()(Effect.gen(function* () {
|
|
4218
|
+
const context = yield* Effect.context();
|
|
4219
|
+
return (httpEffect) => httpEffect.pipe(Effect.provide(context));
|
|
4220
|
+
}), { global: true });
|
|
4221
|
+
export const AdminPermissionDefinitionHttpApiLive = Layer.merge(HttpApiBuilder.layer(AdminPermissionDefinitionHttpApi).pipe(Layer.provide(AdminPermissionDefinitionHttpApiGroupLive), Layer.provide(AdminPermissionDefinitionHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive)), AdminPermissionDefinitionHttpRequirementsLive);
|
|
4222
|
+
export const EmailAuthHttpApiLive = HttpApiBuilder.layer(EmailAuthHttpApi).pipe(Layer.provide(EmailAuthHttpApiGroupLive), Layer.provide(EmailAuthHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4223
|
+
export const PasskeyHttpApiLive = HttpApiBuilder.layer(PasskeyHttpApi).pipe(Layer.provide(PasskeyHttpApiGroupLive), Layer.provide(PasskeyHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4224
|
+
export const IdentityHttpApiLive = HttpApiBuilder.layer(IdentityHttpApi).pipe(Layer.provide(IdentityHttpApiGroupLive), Layer.provide(IdentityHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4225
|
+
export const TotpHttpApiLive = HttpApiBuilder.layer(TotpHttpApi).pipe(Layer.provide(TotpHttpApiGroupLive), Layer.provide(TotpHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4226
|
+
export const RecoveryCodesHttpApiLive = HttpApiBuilder.layer(RecoveryCodesHttpApi).pipe(Layer.provide(RecoveryCodesHttpApiGroupLive), Layer.provide(RecoveryCodesHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4227
|
+
export const MfaHttpApiLive = HttpApiBuilder.layer(MfaHttpApi).pipe(Layer.provide(MfaHttpApiGroupLive), Layer.provide(MfaHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4228
|
+
export const StepUpHttpApiLive = HttpApiBuilder.layer(StepUpHttpApi).pipe(Layer.provide(StepUpHttpApiGroupLive), Layer.provide(StepUpHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4229
|
+
export const CoreAuthLoginApprovalGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "loginApproval", Effect.fn("auth.http.login_approval.group")(function* (handlers) {
|
|
4230
|
+
const operations = yield* LoginApprovalHttpOperations;
|
|
4231
|
+
return handlers
|
|
4232
|
+
.handle("approve", operations.approve)
|
|
4233
|
+
.handle("status", operations.status)
|
|
4234
|
+
.handle("finalize", operations.finalize);
|
|
4235
|
+
}));
|
|
4236
|
+
export const CoreAuthLoginNotificationGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "security", Effect.fn("auth.http.security.group")(function* (handlers) {
|
|
4237
|
+
const operations = yield* LoginNotificationHttpOperations;
|
|
4238
|
+
return handlers.handle("reportLogin", operations.reportLogin);
|
|
4239
|
+
}));
|
|
4240
|
+
export const SecurityTimelineHttpApiGroupLive = HttpApiBuilder.group(SecurityTimelineHttpApi, "securityTimeline", Effect.fn("auth.http.security_timeline.group")(function* (handlers) {
|
|
4241
|
+
const operations = yield* SecurityTimelineHttpOperations;
|
|
4242
|
+
return handlers.handle("list", operations.list);
|
|
4243
|
+
}));
|
|
4244
|
+
export const SecurityTimelineHttpApiLive = HttpApiBuilder.layer(SecurityTimelineHttpApi).pipe(Layer.provide(SecurityTimelineHttpApiGroupLive), Layer.provide(SecurityTimelineHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4245
|
+
export const OAuthProviderAuthorizationHttpApiGroupLive = HttpApiBuilder.group(OAuthProviderAuthorizationHttpApi, "oauthProviderAuthorization", Effect.fn("auth.http.oauth_provider_authorization.group")(function* (handlers) {
|
|
4246
|
+
const operations = yield* OAuthProviderAuthorizationHttpOperations;
|
|
4247
|
+
return handlers.handle("authorize", operations.authorize);
|
|
4248
|
+
}));
|
|
4249
|
+
export const OAuthProviderAuthorizationHttpApiLive = HttpApiBuilder.layer(OAuthProviderAuthorizationHttpApi).pipe(Layer.provide(OAuthProviderAuthorizationHttpApiGroupLive), Layer.provide(OAuthProviderAuthorizationHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4250
|
+
export const OAuthTokenHttpApiGroupLive = HttpApiBuilder.group(OAuthTokenHttpApi, "oauthToken", Effect.fn("auth.http.oauth_token.group")(function* (handlers) {
|
|
4251
|
+
const operations = yield* OAuthTokenHttpOperations;
|
|
4252
|
+
return handlers
|
|
4253
|
+
.handle("token", operations.token)
|
|
4254
|
+
.handle("introspect", operations.introspect)
|
|
4255
|
+
.handle("revoke", operations.revoke);
|
|
4256
|
+
}));
|
|
4257
|
+
export const OAuthTokenHttpApiLive = HttpApiBuilder.layer(OAuthTokenHttpApi).pipe(Layer.provide(OAuthTokenHttpApiGroupLive), Layer.provide(OAuthTokenHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4258
|
+
export const JwtDiscoveryHttpApiGroupLive = HttpApiBuilder.group(JwtDiscoveryHttpApi, "jwtDiscovery", Effect.fn("auth.http.jwt_discovery.group")(function* (handlers) {
|
|
4259
|
+
const operations = yield* JwtDiscoveryHttpOperations;
|
|
4260
|
+
return handlers.handle("jwks", operations.jwks);
|
|
4261
|
+
}));
|
|
4262
|
+
export const JwtDiscoveryHttpApiLive = HttpApiBuilder.layer(JwtDiscoveryHttpApi).pipe(Layer.provide(JwtDiscoveryHttpApiGroupLive), Layer.provide(JwtDiscoveryHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4263
|
+
export const OidcDiscoveryHttpApiGroupLive = HttpApiBuilder.group(OidcDiscoveryHttpApi, "oidcDiscovery", Effect.fn("auth.http.oidc_discovery.group")(function* (handlers) {
|
|
4264
|
+
const operations = yield* OidcDiscoveryHttpOperations;
|
|
4265
|
+
return handlers.handle("openidConfiguration", operations.openidConfiguration);
|
|
4266
|
+
}));
|
|
4267
|
+
export const OidcDiscoveryHttpApiLive = HttpApiBuilder.layer(OidcDiscoveryHttpApi).pipe(Layer.provide(OidcDiscoveryHttpApiGroupLive), Layer.provide(OidcDiscoveryHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4268
|
+
export const AdminSecurityTimelineHttpApiGroupLive = HttpApiBuilder.group(AdminSecurityTimelineHttpApi, "adminSecurityTimeline", Effect.fn("auth.http.admin_security_timeline.group")(function* (handlers) {
|
|
4269
|
+
const operations = yield* AdminSecurityTimelineHttpOperations;
|
|
4270
|
+
return handlers.handle("list", operations.list);
|
|
4271
|
+
}));
|
|
4272
|
+
export const AdminSecurityTimelineHttpApiLive = HttpApiBuilder.layer(AdminSecurityTimelineHttpApi).pipe(Layer.provide(AdminSecurityTimelineHttpApiGroupLive), Layer.provide(AdminSecurityTimelineHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4273
|
+
export const TrustedDeviceHttpApiGroupLive = HttpApiBuilder.group(TrustedDeviceHttpApi, "trustedDevice", Effect.fn("auth.http.trusted_device.group")(function* (handlers) {
|
|
4274
|
+
const operations = yield* TrustedDeviceHttpOperations;
|
|
4275
|
+
return handlers
|
|
4276
|
+
.handle("list", operations.list)
|
|
4277
|
+
.handle("revoke", operations.revoke);
|
|
4278
|
+
}));
|
|
4279
|
+
export const TrustedDeviceHttpApiLive = HttpApiBuilder.layer(TrustedDeviceHttpApi).pipe(Layer.provide(TrustedDeviceHttpApiGroupLive), Layer.provide(TrustedDeviceHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4280
|
+
export const AdminTrustedDeviceHttpApiGroupLive = HttpApiBuilder.group(AdminTrustedDeviceHttpApi, "adminTrustedDevice", Effect.fn("auth.http.admin_trusted_device.group")(function* (handlers) {
|
|
4281
|
+
const operations = yield* AdminTrustedDeviceHttpOperations;
|
|
4282
|
+
return handlers
|
|
4283
|
+
.handle("list", operations.list)
|
|
4284
|
+
.handle("revoke", operations.revoke);
|
|
3020
4285
|
}));
|
|
3021
|
-
export const AdminTrustedDeviceHttpApiLive = HttpApiBuilder.layer(AdminTrustedDeviceHttpApi).pipe(Layer.provide(
|
|
3022
|
-
const
|
|
3023
|
-
export const
|
|
3024
|
-
export const AuthHttpApiLive = AuthHttpApiBaseLive.pipe(Layer.provide(AuthApiRateLimitLive));
|
|
4286
|
+
export const AdminTrustedDeviceHttpApiLive = HttpApiBuilder.layer(AdminTrustedDeviceHttpApi).pipe(Layer.provide(AdminTrustedDeviceHttpApiGroupLive), Layer.provide(AdminTrustedDeviceHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4287
|
+
const CoreAuthHttpApiBaseLive = HttpApiBuilder.layer(CoreAuthHttpApi).pipe(Layer.provide(CoreAuthPasswordGroupLive), Layer.provide(CoreAuthSessionGroupLive), Layer.provide(CoreAuthEmailVerificationGroupLive), Layer.provide(CoreAuthEmailOtpGroupLive), Layer.provide(CoreAuthMagicLinkGroupLive), Layer.provide(CoreAuthLoginApprovalGroupLive), Layer.provide(CoreAuthLoginNotificationGroupLive), Layer.provide(PasswordHttpOperationsLive), Layer.provide(SessionHttpOperationsLive), Layer.provide(EmailVerificationHttpOperationsLive), Layer.provide(EmailOtpHttpOperationsLive), Layer.provide(MagicLinkHttpOperationsLive), Layer.provide(LoginApprovalHttpOperationsLive), Layer.provide(LoginNotificationHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
|
|
4288
|
+
export const CoreAuthHttpApiLive = CoreAuthHttpApiBaseLive.pipe(Layer.provide(BotProtectionNoopLive));
|
|
3025
4289
|
export { AuthResult };
|
|
3026
4290
|
//# sourceMappingURL=Api.js.map
|