@@ -1722,3 +1722,227 @@ export class SmsRegionsAuthConfig {
1722
1722
}
1723
1723
}
1724
1724
}
1725
+ /**
1726
+ * Enforcement state of reCAPTCHA protection.
1727
+ * - 'OFF': Unenforced.
1728
+ * - 'AUDIT': Create assessment but don't enforce the result.
1729
+ * - 'ENFORCE': Create assessment and enforce the result.
1730
+ */
1731
+ export type RecaptchaProviderEnforcementState = 'OFF' | 'AUDIT' | 'ENFORCE' ;
1732
+
1733
+ /**
1734
+ * The actions to take for reCAPTCHA-protected requests.
1735
+ * - 'BLOCK': The reCAPTCHA-protected request will be blocked.
1736
+ */
1737
+ export type RecaptchaAction = 'BLOCK' ;
1738
+
1739
+ /**
1740
+ * The config for a reCAPTCHA action rule.
1741
+ */
1742
+ export interface RecaptchaManagedRule {
1743
+ /**
1744
+ * The action will be enforced if the reCAPTCHA score of a request is larger than endScore.
1745
+ */
1746
+ endScore : number ;
1747
+ /**
1748
+ * The action for reCAPTCHA-protected requests.
1749
+ */
1750
+ action ?: RecaptchaAction ;
1751
+ }
1752
+
1753
+ /**
1754
+ * The key's platform type.
1755
+ */
1756
+ export type RecaptchaKeyClientType = 'WEB' | 'IOS' | 'ANDROID' ;
1757
+
1758
+ /**
1759
+ * The reCAPTCHA key config.
1760
+ */
1761
+ export interface RecaptchaKey {
1762
+ /**
1763
+ * The key's client platform type.
1764
+ */
1765
+ type ?: RecaptchaKeyClientType ;
1766
+
1767
+ /**
1768
+ * The reCAPTCHA site key.
1769
+ */
1770
+ key : string ;
1771
+ }
1772
+
1773
+ /**
1774
+ * The request interface for updating a reCAPTCHA Config.
1775
+ * By enabling reCAPTCHA Enterprise Integration you are
1776
+ * agreeing to reCAPTCHA Enterprise
1777
+ * {@link https://cloud.google.com/terms/service-terms | Term of Service}.
1778
+ */
1779
+ export interface RecaptchaConfig {
1780
+ /**
1781
+ * The enforcement state of the email password provider.
1782
+ */
1783
+ emailPasswordEnforcementState ?: RecaptchaProviderEnforcementState ;
1784
+ /**
1785
+ * The reCAPTCHA managed rules.
1786
+ */
1787
+ managedRules ?: RecaptchaManagedRule [ ] ;
1788
+
1789
+ /**
1790
+ * The reCAPTCHA keys.
1791
+ */
1792
+ recaptchaKeys ?: RecaptchaKey [ ] ;
1793
+
1794
+ /**
1795
+ * Whether to use account defender for reCAPTCHA assessment.
1796
+ * The default value is false.
1797
+ */
1798
+ useAccountDefender ?: boolean ;
1799
+ }
1800
+
1801
+ export class RecaptchaAuthConfig implements RecaptchaConfig {
1802
+ public readonly emailPasswordEnforcementState ?: RecaptchaProviderEnforcementState ;
1803
+ public readonly managedRules ?: RecaptchaManagedRule [ ] ;
1804
+ public readonly recaptchaKeys ?: RecaptchaKey [ ] ;
1805
+ public readonly useAccountDefender ?: boolean ;
1806
+
1807
+ constructor ( recaptchaConfig : RecaptchaConfig ) {
1808
+ this . emailPasswordEnforcementState = recaptchaConfig . emailPasswordEnforcementState ;
1809
+ this . managedRules = recaptchaConfig . managedRules ;
1810
+ this . recaptchaKeys = recaptchaConfig . recaptchaKeys ;
1811
+ this . useAccountDefender = recaptchaConfig . useAccountDefender ;
1812
+ }
1813
+
1814
+ /**
1815
+ * Validates the RecaptchaConfig options object. Throws an error on failure.
1816
+ * @param options - The options object to validate.
1817
+ */
1818
+ public static validate ( options : RecaptchaConfig ) : void {
1819
+ const validKeys = {
1820
+ emailPasswordEnforcementState : true ,
1821
+ managedRules : true ,
1822
+ recaptchaKeys : true ,
1823
+ useAccountDefender : true ,
1824
+ } ;
1825
+
1826
+ if ( ! validator . isNonNullObject ( options ) ) {
1827
+ throw new FirebaseAuthError (
1828
+ AuthClientErrorCode . INVALID_CONFIG ,
1829
+ '"RecaptchaConfig" must be a non-null object.' ,
1830
+ ) ;
1831
+ }
1832
+
1833
+ for ( const key in options ) {
1834
+ if ( ! ( key in validKeys ) ) {
1835
+ throw new FirebaseAuthError (
1836
+ AuthClientErrorCode . INVALID_CONFIG ,
1837
+ `"${ key } " is not a valid RecaptchaConfig parameter.` ,
1838
+ ) ;
1839
+ }
1840
+ }
1841
+
1842
+ // Validation
1843
+ if ( typeof options . emailPasswordEnforcementState !== undefined ) {
1844
+ if ( ! validator . isNonEmptyString ( options . emailPasswordEnforcementState ) ) {
1845
+ throw new FirebaseAuthError (
1846
+ AuthClientErrorCode . INVALID_ARGUMENT ,
1847
+ '"RecaptchaConfig.emailPasswordEnforcementState" must be a valid non-empty string.' ,
1848
+ ) ;
1849
+ }
1850
+
1851
+ if ( options . emailPasswordEnforcementState !== 'OFF' &&
1852
+ options . emailPasswordEnforcementState !== 'AUDIT' &&
1853
+ options . emailPasswordEnforcementState !== 'ENFORCE' ) {
1854
+ throw new FirebaseAuthError (
1855
+ AuthClientErrorCode . INVALID_CONFIG ,
1856
+ '"RecaptchaConfig.emailPasswordEnforcementState" must be either "OFF", "AUDIT" or "ENFORCE".' ,
1857
+ ) ;
1858
+ }
1859
+ }
1860
+
1861
+ if ( typeof options . managedRules !== 'undefined' ) {
1862
+ // Validate array
1863
+ if ( ! validator . isArray ( options . managedRules ) ) {
1864
+ throw new FirebaseAuthError (
1865
+ AuthClientErrorCode . INVALID_CONFIG ,
1866
+ '"RecaptchaConfig.managedRules" must be an array of valid "RecaptchaManagedRule".' ,
1867
+ ) ;
1868
+ }
1869
+ // Validate each rule of the array
1870
+ options . managedRules . forEach ( ( managedRule ) => {
1871
+ RecaptchaAuthConfig . validateManagedRule ( managedRule ) ;
1872
+ } ) ;
1873
+ }
1874
+
1875
+ if ( typeof options . useAccountDefender != 'undefined' ) {
1876
+ if ( ! validator . isBoolean ( options . useAccountDefender ) ) {
1877
+ throw new FirebaseAuthError (
1878
+ AuthClientErrorCode . INVALID_CONFIG ,
1879
+ '"RecaptchaConfig.useAccountDefender" must be a boolean value".' ,
1880
+ ) ;
1881
+ }
1882
+ }
1883
+ }
1884
+
1885
+ /**
1886
+ * Validate each element in ManagedRule array
1887
+ * @param options - The options object to validate.
1888
+ */
1889
+ private static validateManagedRule ( options : RecaptchaManagedRule ) : void {
1890
+ const validKeys = {
1891
+ endScore : true ,
1892
+ action : true ,
1893
+ }
1894
+ if ( ! validator . isNonNullObject ( options ) ) {
1895
+ throw new FirebaseAuthError (
1896
+ AuthClientErrorCode . INVALID_CONFIG ,
1897
+ '"RecaptchaManagedRule" must be a non-null object.' ,
1898
+ ) ;
1899
+ }
1900
+ // Check for unsupported top level attributes.
1901
+ for ( const key in options ) {
1902
+ if ( ! ( key in validKeys ) ) {
1903
+ throw new FirebaseAuthError (
1904
+ AuthClientErrorCode . INVALID_CONFIG ,
1905
+ `"${ key } " is not a valid RecaptchaManagedRule parameter.` ,
1906
+ ) ;
1907
+ }
1908
+ }
1909
+
1910
+ // Validate content.
1911
+ if ( typeof options . action !== 'undefined' &&
1912
+ options . action !== 'BLOCK' ) {
1913
+ throw new FirebaseAuthError (
1914
+ AuthClientErrorCode . INVALID_CONFIG ,
1915
+ '"RecaptchaManagedRule.action" must be "BLOCK".' ,
1916
+ ) ;
1917
+ }
1918
+ }
1919
+
1920
+ /**
1921
+ * Returns a JSON-serializable representation of this object.
1922
+ * @returns The JSON-serializable object representation of the ReCaptcha config instance
1923
+ */
1924
+ public toJSON ( ) : object {
1925
+ const json : any = {
1926
+ emailPasswordEnforcementState : this . emailPasswordEnforcementState ,
1927
+ managedRules : deepCopy ( this . managedRules ) ,
1928
+ recaptchaKeys : deepCopy ( this . recaptchaKeys ) ,
1929
+ useAccountDefender : this . useAccountDefender ,
1930
+ }
1931
+
1932
+ if ( typeof json . emailPasswordEnforcementState === 'undefined' ) {
1933
+ delete json . emailPasswordEnforcementState ;
1934
+ }
1935
+ if ( typeof json . managedRules === 'undefined' ) {
1936
+ delete json . managedRules ;
1937
+ }
1938
+ if ( typeof json . recaptchaKeys === 'undefined' ) {
1939
+ delete json . recaptchaKeys ;
1940
+ }
1941
+
1942
+ if ( typeof json . useAccountDefender === 'undefined' ) {
1943
+ delete json . useAccountDefender ;
1944
+ }
1945
+
1946
+ return json ;
1947
+ }
1948
+ }
0 commit comments