diff --git a/Cargo.lock b/Cargo.lock index ff777f8f62..05c45938fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,7 +264,7 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2", - "time 0.3.21", + "time 0.3.22", "url", ] @@ -388,7 +388,7 @@ dependencies = [ "serde", "serde_json", "strum", - "time 0.3.21", + "time 0.3.22", "url", "utoipa", ] @@ -413,9 +413,9 @@ checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" [[package]] name = "assert-json-diff" @@ -600,7 +600,7 @@ dependencies = [ "http", "hyper", "ring", - "time 0.3.21", + "time 0.3.22", "tokio", "tower", "tracing", @@ -820,7 +820,7 @@ dependencies = [ "percent-encoding", "regex", "sha2", - "time 0.3.21", + "time 0.3.22", "tracing", ] @@ -960,7 +960,7 @@ dependencies = [ "itoa", "num-integer", "ryu", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -1068,6 +1068,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -1091,15 +1100,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded" [[package]] name = "blake3" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" dependencies = [ "arrayref", "arrayvec", @@ -1202,7 +1211,7 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -1285,9 +1294,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.2" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "401a4694d2bf92537b6867d94de48c4842089645fdcdf6c71865b175d836e9c2" +checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" dependencies = [ "clap_builder", "clap_derive", @@ -1296,9 +1305,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.1" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980" +checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" dependencies = [ "anstyle", "bitflags 1.3.2", @@ -1350,6 +1359,7 @@ dependencies = [ "md5", "nanoid", "once_cell", + "phonenumber", "proptest", "quick-xml", "rand 0.8.5", @@ -1361,8 +1371,9 @@ dependencies = [ "serde_urlencoded", "signal-hook", "signal-hook-tokio", + "test-case", "thiserror", - "time 0.3.21", + "time 0.3.22", "tokio", ] @@ -1396,9 +1407,9 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" [[package]] name = "convert_case" @@ -1413,7 +1424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.21", + "time 0.3.22", "version_check", ] @@ -1484,9 +1495,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", @@ -1497,9 +1508,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -1646,14 +1657,14 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7a532c1f99a0f596f6960a60d1e119e91582b24b39e2d83a190e61262c3ef0c" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.2", "byteorder", "diesel_derives", "itoa", "pq-sys", "r2d2", "serde_json", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -1871,7 +1882,7 @@ dependencies = [ "mime", "serde", "serde_json", - "time 0.3.21", + "time 0.3.22", "tokio", "url", "webdriver", @@ -2403,9 +2414,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2531,14 +2542,14 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.21", + "time 0.3.22", ] [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -2674,9 +2685,18 @@ dependencies = [ [[package]] name = "log" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] [[package]] name = "luhn" @@ -2770,9 +2790,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -2831,9 +2851,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36506f2f935238463605f3bb13b362f1949daafc3b347d05d60ae08836db2bd2" +checksum = "206bf83f415b0579fd885fe0804eb828e727636657dc1bf73d80d2f1218e14a1" dependencies = [ "async-io", "async-lock", @@ -2841,7 +2861,6 @@ dependencies = [ "crossbeam-epoch", "crossbeam-utils", "futures-util", - "num_cpus", "once_cell", "parking_lot", "quanta", @@ -2949,6 +2968,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "oncemutex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2" + [[package]] name = "openssl" version = "0.10.54" @@ -3200,6 +3225,26 @@ dependencies = [ "sha2", ] +[[package]] +name = "phonenumber" +version = "0.3.2+8.13.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34749f64ea9d76f10cdc8a859588b57775f59177c7dd91f744d620bd62982d6f" +dependencies = [ + "bincode", + "either", + "fnv", + "itertools", + "lazy_static", + "nom", + "quick-xml", + "regex", + "regex-cache", + "serde", + "serde_derive", + "thiserror", +] + [[package]] name = "pin-project" version = "1.1.0" @@ -3311,9 +3356,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] @@ -3590,6 +3635,18 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-cache" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f7b62d69743b8b94f353b6b7c3deb4c5582828328bcb8d5fedf214373808793" +dependencies = [ + "lru-cache", + "oncemutex", + "regex", + "regex-syntax 0.6.29", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -3742,7 +3799,7 @@ dependencies = [ "strum", "thirtyfour", "thiserror", - "time 0.3.21", + "time 0.3.22", "tokio", "toml 0.7.4", "url", @@ -3781,7 +3838,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "strum", - "time 0.3.21", + "time 0.3.22", "tokio", "tracing", "tracing-actix-web", @@ -3794,9 +3851,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "6.6.1" +version = "6.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b68543d5527e158213414a92832d2aab11a84d2571a5eb021ebe22c43aab066" +checksum = "b73e721f488c353141288f223b599b4ae9303ecf3e62923f40a492f0634a4dc3" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -3805,15 +3862,15 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "6.5.0" +version = "6.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4e0f0ced47ded9a68374ac145edd65a6c1fa13a96447b873660b2a568a0fd7" +checksum = "e22ce362f5561923889196595504317a4372b84210e6e335da529a65ea5452b5" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", "shellexpand", - "syn 1.0.109", + "syn 2.0.18", "walkdir", ] @@ -3854,9 +3911,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.19" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags 1.3.2", "errno", @@ -3880,9 +3937,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -4000,18 +4057,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", @@ -4115,7 +4172,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -4246,7 +4303,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -4313,7 +4370,7 @@ dependencies = [ "serde_json", "strum", "thiserror", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -4416,6 +4473,41 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "test-case" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1d6e7bde536b0412f20765b76e921028059adfd1b90d8974d33fd3c91b25df" +dependencies = [ + "test-case-macros", +] + +[[package]] +name = "test-case-core" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d10394d5d1e27794f772b6fc854c7e91a2dc26e2cbf807ad523370c2a59c0cee" +dependencies = [ + "cfg-if", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "test-case-macros" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeb9a44b1c6a54c1ba58b152797739dba2a83ca74e18168a68c980eb142f9404" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", + "test-case-core", +] + [[package]] name = "thirtyfour" version = "0.31.0" @@ -4497,9 +4589,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "itoa", "serde", @@ -4764,7 +4856,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ "crossbeam-channel", - "time 0.3.21", + "time 0.3.22", "tracing-subscriber", ] @@ -4999,9 +5091,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" dependencies = [ "getrandom 0.2.10", "serde", @@ -5029,7 +5121,7 @@ dependencies = [ "git2", "rustc_version", "rustversion", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -5071,11 +5163,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -5099,9 +5190,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5109,9 +5200,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -5124,9 +5215,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -5136,9 +5227,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5146,9 +5237,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -5159,15 +5250,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -5187,7 +5278,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.21", + "time 0.3.22", "unicode-segmentation", "url", ] @@ -5376,9 +5467,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" dependencies = [ "memchr", ] @@ -5394,9 +5485,9 @@ dependencies = [ [[package]] name = "wiremock" -version = "0.5.18" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7b0b5b253ebc0240d6aac6dd671c495c467420577bf634d3064ae7e6fa2b4c" +checksum = "c6f71803d3a1c80377a06221e0530be02035d5b3e854af56c6ece7ac20ac441d" dependencies = [ "assert-json-diff", "async-trait", diff --git a/crates/common_utils/Cargo.toml b/crates/common_utils/Cargo.toml index 80aa645e15..145a06573e 100644 --- a/crates/common_utils/Cargo.toml +++ b/crates/common_utils/Cargo.toml @@ -33,6 +33,7 @@ signal-hook = { version = "0.3.15", optional = true } thiserror = "1.0.40" time = { version = "0.3.21", features = ["serde", "serde-well-known", "std"] } tokio = { version = "1.28.2", features = ["macros", "rt-multi-thread"], optional = true } +phonenumber = "0.3.2+8.13.9" # First party crates masking = { version = "0.1.0", path = "../masking" } @@ -44,3 +45,4 @@ signal-hook-tokio = { version = "0.3.1", features = ["futures-v0_3"], optional = [dev-dependencies] fake = "2.6.1" proptest = "1.2.0" +test-case = "3.1.0" diff --git a/crates/common_utils/src/errors.rs b/crates/common_utils/src/errors.rs index fc8ef51256..fd662227db 100644 --- a/crates/common_utils/src/errors.rs +++ b/crates/common_utils/src/errors.rs @@ -29,11 +29,14 @@ pub enum ParsingError { /// Failed to parse email #[error("Failed to parse email")] EmailParsingError, + /// Failed to parse phone number + #[error("Failed to parse phone number")] + PhoneNumberParsingError, } /// Validation errors. #[allow(missing_docs)] // Only to prevent warnings about struct fields not being documented -#[derive(Debug, thiserror::Error, Clone)] +#[derive(Debug, thiserror::Error, Clone, PartialEq)] pub enum ValidationError { /// The provided input is missing a required field. #[error("Missing required field: {field_name}")] diff --git a/crates/common_utils/src/pii.rs b/crates/common_utils/src/pii.rs index 6b109ad1dd..c4d4d8b7a0 100644 --- a/crates/common_utils/src/pii.rs +++ b/crates/common_utils/src/pii.rs @@ -16,7 +16,7 @@ use masking::{ExposeInterface, Secret, Strategy, WithType}; use crate::{ crypto::Encryptable, errors::{self, ValidationError}, - validation::validate_email, + validation::{validate_email, validate_phone_number}, }; /// A string constant representing a redacted or masked value. @@ -25,6 +25,96 @@ pub const REDACTED: &str = "Redacted"; /// Type alias for serde_json value which has Secret Information pub type SecretSerdeValue = Secret; +/// Strategy for masking a PhoneNumber +#[derive(Debug)] +pub struct PhoneNumberStrategy; + +/// Phone Number +#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[serde(try_from = "String")] +pub struct PhoneNumber(Secret); + +impl Strategy for PhoneNumberStrategy +where + T: AsRef + std::fmt::Debug, +{ + fn fmt(val: &T, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let val_str: &str = val.as_ref(); + + // masks everything but the last 4 digits + write!( + f, + "{}{}", + "*".repeat(val_str.len() - 4), + &val_str[val_str.len() - 4..] + ) + } +} + +impl FromStr for PhoneNumber { + type Err = error_stack::Report; + fn from_str(phone_number: &str) -> Result { + validate_phone_number(phone_number)?; + let secret = Secret::::new(phone_number.to_string()); + Ok(Self(secret)) + } +} + +impl TryFrom for PhoneNumber { + type Error = error_stack::Report; + + fn try_from(value: String) -> Result { + Self::from_str(&value).change_context(errors::ParsingError::PhoneNumberParsingError) + } +} + +impl ops::Deref for PhoneNumber { + type Target = Secret; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ops::DerefMut for PhoneNumber { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl Queryable for PhoneNumber +where + DB: Backend, + Self: FromSql, +{ + type Row = Self; + + fn build(row: Self::Row) -> deserialize::Result { + Ok(row) + } +} + +impl FromSql for PhoneNumber +where + DB: Backend, + String: FromSql, +{ + fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result { + let val = String::from_sql(bytes)?; + Ok(Self::from_str(val.as_str())?) + } +} + +impl ToSql for PhoneNumber +where + DB: Backend, + String: ToSql, +{ + fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> diesel::serialize::Result { + self.0.to_sql(out) + } +} + /* /// Phone number #[derive(Debug)] @@ -326,4 +416,10 @@ mod pii_masking_strategy_tests { Secret::new("pay_uszFB2QGe9MmLY65ojhT_secret".to_string()); assert_eq!("*** alloc::string::String ***", format!("{secret:?}")); } + + #[test] + fn test_valid_phone_number_default_masking() { + let secret: Secret = Secret::new("+40712345678".to_string()); + assert_eq!("*** alloc::string::String ***", format!("{secret:?}")); + } } diff --git a/crates/common_utils/src/validation.rs b/crates/common_utils/src/validation.rs index 6fc3ba842e..7679c4c36d 100644 --- a/crates/common_utils/src/validation.rs +++ b/crates/common_utils/src/validation.rs @@ -8,6 +8,17 @@ use router_env::logger; use crate::errors::{CustomResult, ValidationError}; +/// Validates a given phone number using the [phonenumber] crate +/// +/// It returns a [ValidationError::InvalidValue] in case it could not parse the phone number +pub fn validate_phone_number(phone_number: &str) -> Result<(), ValidationError> { + let _ = phonenumber::parse(None, phone_number).map_err(|e| ValidationError::InvalidValue { + message: format!("Could not parse phone number: {phone_number}, because: {e:?}"), + })?; + + Ok(()) +} + /// Performs a simple validation against a provided email address. pub fn validate_email(email: &str) -> CustomResult<(), ValidationError> { #[deny(clippy::invalid_regex)] @@ -54,6 +65,7 @@ mod tests { strategy::{Just, NewTree, Strategy}, test_runner::TestRunner, }; + use test_case::test_case; use super::*; @@ -81,6 +93,20 @@ mod tests { assert!(result.is_err()); } + #[test_case("+40745323456" ; "Romanian valid phone number")] + #[test_case("+34912345678" ; "Spanish valid phone number")] + #[test_case("+41 79 123 45 67" ; "Swiss valid phone number")] + #[test_case("+66 81 234 5678" ; "Thailand valid phone number")] + fn test_validate_phone_number(phone_number: &str) { + assert!(validate_phone_number(phone_number).is_ok()); + } + + #[test_case("0745323456" ; "Romanian invalid phone number")] + fn test_invalid_phone_number(phone_number: &str) { + let res = validate_phone_number(phone_number); + assert!(res.is_err()); + } + proptest::proptest! { /// Example of unit test #[test]